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