1# otp.tcl - Copyright (C) 2006 Pat Thoyts <patthoyts@users.sourceforge.net> 2# 3# Tcl implementation of RFC 2289: A One-Time Password System 4# 5# ------------------------------------------------------------------------- 6# See the file "license.terms" for information on usage and redistribution 7# of this file, and for a DISCLAIMER OF ALL WARRANTIES. 8# ------------------------------------------------------------------------- 9 10 11package require Tcl 8.2; # tcl minimum version 12 13namespace eval ::otp { 14 variable version 1.0.0 15 variable rcsid {$Id: otp.tcl,v 1.2 2006/09/02 22:30:17 patthoyts Exp $} 16 17 namespace export otp-md4 otp-md5 otp-sha1 otp-rmd160 18 19 variable Words { 20 "A" "ABE" "ACE" "ACT" "AD" "ADA" "ADD" 21 "AGO" "AID" "AIM" "AIR" "ALL" "ALP" "AM" "AMY" 22 "AN" "ANA" "AND" "ANN" "ANT" "ANY" "APE" "APS" 23 "APT" "ARC" "ARE" "ARK" "ARM" "ART" "AS" "ASH" 24 "ASK" "AT" "ATE" "AUG" "AUK" "AVE" "AWE" "AWK" 25 "AWL" "AWN" "AX" "AYE" "BAD" "BAG" "BAH" "BAM" 26 "BAN" "BAR" "BAT" "BAY" "BE" "BED" "BEE" "BEG" 27 "BEN" "BET" "BEY" "BIB" "BID" "BIG" "BIN" "BIT" 28 "BOB" "BOG" "BON" "BOO" "BOP" "BOW" "BOY" "BUB" 29 "BUD" "BUG" "BUM" "BUN" "BUS" "BUT" "BUY" "BY" 30 "BYE" "CAB" "CAL" "CAM" "CAN" "CAP" "CAR" "CAT" 31 "CAW" "COD" "COG" "COL" "CON" "COO" "COP" "COT" 32 "COW" "COY" "CRY" "CUB" "CUE" "CUP" "CUR" "CUT" 33 "DAB" "DAD" "DAM" "DAN" "DAR" "DAY" "DEE" "DEL" 34 "DEN" "DES" "DEW" "DID" "DIE" "DIG" "DIN" "DIP" 35 "DO" "DOE" "DOG" "DON" "DOT" "DOW" "DRY" "DUB" 36 "DUD" "DUE" "DUG" "DUN" "EAR" "EAT" "ED" "EEL" 37 "EGG" "EGO" "ELI" "ELK" "ELM" "ELY" "EM" "END" 38 "EST" "ETC" "EVA" "EVE" "EWE" "EYE" "FAD" "FAN" 39 "FAR" "FAT" "FAY" "FED" "FEE" "FEW" "FIB" "FIG" 40 "FIN" "FIR" "FIT" "FLO" "FLY" "FOE" "FOG" "FOR" 41 "FRY" "FUM" "FUN" "FUR" "GAB" "GAD" "GAG" "GAL" 42 "GAM" "GAP" "GAS" "GAY" "GEE" "GEL" "GEM" "GET" 43 "GIG" "GIL" "GIN" "GO" "GOT" "GUM" "GUN" "GUS" 44 "GUT" "GUY" "GYM" "GYP" "HA" "HAD" "HAL" "HAM" 45 "HAN" "HAP" "HAS" "HAT" "HAW" "HAY" "HE" "HEM" 46 "HEN" "HER" "HEW" "HEY" "HI" "HID" "HIM" "HIP" 47 "HIS" "HIT" "HO" "HOB" "HOC" "HOE" "HOG" "HOP" 48 "HOT" "HOW" "HUB" "HUE" "HUG" "HUH" "HUM" "HUT" 49 "I" "ICY" "IDA" "IF" "IKE" "ILL" "INK" "INN" 50 "IO" "ION" "IQ" "IRA" "IRE" "IRK" "IS" "IT" 51 "ITS" "IVY" "JAB" "JAG" "JAM" "JAN" "JAR" "JAW" 52 "JAY" "JET" "JIG" "JIM" "JO" "JOB" "JOE" "JOG" 53 "JOT" "JOY" "JUG" "JUT" "KAY" "KEG" "KEN" "KEY" 54 "KID" "KIM" "KIN" "KIT" "LA" "LAB" "LAC" "LAD" 55 "LAG" "LAM" "LAP" "LAW" "LAY" "LEA" "LED" "LEE" 56 "LEG" "LEN" "LEO" "LET" "LEW" "LID" "LIE" "LIN" 57 "LIP" "LIT" "LO" "LOB" "LOG" "LOP" "LOS" "LOT" 58 "LOU" "LOW" "LOY" "LUG" "LYE" "MA" "MAC" "MAD" 59 "MAE" "MAN" "MAO" "MAP" "MAT" "MAW" "MAY" "ME" 60 "MEG" "MEL" "MEN" "MET" "MEW" "MID" "MIN" "MIT" 61 "MOB" "MOD" "MOE" "MOO" "MOP" "MOS" "MOT" "MOW" 62 "MUD" "MUG" "MUM" "MY" "NAB" "NAG" "NAN" "NAP" 63 "NAT" "NAY" "NE" "NED" "NEE" "NET" "NEW" "NIB" 64 "NIL" "NIP" "NIT" "NO" "NOB" "NOD" "NON" "NOR" 65 "NOT" "NOV" "NOW" "NU" "NUN" "NUT" "O" "OAF" 66 "OAK" "OAR" "OAT" "ODD" "ODE" "OF" "OFF" "OFT" 67 "OH" "OIL" "OK" "OLD" "ON" "ONE" "OR" "ORB" 68 "ORE" "ORR" "OS" "OTT" "OUR" "OUT" "OVA" "OW" 69 "OWE" "OWL" "OWN" "OX" "PA" "PAD" "PAL" "PAM" 70 "PAN" "PAP" "PAR" "PAT" "PAW" "PAY" "PEA" "PEG" 71 "PEN" "PEP" "PER" "PET" "PEW" "PHI" "PI" "PIE" 72 "PIN" "PIT" "PLY" "PO" "POD" "POE" "POP" "POT" 73 "POW" "PRO" "PRY" "PUB" "PUG" "PUN" "PUP" "PUT" 74 "QUO" "RAG" "RAM" "RAN" "RAP" "RAT" "RAW" "RAY" 75 "REB" "RED" "REP" "RET" "RIB" "RID" "RIG" "RIM" 76 "RIO" "RIP" "ROB" "ROD" "ROE" "RON" "ROT" "ROW" 77 "ROY" "RUB" "RUE" "RUG" "RUM" "RUN" "RYE" "SAC" 78 "SAD" "SAG" "SAL" "SAM" "SAN" "SAP" "SAT" "SAW" 79 "SAY" "SEA" "SEC" "SEE" "SEN" "SET" "SEW" "SHE" 80 "SHY" "SIN" "SIP" "SIR" "SIS" "SIT" "SKI" "SKY" 81 "SLY" "SO" "SOB" "SOD" "SON" "SOP" "SOW" "SOY" 82 "SPA" "SPY" "SUB" "SUD" "SUE" "SUM" "SUN" "SUP" 83 "TAB" "TAD" "TAG" "TAN" "TAP" "TAR" "TEA" "TED" 84 "TEE" "TEN" "THE" "THY" "TIC" "TIE" "TIM" "TIN" 85 "TIP" "TO" "TOE" "TOG" "TOM" "TON" "TOO" "TOP" 86 "TOW" "TOY" "TRY" "TUB" "TUG" "TUM" "TUN" "TWO" 87 "UN" "UP" "US" "USE" "VAN" "VAT" "VET" "VIE" 88 "WAD" "WAG" "WAR" "WAS" "WAY" "WE" "WEB" "WED" 89 "WEE" "WET" "WHO" "WHY" "WIN" "WIT" "WOK" "WON" 90 "WOO" "WOW" "WRY" "WU" "YAM" "YAP" "YAW" "YE" 91 "YEA" "YES" "YET" "YOU" "ABED" "ABEL" "ABET" "ABLE" 92 "ABUT" "ACHE" "ACID" "ACME" "ACRE" "ACTA" "ACTS" "ADAM" 93 "ADDS" "ADEN" "AFAR" "AFRO" "AGEE" "AHEM" "AHOY" "AIDA" 94 "AIDE" "AIDS" "AIRY" "AJAR" "AKIN" "ALAN" "ALEC" "ALGA" 95 "ALIA" "ALLY" "ALMA" "ALOE" "ALSO" "ALTO" "ALUM" "ALVA" 96 "AMEN" "AMES" "AMID" "AMMO" "AMOK" "AMOS" "AMRA" "ANDY" 97 "ANEW" "ANNA" "ANNE" "ANTE" "ANTI" "AQUA" "ARAB" "ARCH" 98 "AREA" "ARGO" "ARID" "ARMY" "ARTS" "ARTY" "ASIA" "ASKS" 99 "ATOM" "AUNT" "AURA" "AUTO" "AVER" "AVID" "AVIS" "AVON" 100 "AVOW" "AWAY" "AWRY" "BABE" "BABY" "BACH" "BACK" "BADE" 101 "BAIL" "BAIT" "BAKE" "BALD" "BALE" "BALI" "BALK" "BALL" 102 "BALM" "BAND" "BANE" "BANG" "BANK" "BARB" "BARD" "BARE" 103 "BARK" "BARN" "BARR" "BASE" "BASH" "BASK" "BASS" "BATE" 104 "BATH" "BAWD" "BAWL" "BEAD" "BEAK" "BEAM" "BEAN" "BEAR" 105 "BEAT" "BEAU" "BECK" "BEEF" "BEEN" "BEER" "BEET" "BELA" 106 "BELL" "BELT" "BEND" "BENT" "BERG" "BERN" "BERT" "BESS" 107 "BEST" "BETA" "BETH" "BHOY" "BIAS" "BIDE" "BIEN" "BILE" 108 "BILK" "BILL" "BIND" "BING" "BIRD" "BITE" "BITS" "BLAB" 109 "BLAT" "BLED" "BLEW" "BLOB" "BLOC" "BLOT" "BLOW" "BLUE" 110 "BLUM" "BLUR" "BOAR" "BOAT" "BOCA" "BOCK" "BODE" "BODY" 111 "BOGY" "BOHR" "BOIL" "BOLD" "BOLO" "BOLT" "BOMB" "BONA" 112 "BOND" "BONE" "BONG" "BONN" "BONY" "BOOK" "BOOM" "BOON" 113 "BOOT" "BORE" "BORG" "BORN" "BOSE" "BOSS" "BOTH" "BOUT" 114 "BOWL" "BOYD" "BRAD" "BRAE" "BRAG" "BRAN" "BRAY" "BRED" 115 "BREW" "BRIG" "BRIM" "BROW" "BUCK" "BUDD" "BUFF" "BULB" 116 "BULK" "BULL" "BUNK" "BUNT" "BUOY" "BURG" "BURL" "BURN" 117 "BURR" "BURT" "BURY" "BUSH" "BUSS" "BUST" "BUSY" "BYTE" 118 "CADY" "CAFE" "CAGE" "CAIN" "CAKE" "CALF" "CALL" "CALM" 119 "CAME" "CANE" "CANT" "CARD" "CARE" "CARL" "CARR" "CART" 120 "CASE" "CASH" "CASK" "CAST" "CAVE" "CEIL" "CELL" "CENT" 121 "CERN" "CHAD" "CHAR" "CHAT" "CHAW" "CHEF" "CHEN" "CHEW" 122 "CHIC" "CHIN" "CHOU" "CHOW" "CHUB" "CHUG" "CHUM" "CITE" 123 "CITY" "CLAD" "CLAM" "CLAN" "CLAW" "CLAY" "CLOD" "CLOG" 124 "CLOT" "CLUB" "CLUE" "COAL" "COAT" "COCA" "COCK" "COCO" 125 "CODA" "CODE" "CODY" "COED" "COIL" "COIN" "COKE" "COLA" 126 "COLD" "COLT" "COMA" "COMB" "COME" "COOK" "COOL" "COON" 127 "COOT" "CORD" "CORE" "CORK" "CORN" "COST" "COVE" "COWL" 128 "CRAB" "CRAG" "CRAM" "CRAY" "CREW" "CRIB" "CROW" "CRUD" 129 "CUBA" "CUBE" "CUFF" "CULL" "CULT" "CUNY" "CURB" "CURD" 130 "CURE" "CURL" "CURT" "CUTS" "DADE" "DALE" "DAME" "DANA" 131 "DANE" "DANG" "DANK" "DARE" "DARK" "DARN" "DART" "DASH" 132 "DATA" "DATE" "DAVE" "DAVY" "DAWN" "DAYS" "DEAD" "DEAF" 133 "DEAL" "DEAN" "DEAR" "DEBT" "DECK" "DEED" "DEEM" "DEER" 134 "DEFT" "DEFY" "DELL" "DENT" "DENY" "DESK" "DIAL" "DICE" 135 "DIED" "DIET" "DIME" "DINE" "DING" "DINT" "DIRE" "DIRT" 136 "DISC" "DISH" "DISK" "DIVE" "DOCK" "DOES" "DOLE" "DOLL" 137 "DOLT" "DOME" "DONE" "DOOM" "DOOR" "DORA" "DOSE" "DOTE" 138 "DOUG" "DOUR" "DOVE" "DOWN" "DRAB" "DRAG" "DRAM" "DRAW" 139 "DREW" "DRUB" "DRUG" "DRUM" "DUAL" "DUCK" "DUCT" "DUEL" 140 "DUET" "DUKE" "DULL" "DUMB" "DUNE" "DUNK" "DUSK" "DUST" 141 "DUTY" "EACH" "EARL" "EARN" "EASE" "EAST" "EASY" "EBEN" 142 "ECHO" "EDDY" "EDEN" "EDGE" "EDGY" "EDIT" "EDNA" "EGAN" 143 "ELAN" "ELBA" "ELLA" "ELSE" "EMIL" "EMIT" "EMMA" "ENDS" 144 "ERIC" "EROS" "EVEN" "EVER" "EVIL" "EYED" "FACE" "FACT" 145 "FADE" "FAIL" "FAIN" "FAIR" "FAKE" "FALL" "FAME" "FANG" 146 "FARM" "FAST" "FATE" "FAWN" "FEAR" "FEAT" "FEED" "FEEL" 147 "FEET" "FELL" "FELT" "FEND" "FERN" "FEST" "FEUD" "FIEF" 148 "FIGS" "FILE" "FILL" "FILM" "FIND" "FINE" "FINK" "FIRE" 149 "FIRM" "FISH" "FISK" "FIST" "FITS" "FIVE" "FLAG" "FLAK" 150 "FLAM" "FLAT" "FLAW" "FLEA" "FLED" "FLEW" "FLIT" "FLOC" 151 "FLOG" "FLOW" "FLUB" "FLUE" "FOAL" "FOAM" "FOGY" "FOIL" 152 "FOLD" "FOLK" "FOND" "FONT" "FOOD" "FOOL" "FOOT" "FORD" 153 "FORE" "FORK" "FORM" "FORT" "FOSS" "FOUL" "FOUR" "FOWL" 154 "FRAU" "FRAY" "FRED" "FREE" "FRET" "FREY" "FROG" "FROM" 155 "FUEL" "FULL" "FUME" "FUND" "FUNK" "FURY" "FUSE" "FUSS" 156 "GAFF" "GAGE" "GAIL" "GAIN" "GAIT" "GALA" "GALE" "GALL" 157 "GALT" "GAME" "GANG" "GARB" "GARY" "GASH" "GATE" "GAUL" 158 "GAUR" "GAVE" "GAWK" "GEAR" "GELD" "GENE" "GENT" "GERM" 159 "GETS" "GIBE" "GIFT" "GILD" "GILL" "GILT" "GINA" "GIRD" 160 "GIRL" "GIST" "GIVE" "GLAD" "GLEE" "GLEN" "GLIB" "GLOB" 161 "GLOM" "GLOW" "GLUE" "GLUM" "GLUT" "GOAD" "GOAL" "GOAT" 162 "GOER" "GOES" "GOLD" "GOLF" "GONE" "GONG" "GOOD" "GOOF" 163 "GORE" "GORY" "GOSH" "GOUT" "GOWN" "GRAB" "GRAD" "GRAY" 164 "GREG" "GREW" "GREY" "GRID" "GRIM" "GRIN" "GRIT" "GROW" 165 "GRUB" "GULF" "GULL" "GUNK" "GURU" "GUSH" "GUST" "GWEN" 166 "GWYN" "HAAG" "HAAS" "HACK" "HAIL" "HAIR" "HALE" "HALF" 167 "HALL" "HALO" "HALT" "HAND" "HANG" "HANK" "HANS" "HARD" 168 "HARK" "HARM" "HART" "HASH" "HAST" "HATE" "HATH" "HAUL" 169 "HAVE" "HAWK" "HAYS" "HEAD" "HEAL" "HEAR" "HEAT" "HEBE" 170 "HECK" "HEED" "HEEL" "HEFT" "HELD" "HELL" "HELM" "HERB" 171 "HERD" "HERE" "HERO" "HERS" "HESS" "HEWN" "HICK" "HIDE" 172 "HIGH" "HIKE" "HILL" "HILT" "HIND" "HINT" "HIRE" "HISS" 173 "HIVE" "HOBO" "HOCK" "HOFF" "HOLD" "HOLE" "HOLM" "HOLT" 174 "HOME" "HONE" "HONK" "HOOD" "HOOF" "HOOK" "HOOT" "HORN" 175 "HOSE" "HOST" "HOUR" "HOVE" "HOWE" "HOWL" "HOYT" "HUCK" 176 "HUED" "HUFF" "HUGE" "HUGH" "HUGO" "HULK" "HULL" "HUNK" 177 "HUNT" "HURD" "HURL" "HURT" "HUSH" "HYDE" "HYMN" "IBIS" 178 "ICON" "IDEA" "IDLE" "IFFY" "INCA" "INCH" "INTO" "IONS" 179 "IOTA" "IOWA" "IRIS" "IRMA" "IRON" "ISLE" "ITCH" "ITEM" 180 "IVAN" "JACK" "JADE" "JAIL" "JAKE" "JANE" "JAVA" "JEAN" 181 "JEFF" "JERK" "JESS" "JEST" "JIBE" "JILL" "JILT" "JIVE" 182 "JOAN" "JOBS" "JOCK" "JOEL" "JOEY" "JOHN" "JOIN" "JOKE" 183 "JOLT" "JOVE" "JUDD" "JUDE" "JUDO" "JUDY" "JUJU" "JUKE" 184 "JULY" "JUNE" "JUNK" "JUNO" "JURY" "JUST" "JUTE" "KAHN" 185 "KALE" "KANE" "KANT" "KARL" "KATE" "KEEL" "KEEN" "KENO" 186 "KENT" "KERN" "KERR" "KEYS" "KICK" "KILL" "KIND" "KING" 187 "KIRK" "KISS" "KITE" "KLAN" "KNEE" "KNEW" "KNIT" "KNOB" 188 "KNOT" "KNOW" "KOCH" "KONG" "KUDO" "KURD" "KURT" "KYLE" 189 "LACE" "LACK" "LACY" "LADY" "LAID" "LAIN" "LAIR" "LAKE" 190 "LAMB" "LAME" "LAND" "LANE" "LANG" "LARD" "LARK" "LASS" 191 "LAST" "LATE" "LAUD" "LAVA" "LAWN" "LAWS" "LAYS" "LEAD" 192 "LEAF" "LEAK" "LEAN" "LEAR" "LEEK" "LEER" "LEFT" "LEND" 193 "LENS" "LENT" "LEON" "LESK" "LESS" "LEST" "LETS" "LIAR" 194 "LICE" "LICK" "LIED" "LIEN" "LIES" "LIEU" "LIFE" "LIFT" 195 "LIKE" "LILA" "LILT" "LILY" "LIMA" "LIMB" "LIME" "LIND" 196 "LINE" "LINK" "LINT" "LION" "LISA" "LIST" "LIVE" "LOAD" 197 "LOAF" "LOAM" "LOAN" "LOCK" "LOFT" "LOGE" "LOIS" "LOLA" 198 "LONE" "LONG" "LOOK" "LOON" "LOOT" "LORD" "LORE" "LOSE" 199 "LOSS" "LOST" "LOUD" "LOVE" "LOWE" "LUCK" "LUCY" "LUGE" 200 "LUKE" "LULU" "LUND" "LUNG" "LURA" "LURE" "LURK" "LUSH" 201 "LUST" "LYLE" "LYNN" "LYON" "LYRA" "MACE" "MADE" "MAGI" 202 "MAID" "MAIL" "MAIN" "MAKE" "MALE" "MALI" "MALL" "MALT" 203 "MANA" "MANN" "MANY" "MARC" "MARE" "MARK" "MARS" "MART" 204 "MARY" "MASH" "MASK" "MASS" "MAST" "MATE" "MATH" "MAUL" 205 "MAYO" "MEAD" "MEAL" "MEAN" "MEAT" "MEEK" "MEET" "MELD" 206 "MELT" "MEMO" "MEND" "MENU" "MERT" "MESH" "MESS" "MICE" 207 "MIKE" "MILD" "MILE" "MILK" "MILL" "MILT" "MIMI" "MIND" 208 "MINE" "MINI" "MINK" "MINT" "MIRE" "MISS" "MIST" "MITE" 209 "MITT" "MOAN" "MOAT" "MOCK" "MODE" "MOLD" "MOLE" "MOLL" 210 "MOLT" "MONA" "MONK" "MONT" "MOOD" "MOON" "MOOR" "MOOT" 211 "MORE" "MORN" "MORT" "MOSS" "MOST" "MOTH" "MOVE" "MUCH" 212 "MUCK" "MUDD" "MUFF" "MULE" "MULL" "MURK" "MUSH" "MUST" 213 "MUTE" "MUTT" "MYRA" "MYTH" "NAGY" "NAIL" "NAIR" "NAME" 214 "NARY" "NASH" "NAVE" "NAVY" "NEAL" "NEAR" "NEAT" "NECK" 215 "NEED" "NEIL" "NELL" "NEON" "NERO" "NESS" "NEST" "NEWS" 216 "NEWT" "NIBS" "NICE" "NICK" "NILE" "NINA" "NINE" "NOAH" 217 "NODE" "NOEL" "NOLL" "NONE" "NOOK" "NOON" "NORM" "NOSE" 218 "NOTE" "NOUN" "NOVA" "NUDE" "NULL" "NUMB" "OATH" "OBEY" 219 "OBOE" "ODIN" "OHIO" "OILY" "OINT" "OKAY" "OLAF" "OLDY" 220 "OLGA" "OLIN" "OMAN" "OMEN" "OMIT" "ONCE" "ONES" "ONLY" 221 "ONTO" "ONUS" "ORAL" "ORGY" "OSLO" "OTIS" "OTTO" "OUCH" 222 "OUST" "OUTS" "OVAL" "OVEN" "OVER" "OWLY" "OWNS" "QUAD" 223 "QUIT" "QUOD" "RACE" "RACK" "RACY" "RAFT" "RAGE" "RAID" 224 "RAIL" "RAIN" "RAKE" "RANK" "RANT" "RARE" "RASH" "RATE" 225 "RAVE" "RAYS" "READ" "REAL" "REAM" "REAR" "RECK" "REED" 226 "REEF" "REEK" "REEL" "REID" "REIN" "RENA" "REND" "RENT" 227 "REST" "RICE" "RICH" "RICK" "RIDE" "RIFT" "RILL" "RIME" 228 "RING" "RINK" "RISE" "RISK" "RITE" "ROAD" "ROAM" "ROAR" 229 "ROBE" "ROCK" "RODE" "ROIL" "ROLL" "ROME" "ROOD" "ROOF" 230 "ROOK" "ROOM" "ROOT" "ROSA" "ROSE" "ROSS" "ROSY" "ROTH" 231 "ROUT" "ROVE" "ROWE" "ROWS" "RUBE" "RUBY" "RUDE" "RUDY" 232 "RUIN" "RULE" "RUNG" "RUNS" "RUNT" "RUSE" "RUSH" "RUSK" 233 "RUSS" "RUST" "RUTH" "SACK" "SAFE" "SAGE" "SAID" "SAIL" 234 "SALE" "SALK" "SALT" "SAME" "SAND" "SANE" "SANG" "SANK" 235 "SARA" "SAUL" "SAVE" "SAYS" "SCAN" "SCAR" "SCAT" "SCOT" 236 "SEAL" "SEAM" "SEAR" "SEAT" "SEED" "SEEK" "SEEM" "SEEN" 237 "SEES" "SELF" "SELL" "SEND" "SENT" "SETS" "SEWN" "SHAG" 238 "SHAM" "SHAW" "SHAY" "SHED" "SHIM" "SHIN" "SHOD" "SHOE" 239 "SHOT" "SHOW" "SHUN" "SHUT" "SICK" "SIDE" "SIFT" "SIGH" 240 "SIGN" "SILK" "SILL" "SILO" "SILT" "SINE" "SING" "SINK" 241 "SIRE" "SITE" "SITS" "SITU" "SKAT" "SKEW" "SKID" "SKIM" 242 "SKIN" "SKIT" "SLAB" "SLAM" "SLAT" "SLAY" "SLED" "SLEW" 243 "SLID" "SLIM" "SLIT" "SLOB" "SLOG" "SLOT" "SLOW" "SLUG" 244 "SLUM" "SLUR" "SMOG" "SMUG" "SNAG" "SNOB" "SNOW" "SNUB" 245 "SNUG" "SOAK" "SOAR" "SOCK" "SODA" "SOFA" "SOFT" "SOIL" 246 "SOLD" "SOME" "SONG" "SOON" "SOOT" "SORE" "SORT" "SOUL" 247 "SOUR" "SOWN" "STAB" "STAG" "STAN" "STAR" "STAY" "STEM" 248 "STEW" "STIR" "STOW" "STUB" "STUN" "SUCH" "SUDS" "SUIT" 249 "SULK" "SUMS" "SUNG" "SUNK" "SURE" "SURF" "SWAB" "SWAG" 250 "SWAM" "SWAN" "SWAT" "SWAY" "SWIM" "SWUM" "TACK" "TACT" 251 "TAIL" "TAKE" "TALE" "TALK" "TALL" "TANK" "TASK" "TATE" 252 "TAUT" "TEAL" "TEAM" "TEAR" "TECH" "TEEM" "TEEN" "TEET" 253 "TELL" "TEND" "TENT" "TERM" "TERN" "TESS" "TEST" "THAN" 254 "THAT" "THEE" "THEM" "THEN" "THEY" "THIN" "THIS" "THUD" 255 "THUG" "TICK" "TIDE" "TIDY" "TIED" "TIER" "TILE" "TILL" 256 "TILT" "TIME" "TINA" "TINE" "TINT" "TINY" "TIRE" "TOAD" 257 "TOGO" "TOIL" "TOLD" "TOLL" "TONE" "TONG" "TONY" "TOOK" 258 "TOOL" "TOOT" "TORE" "TORN" "TOTE" "TOUR" "TOUT" "TOWN" 259 "TRAG" "TRAM" "TRAY" "TREE" "TREK" "TRIG" "TRIM" "TRIO" 260 "TROD" "TROT" "TROY" "TRUE" "TUBA" "TUBE" "TUCK" "TUFT" 261 "TUNA" "TUNE" "TUNG" "TURF" "TURN" "TUSK" "TWIG" "TWIN" 262 "TWIT" "ULAN" "UNIT" "URGE" "USED" "USER" "USES" "UTAH" 263 "VAIL" "VAIN" "VALE" "VARY" "VASE" "VAST" "VEAL" "VEDA" 264 "VEIL" "VEIN" "VEND" "VENT" "VERB" "VERY" "VETO" "VICE" 265 "VIEW" "VINE" "VISE" "VOID" "VOLT" "VOTE" "WACK" "WADE" 266 "WAGE" "WAIL" "WAIT" "WAKE" "WALE" "WALK" "WALL" "WALT" 267 "WAND" "WANE" "WANG" "WANT" "WARD" "WARM" "WARN" "WART" 268 "WASH" "WAST" "WATS" "WATT" "WAVE" "WAVY" "WAYS" "WEAK" 269 "WEAL" "WEAN" "WEAR" "WEED" "WEEK" "WEIR" "WELD" "WELL" 270 "WELT" "WENT" "WERE" "WERT" "WEST" "WHAM" "WHAT" "WHEE" 271 "WHEN" "WHET" "WHOA" "WHOM" "WICK" "WIFE" "WILD" "WILL" 272 "WIND" "WINE" "WING" "WINK" "WINO" "WIRE" "WISE" "WISH" 273 "WITH" "WOLF" "WONT" "WOOD" "WOOL" "WORD" "WORE" "WORK" 274 "WORM" "WORN" "WOVE" "WRIT" "WYNN" "YALE" "YANG" "YANK" 275 "YARD" "YARN" "YAWL" "YAWN" "YEAH" "YEAR" "YELL" "YOGA" 276 "YOKE" 277 } 278} 279 280# Encode 64 bits as words selected from the RFC 2289 dictionary. 281# See the RFC for details. Briefly the input is broken into 11 bit 282# chunks + 2bits of checksum and each chunk selects a word from the 283# 2048 word table. 284# 285proc ::otp::otp_encode {data} { 286 variable Words 287 if {[string length $data] != 8} { 288 set bc [expr {[string length $data] * 8}] 289 return -code error "invalid input: 64 bits of data\ 290 required and $bc bits provided" 291 } 292 binary scan $data II A B 293 294 set cksum 0 295 foreach w [list $A $B] { 296 for {set n 0} {$n < 32} {incr n 2} { 297 incr cksum [expr {($w >> $n) & 3}] 298 } 299 } 300 301 set W0 [expr { (($A & 0xFFE00000) >> 21) & 0x07ff}] 302 set W1 [expr { (($A & 0x001FFC00) >> 10)}] 303 set W2 [expr { (($A & 0x000003FF) << 1) | (($B >> 31) & 0x1)}] 304 set W3 [expr { ($B & 0x7FF00000) >> 20}] 305 set W4 [expr { ($B & 0x000FFE00) >> 9}] 306 set W5 [expr { (($B & 0x000001FF) << 2) | ($cksum & 3)}] 307 308 foreach w [list $W0 $W1 $W2 $W3 $W4 $W5] { 309 lappend words [lindex $Words $w] 310 } 311 312 return $words 313} 314 315# Fold a 128 bit digest in little-endian format into a 64 bit 316# little-endian output 317proc ::otp::Fold64LE {digest} { 318 binary scan $digest iiii A B C D 319 set w0 [expr {($A ^ $C) & 0xffffffff}] 320 set w1 [expr {($B ^ $D) & 0xffffffff}] 321 binary format ii $w0 $w1 322} 323 324# Fold a160 bit big-endian digest (SHA-1) into a 64 bit 325# little-endian output 326proc ::otp::Fold160BE {digest} { 327 binary scan $digest IIIII A B C D E 328 set w0 [expr {(($A ^ $C) ^ $E) & 0xffffffff}] 329 set w1 [expr { ($B ^ $D) & 0xffffffff}] 330 binary format ii $w0 $w1 331} 332 333# Fold a 160 bit little-endian digest into a 64 bit 334# little-endian output. 335proc ::otp::Fold160LE {digest} { 336 binary scan $digest iiiii A B C D E 337 set w0 [expr {(($A ^ $C) ^ $E) & 0xffffffff}] 338 set w1 [expr { ($B ^ $D) & 0xffffffff}] 339 binary format ii $w0 $w1 340} 341 342# Description: 343# Pop the nth element off a list. Used in options processing. 344# 345proc ::otp::Pop {varname {nth 0}} { 346 upvar $varname args 347 set r [lindex $args $nth] 348 set args [lreplace $args $nth $nth] 349 return $r 350} 351 352proc ::otp::otp {args} { 353 array set opts {-hash md5 -seed {} -count 0 -hex 0 -words 0} 354 while {[string match -* [set option [lindex $args 0]]]} { 355 switch -exact -- $option { 356 -hex { set opts(-hex) 1} 357 -word - 358 -words { set opts(-words) 1 } 359 -hash { set opts(-hash) [Pop args 1] } 360 -seed { set opts(-seed) [Pop args 1] } 361 -count { set opts(-count) [Pop args 1] } 362 default { 363 if {[llength $args] == 1} { break } 364 if {[string compare $option "--"] == 0} { Pop args; break } 365 set err [join [lsort [array names opts]] ", "] 366 return -code error "bad option \"$option\":\ 367 must be one of $err" 368 } 369 } 370 Pop args 371 } 372 373 set data [lindex $args 0] 374 375 if {[string length $opts(-seed)] < 1 || [string length $opts(-seed)] > 16} { 376 return -code error "seed must be between 1 and 16 characters in length" 377 } 378 switch -exact -- $opts(-hash) { 379 md4 { set func ::md4::md4 ; set fold ::otp::Fold64LE } 380 md5 { set func ::md5::md5 ; set fold ::otp::Fold64LE } 381 sha1 { set func ::otp::sha1 ; set fold ::otp::Fold160BE } 382 rmd160 { set func ::ripemd::ripemd160 ; set fold ::otp::Fold160LE } 383 default { 384 return -code error "invalid hash type \"$opts(-hash)\":\ 385 must be one of md4, md5, rmd160 or sha1" 386 } 387 } 388 # RFC 2289: Initial step 389 set S [$fold [$func [string tolower $opts(-seed)]$data]] 390 391 # RFC2289:6 Computation step 392 for {set n 0} {$n < $opts(-count)} {incr n} { 393 set S [$fold [$func $S]] 394 } 395 396 if {$opts(-hex)} { 397 binary scan $S H* S 398 } elseif {$opts(-words)} { 399 set S [otp_encode $S] 400 } 401 return $S 402} 403 404proc ::otp::otp-md4 {args} { 405 package require md4 406 return [eval [linsert $args 0 [namespace current]::otp -hash md4]] 407} 408 409proc ::otp::otp-md5 {args} { 410 package require md5 411 return [eval [linsert $args 0 [namespace current]::otp -hash md5]] 412} 413 414proc ::otp::otp-sha1 {args} { 415 package require sha1 416 interp alias {} ::otp::sha1 {} ::sha1::sha1 -bin 417 return [eval [linsert $args 0 [namespace current]::otp -hash sha1]] 418} 419 420proc ::otp::otp-rmd160 {args} { 421 package require ripemd160 422 return [eval [linsert $args 0 [namespace current]::otp -hash rmd160]] 423} 424 425# ------------------------------------------------------------------------- 426 427package provide otp $::otp::version 428 429# ------------------------------------------------------------------------- 430# Local Variables: 431# mode: tcl 432# indent-tabs-mode: nil 433# End: 434