chiark / gitweb /
Add some more vectors, and a whinge about how Skipjack test vectors are.
[catacomb] / blowfish-mktab.c
1 /* -*-c-*-
2  *
3  * $Id: blowfish-mktab.c,v 1.2 2000/07/16 12:33:11 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.2  2000/07/16 12:33:11  mdw
34  * Shut stupid compiler up.
35  *
36  * Revision 1.1  2000/06/17 10:47:28  mdw
37  * Emits Blowfish initial key data, derived from the digits of pi.
38  *
39  */
40
41 /*----- Header files ------------------------------------------------------*/
42
43 #include <stdio.h>
44 #include <stdlib.h>
45
46 #include <mLib/bits.h>
47
48 /*----- Main code ---------------------------------------------------------*/
49
50 /* --- @spigot@ --- *
51  *
52  * Arguments:   @uint32 *buf@ = pointer to the output buffer
53  *              @size_t n@ = number of output digits wanted
54  *
55  * Returns:     ---
56  *
57  * Use:         Writes digits of %$\pi$% to the given array.  The algorithm
58  *              is based on the Spigot algorithm by Stanley Rabinowitz and
59  *              Stan Wagon, published in Amer.Math.Monthly, March 1995, with
60  *              bug fixes by C. Haenel.  I then bodged it to output hex
61  *              digits rather than decimal ones, and to leave off the initial
62  *              `3'.
63  *
64  *              I've not analysed the algorithm very much.
65  */
66
67 #define SPIGOT_WORDS (18 + 4 * 256ul)
68 #define SPIGOT_BITS 8
69 #define SPIGOT_RADIX (1ul << SPIGOT_BITS)
70 #define SPIGOT_BUFLEN (SPIGOT_WORDS * 32)
71
72 static void spigot(uint32 *buf, size_t n)
73 {
74   uint32 acc = 0;
75   int b = -1;
76   unsigned a[SPIGOT_BUFLEN] = { 0 };
77   uint32 p = 0;
78   unsigned f = 0;
79   unsigned max = 32 * n;
80   size_t step = n / 60;
81
82   fputs("[                                                             ]\r[",
83         stderr);
84
85 #define EMIT(z) do {                                                    \
86   if (b == -1)                                                          \
87     b = 0;                                                              \
88   else {                                                                \
89     acc = (acc << SPIGOT_BITS) | (z);                                   \
90     b += SPIGOT_BITS;                                                   \
91     if (b == 32) {                                                      \
92       *buf++ = acc;                                                     \
93       acc = 0;                                                          \
94       b = 0;                                                            \
95       n--;                                                              \
96       if (!n)                                                           \
97         goto done;                                                      \
98       if (n % step == 0)                                                \
99         fputc('.', stderr);                                             \
100     }                                                                   \
101   }                                                                     \
102 } while (0)
103
104   while (n) {
105     uint32 q = 0;
106     uint32 i;
107     uint32 x = 0;
108     uint32 k = max * 2 - 1;
109
110     for (i = max; i; i--) {
111       x = (b == -1 ? SPIGOT_RADIX * 2 : a[i - 1] << SPIGOT_BITS) + q * i;
112       q = x / k;
113       a[i - 1] = x - q * k;
114       k -= 2;
115     }
116
117     k = x & (SPIGOT_RADIX - 1);
118     if (k == SPIGOT_RADIX - 1)
119       f++;
120     else {
121       EMIT(p + (x >> SPIGOT_BITS));
122       if (f) {
123         unsigned d = (x >= SPIGOT_RADIX ? 0 : SPIGOT_RADIX - 1);
124         while (f) {
125           EMIT(d);
126           f--;
127         }
128       }
129       p = k;
130     }
131   }
132
133 done:
134   fputc('\n', stderr);
135
136 #undef EMIT
137 }
138
139 /* --- @main@ --- */
140
141 int main(void)
142 {
143   uint32 dbuf[SPIGOT_WORDS];
144   int i, j;
145   uint32 *d = dbuf;
146
147   spigot(d, SPIGOT_WORDS);
148
149   fputs("\
150 /* -*-c-*-\n\
151  *\n\
152  * Blowfish initial key table [generated]\n\
153  */\n\
154 \n\
155 #ifndef CATACOMB_BLOWFISH_TAB_H\n\
156 #define CATACOMB_BLOWFISH_TAB_H\n\
157 \n\
158 #define BLOWFISH_IKEY {                                                 \\\n\
159   { ", stdout);
160
161   for (i = 0; i < 18; i++) {
162     printf("0x%08x", *d++);
163     if (i == 17)
164       fputs(" },                                                \\\n\
165                                                                         \\\n\
166   { ", stdout);
167     else if (i % 4 == 3)
168       fputs(",                  \\\n    ", stdout);
169     else
170       fputs(", ", stdout);
171   }
172
173   for (j = 0; j < 4; j++) {
174     for (i = 0; i < 256; i++) {
175     printf("0x%08x", *d++);
176     if (i == 255) {
177       if (j == 3)
178         fputs(" }                       \\\n}\n\n#endif\n", stdout);
179       else
180         fputs(" },                      \\\n\
181                                                                         \\\n\
182   { ", stdout);
183     } else if (i % 4 == 3)
184       fputs(",                  \\\n    ", stdout);
185     else
186       fputs(", ", stdout);
187     }
188   }
189
190   if (fclose(stdout)) {
191     fprintf(stderr, "error writing data\n");
192     exit(EXIT_FAILURE);
193   }
194   return (0);
195 }
196
197 /*----- That's all, folks -------------------------------------------------*/