Small cleanups
[shamirs] / pgp-words.c
1 /*
2  * Shamir's secret sharing PGP Words Dumping
3  *
4  * Copyright (C) 2013 Matt Corallo <git@bluematt.me>
5  *
6  * This file is part of ASSS (Audit-friendly Shamir's Secret Sharing)
7  *
8  * ASSS is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Affero General Public License as
10  * published by the Free Software Foundation,   either version 3 of
11  * the License, or (at your option) any later version.
12  *
13  * ASSS is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Affero General Public License for more details.
17
18  * You should have received a copy of the GNU Affero General Public
19  * License along with ASSS.  If not,    see
20  * <http://www.gnu.org/licenses/>.
21  */
22
23 #define _POSIX_C_SOURCE 200809L
24 #include <unistd.h>
25 #include <stdio.h>
26 #include <getopt.h>
27 #include <assert.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <strings.h>
31
32 static const char* words[256][2] = {
33         // even word,   odd word
34         {"aardvark",    "adroitness"},
35         {"absurd",              "adviser"},
36         {"accrue",              "aftermath"},
37         {"acme",                "aggregate"},
38         {"adrift",              "alkali"},
39         {"adult",               "almighty"},
40         {"afflict",             "amulet"},
41         {"ahead",               "amusement"},
42         {"aimless",             "antenna"},
43         {"Algol",               "applicant"},
44         {"allow",               "Apollo"},
45         {"alone",               "armistice"},
46         {"ammo",                "article"},
47         {"ancient",             "asteroid"},
48         {"apple",               "Atlantic"},
49         {"artist",              "atmosphere"},
50         {"assume",              "autopsy"},
51         {"Athens",              "Babylon"},
52         {"atlas",               "backwater"},
53         {"Aztec",               "barbecue"},
54         {"baboon",              "belowground"},
55         {"backfield",   "bifocals"},
56         {"backward",    "bodyguard"},
57         {"banjo",               "bookseller"},
58         {"beaming",             "borderline"},
59         {"bedlamp",             "bottomless"},
60         {"beehive",             "Bradbury"},
61         {"beeswax",             "bravado"},
62         {"befriend",    "Brazilian"},
63         {"Belfast",             "breakaway"},
64         {"berserk",             "Burlington"},
65         {"billiard",    "businessman"},
66         {"bison",               "butterfat"},
67         {"blackjack",   "Camelot"},
68         {"blockade",    "candidate"},
69         {"blowtorch",   "cannonball"},
70         {"bluebird",    "Capricorn"},
71         {"bombast",             "caravan"},
72         {"bookshelf",   "caretaker"},
73         {"brackish",    "celebrate"},
74         {"breadline",   "cellulose"},
75         {"breakup",             "certify"},
76         {"brickyard",   "chambermaid"},
77         {"briefcase",   "Cherokee"},
78         {"Burbank",             "Chicago"},
79         {"button",              "clergyman"},
80         {"buzzard",             "coherence"},
81         {"cement",              "combustion"},
82         {"chairlift",   "commando"},
83         {"chatter",             "company"},
84         {"checkup",             "component"},
85         {"chisel",              "concurrent"},
86         {"choking",             "confidence"},
87         {"chopper",             "conformist"},
88         {"Christmas",   "congregate"},
89         {"clamshell",   "consensus"},
90         {"classic",             "consulting"},
91         {"classroom",   "corporate"},
92         {"cleanup",             "corrosion"},
93         {"clockwork",   "councilman"},
94         {"cobra",               "crossover"},
95         {"commence",    "crucifix"},
96         {"concert",             "cumbersome"},
97         {"cowbell",             "customer"},
98         {"crackdown",   "Dakota"},
99         {"cranky",              "decadence"},
100         {"crowfoot",    "December"},
101         {"crucial",             "decimal"},
102         {"crumpled",    "designing"},
103         {"crusade",             "detector"},
104         {"cubic",               "detergent"},
105         {"dashboard",   "determine"},
106         {"deadbolt",    "dictator"},
107         {"deckhand",    "dinosaur"},
108         {"dogsled",             "direction"},
109         {"dragnet",             "disable"},
110         {"drainage",    "disbelief"},
111         {"dreadful",    "disruptive"},
112         {"drifter",             "distortion"},
113         {"dropper",             "document"},
114         {"drumbeat",    "embezzle"},
115         {"drunken",             "enchanting"},
116         {"Dupont",              "enrollment"},
117         {"dwelling",    "enterprise"},
118         {"eating",              "equation"},
119         {"edict",               "equipment"},
120         {"egghead",             "escapade"},
121         {"eightball",   "Eskimo"},
122         {"endorse",             "everyday"},
123         {"endow",               "examine"},
124         {"enlist",              "existence"},
125         {"erase",               "exodus"},
126         {"escape",              "fascinate"},
127         {"exceed",              "filament"},
128         {"eyeglass",    "finicky"},
129         {"eyetooth",    "forever"},
130         {"facial",              "fortitude"},
131         {"fallout",             "frequency"},
132         {"flagpole",    "gadgetry"},
133         {"flatfoot",    "Galveston"},
134         {"flytrap",             "getaway"},
135         {"fracture",    "glossary"},
136         {"framework",   "gossamer"},
137         {"freedom",             "graduate"},
138         {"frighten",    "gravity"},
139         {"gazelle",             "guitarist"},
140         {"Geiger",              "hamburger"},
141         {"glitter",             "Hamilton"},
142         {"glucose",             "handiwork"},
143         {"goggles",             "hazardous"},
144         {"goldfish",    "headwaters"},
145         {"gremlin",             "hemisphere"},
146         {"guidance",    "hesitate"},
147         {"hamlet",              "hideaway"},
148         {"highchair",   "holiness"},
149         {"hockey",              "hurricane"},
150         {"indoors",             "hydraulic"},
151         {"indulge",             "impartial"},
152         {"inverse",             "impetus"},
153         {"involve",             "inception"},
154         {"island",              "indigo"},
155         {"jawbone",             "inertia"},
156         {"keyboard",    "infancy"},
157         {"kickoff",             "inferno"},
158         {"kiwi",                "informant"},
159         {"klaxon",              "insincere"},
160         {"locale",              "insurgent"},
161         {"lockup",              "integrate"},
162         {"merit",               "intention"},
163         {"minnow",              "inventive"},
164         {"miser",               "Istanbul"},
165         {"Mohawk",              "Jamaica"},
166         {"mural",               "Jupiter"},
167         {"music",               "leprosy"},
168         {"necklace",    "letterhead"},
169         {"Neptune",             "liberty"},
170         {"newborn",             "maritime"},
171         {"nightbird",   "matchmaker"},
172         {"Oakland",             "maverick"},
173         {"obtuse",              "Medusa"},
174         {"offload",             "megaton"},
175         {"optic",               "microscope"},
176         {"orca",                "microwave"},
177         {"payday",              "midsummer"},
178         {"peachy",              "millionaire"},
179         {"pheasant",    "miracle"},
180         {"physique",    "misnomer"},
181         {"playhouse",   "molasses"},
182         {"Pluto",               "molecule"},
183         {"preclude",    "Montana"},
184         {"prefer",              "monument"},
185         {"preshrunk",   "mosquito"},
186         {"printer",             "narrative"},
187         {"prowler",             "nebula"},
188         {"pupil",               "newsletter"},
189         {"puppy",               "Norwegian"},
190         {"python",              "October"},
191         {"quadrant",    "Ohio"},
192         {"quiver",              "onlooker"},
193         {"quota",               "opulent"},
194         {"ragtime",             "Orlando"},
195         {"ratchet",             "outfielder"},
196         {"rebirth",             "Pacific"},
197         {"reform",              "pandemic"},
198         {"regain",              "Pandora"},
199         {"reindeer",    "paperweight"},
200         {"rematch",             "paragon"},
201         {"repay",               "paragraph"},
202         {"retouch",             "paramount"},
203         {"revenge",             "passenger"},
204         {"reward",              "pedigree"},
205         {"rhythm",              "Pegasus"},
206         {"ribcage",             "penetrate"},
207         {"ringbolt",    "perceptive"},
208         {"robust",              "performance"},
209         {"rocker",              "pharmacy"},
210         {"ruffled",             "phonetic"},
211         {"sailboat",    "photograph"},
212         {"sawdust",             "pioneer"},
213         {"scallion",    "pocketful"},
214         {"scenic",              "politeness"},
215         {"scorecard",   "positive"},
216         {"Scotland",    "potato"},
217         {"seabird",             "processor"},
218         {"select",              "provincial"},
219         {"sentence",    "proximate"},
220         {"shadow",              "puberty"},
221         {"shamrock",    "publisher"},
222         {"showgirl",    "pyramid"},
223         {"skullcap",    "quantity"},
224         {"skydive",             "racketeer"},
225         {"slingshot",   "rebellion"},
226         {"slowdown",    "recipe"},
227         {"snapline",    "recover"},
228         {"snapshot",    "repellent"},
229         {"snowcap",             "replica"},
230         {"snowslide",   "reproduce"},
231         {"solo",                "resistor"},
232         {"southward",   "responsive"},
233         {"soybean",             "retraction"},
234         {"spaniel",             "retrieval"},
235         {"spearhead",   "retrospect"},
236         {"spellbind",   "revenue"},
237         {"spheroid",    "revival"},
238         {"spigot",              "revolver"},
239         {"spindle",             "sandalwood"},
240         {"spyglass",    "sardonic"},
241         {"stagehand",   "Saturday"},
242         {"stagnate",    "savagery"},
243         {"stairway",    "scavenger"},
244         {"standard",    "sensation"},
245         {"stapler",             "sociable"},
246         {"steamship",   "souvenir"},
247         {"sterling",    "specialist"},
248         {"stockman",    "speculate"},
249         {"stopwatch",   "stethoscope"},
250         {"stormy",              "stupendous"},
251         {"sugar",               "supportive"},
252         {"surmount",    "surrender"},
253         {"suspense",    "suspicious"},
254         {"sweatband",   "sympathy"},
255         {"swelter",             "tambourine"},
256         {"tactics",             "telephone"},
257         {"talon",               "therapist"},
258         {"tapeworm",    "tobacco"},
259         {"tempest",             "tolerance"},
260         {"tiger",               "tomorrow"},
261         {"tissue",              "torpedo"},
262         {"tonic",               "tradition"},
263         {"topmost",             "travesty"},
264         {"tracker",             "trombonist"},
265         {"transit",             "truncated"},
266         {"trauma",              "typewriter"},
267         {"treadmill",   "ultimate"},
268         {"Trojan",              "undaunted"},
269         {"trouble",             "underfoot"},
270         {"tumor",               "unicorn"},
271         {"tunnel",              "unify"},
272         {"tycoon",              "universe"},
273         {"uncut",               "unravel"},
274         {"unearth",             "upcoming"},
275         {"unwind",              "vacancy"},
276         {"uproot",              "vagabond"},
277         {"upset",               "vertigo"},
278         {"upshot",              "Virginia"},
279         {"vapor",               "visitor"},
280         {"village",             "vocalist"},
281         {"virus",               "voyager"},
282         {"Vulcan",              "warranty"},
283         {"waffle",              "Waterloo"},
284         {"wallet",              "whimsical"},
285         {"watchword",   "Wichita"},
286         {"wayside",             "Wilmington"},
287         {"willow",              "Wyoming"},
288         {"woodlark",    "yesteryear"},
289         {"Zulu",                "Yucatan"}
290 };
291
292 int main(int argc, char* argv[]) {
293         char* input_file = NULL;
294         int i;
295         while ((i = getopt(argc, argv, "f:h?")) != -1) {
296                 switch(i) {
297                 case 'h':
298                 case '?':
299                         printf("Usage: -f filename outputs filename in PGP words\n");
300                         printf("No arguments allows PGP words to be input (one per line) and then outputs the file after EOF/^D\n");
301                         return 0;
302                         break;
303                 case 'f':
304                         input_file = optarg;
305                         break;
306                 default:
307                         printf("Error: Unknown argument: check -?\n");
308                         return -1;
309                 }
310         }
311
312         if (input_file) {
313                 FILE* in = fopen(input_file, "rb");
314                 assert(in);
315                 unsigned char c;
316                 while (1) {
317                         // even word
318                         if (fread(&c, 1, 1, in) != 1)
319                                 break;
320                         printf(words[c][0]);
321                         printf(" ");
322                         // odd word
323                         if (fread(&c, 1, 1, in) != 1)
324                                 break;
325                         printf(words[c][1]);
326                         printf(" ");
327                 }
328                 printf("\n");
329         } else {
330                 char* line = NULL;
331                 size_t line_size = 0;
332                 unsigned char* output = (unsigned char*) malloc(1024);
333                 size_t output_size = 1024, output_index = 0;
334                 int read;
335                 int use_odd = 0;
336                 while ((read = getline(&line, &line_size, stdin)) != -1) {
337                         // Maybe we should use an actual data structure here.....naaaa
338                         if (output_index + 1 >= output_size) {
339                                 output_size += 1024;
340                                 output = realloc(output, output_size);
341                         }
342                         int word = -1;
343                         for (int i = 0; i <= 0xff; i++) {
344                                 if (!strncasecmp(words[i][use_odd], line, strlen(words[i][use_odd])))
345                                         word = i;
346                         }
347                         if (word == -1)
348                                 fprintf(stderr, "Failed to find %s word %s", use_odd ? "odd" : "even", line);
349                         else {
350                                 output[output_index++] = (unsigned char)word;
351                                 use_odd = (use_odd + 1) % 2;
352                         }
353                 }
354                 for (size_t i = 0; i < output_index; i++) // lol efficiency, who needs it?
355                         printf("%c", output[i]);
356         }
357 }