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