chiark / gitweb /
Fix daft error in the comment for @gfshare_get@.
[catacomb] / blowfish-mktab.c
1 /* -*-c-*-
2  *
3  * $Id: blowfish-mktab.c,v 1.1 2000/06/17 10:47:28 mdw Exp $
4  *
5  * Build Blowfish key table
6  *
7  * (c) 2000 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: blowfish-mktab.c,v $
33  * Revision 1.1  2000/06/17 10:47:28  mdw
34  * Emits Blowfish initial key data, derived from the digits of pi.
35  *
36  */
37
38 /*----- Header files ------------------------------------------------------*/
39
40 #include <stdio.h>
41 #include <stdlib.h>
42
43 #include <mLib/bits.h>
44
45 /*----- Main code ---------------------------------------------------------*/
46
47 /* --- @spigot@ --- *
48  *
49  * Arguments:   @uint32 *buf@ = pointer to the output buffer
50  *              @size_t n@ = number of output digits wanted
51  *
52  * Returns:     ---
53  *
54  * Use:         Writes digits of %$\pi$% to the given array.  The algorithm
55  *              is based on the Spigot algorithm by Stanley Rabinowitz and
56  *              Stan Wagon, published in Amer.Math.Monthly, March 1995, with
57  *              bug fixes by C. Haenel.  I then bodged it to output hex
58  *              digits rather than decimal ones, and to leave off the initial
59  *              `3'.
60  *
61  *              I've not analysed the algorithm very much.
62  */
63
64 #define SPIGOT_WORDS (18 + 4 * 256ul)
65 #define SPIGOT_BITS 8
66 #define SPIGOT_RADIX (1ul << SPIGOT_BITS)
67 #define SPIGOT_BUFLEN (SPIGOT_WORDS * 32)
68
69 static void spigot(uint32 *buf, size_t n)
70 {
71   uint32 acc = 0;
72   int b = -1;
73   unsigned a[SPIGOT_BUFLEN] = { 0 };
74   uint32 p = 0;
75   unsigned f = 0;
76   unsigned max = 32 * n;
77   size_t step = n / 60;
78
79   fputs("[                                                             ]\r[",
80         stderr);
81
82 #define EMIT(z) do {                                                    \
83   if (b == -1)                                                          \
84     b = 0;                                                              \
85   else {                                                                \
86     acc = (acc << SPIGOT_BITS) | (z);                                   \
87     b += SPIGOT_BITS;                                                   \
88     if (b == 32) {                                                      \
89       *buf++ = acc;                                                     \
90       acc = 0;                                                          \
91       b = 0;                                                            \
92       n--;                                                              \
93       if (!n)                                                           \
94         goto done;                                                      \
95       if (n % step == 0)                                                \
96         fputc('.', stderr);                                             \
97     }                                                                   \
98   }                                                                     \
99 } while (0)
100
101   while (n) {
102     uint32 q = 0;
103     uint32 i;
104     uint32 x;
105     uint32 k = max * 2 - 1;
106
107     for (i = max; i; i--) {
108       x = (b == -1 ? SPIGOT_RADIX * 2 : a[i - 1] << SPIGOT_BITS) + q * i;
109       q = x / k;
110       a[i - 1] = x - q * k;
111       k -= 2;
112     }
113
114     k = x & (SPIGOT_RADIX - 1);
115     if (k == SPIGOT_RADIX - 1)
116       f++;
117     else {
118       EMIT(p + (x >> SPIGOT_BITS));
119       if (f) {
120         unsigned d = (x >= SPIGOT_RADIX ? 0 : SPIGOT_RADIX - 1);
121         while (f) {
122           EMIT(d);
123           f--;
124         }
125       }
126       p = k;
127     }
128   }
129
130 done:
131   fputc('\n', stderr);
132
133 #undef EMIT
134 }
135
136 /* --- @main@ --- */
137
138 int main(void)
139 {
140   uint32 dbuf[SPIGOT_WORDS];
141   int i, j;
142   uint32 *d = dbuf;
143
144   spigot(d, SPIGOT_WORDS);
145
146   fputs("\
147 /* -*-c-*-\n\
148  *\n\
149  * Blowfish initial key table [generated]\n\
150  */\n\
151 \n\
152 #ifndef CATACOMB_BLOWFISH_TAB_H\n\
153 #define CATACOMB_BLOWFISH_TAB_H\n\
154 \n\
155 #define BLOWFISH_IKEY {                                                 \\\n\
156   { ", stdout);
157
158   for (i = 0; i < 18; i++) {
159     printf("0x%08x", *d++);
160     if (i == 17)
161       fputs(" },                                                \\\n\
162                                                                         \\\n\
163   { ", stdout);
164     else if (i % 4 == 3)
165       fputs(",                  \\\n    ", stdout);
166     else
167       fputs(", ", stdout);
168   }
169
170   for (j = 0; j < 4; j++) {
171     for (i = 0; i < 256; i++) {
172     printf("0x%08x", *d++);
173     if (i == 255) {
174       if (j == 3)
175         fputs(" }                       \\\n}\n\n#endif\n", stdout);
176       else
177         fputs(" },                      \\\n\
178                                                                         \\\n\
179   { ", stdout);
180     } else if (i % 4 == 3)
181       fputs(",                  \\\n    ", stdout);
182     else
183       fputs(", ", stdout);
184     }
185   }
186
187   if (fclose(stdout)) {
188     fprintf(stderr, "error writing data\n");
189     exit(EXIT_FAILURE);
190   }
191   return (0);
192 }
193
194 /*----- That's all, folks -------------------------------------------------*/