Table for driving key data extraction.
[u/mdw/catacomb] / des-mktab.c
1 /* -*-c-*-
2 *
3 * $Id: des-mktab.c,v 1.2 1999/12/22 16:02:30 mdw Exp $
4 *
5 * Build combined S-P tables for DES
6 *
7 * (c) 1999 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: des-mktab.c,v $
33 * Revision 1.2 1999/12/22 16:02:30 mdw
34 * Output the table with the correct new header guard names.
35 *
36 * Revision 1.1 1999/09/03 08:41:11 mdw
37 * Initial import.
38 *
39 */
40
41 /*----- Header files ------------------------------------------------------*/
42
43 #include <stdarg.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47
48 #include <mLib/bits.h>
49
50 /*----- Static variables --------------------------------------------------*/
51
52 /* --- S boxes --- */
53
54 static char s[8][4][16] = {
55
56 /* --- S1 --- */
57
58 { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
59 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
60 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
61 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } },
62
63 /* --- S2 --- */
64
65 { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
66 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
67 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
68 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } },
69
70 /* --- S3 --- */
71
72 { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
73 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
74 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
75 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } },
76
77 /* --- S4 --- */
78
79 { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
80 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
81 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
82 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } },
83
84 /* --- S5 --- */
85
86 { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
87 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
88 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
89 { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } },
90
91 /* --- S6 --- */
92
93 { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
94 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
95 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
96 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } },
97
98 /* --- S7 --- */
99
100 { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
101 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
102 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
103 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } },
104
105 /* --- S8 --- */
106
107 { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
108 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
109 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
110 { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } }
111 };
112
113 /* --- P table --- */
114
115 static char p[32] = {
116 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
117 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
118 };
119
120 /*----- Main code ---------------------------------------------------------*/
121
122 /* --- @unique@ --- *
123 *
124 * Arguments: @const char *t@ = pointer to table
125 * @int base@ = base of the data
126 * @int sz@ = number of elements
127 * @const char *name@ = name of this table
128 * @...@ = things to fill in
129 *
130 * Returns: Zero if it failed, nonzero if it didn't.
131 *
132 * Use: Validates a table. All the elements must be in range and
133 * unique.
134 */
135
136 static int unique(char *t, int base, int sz, const char *name, ...)
137 {
138 char u[32];
139 char nbuf[128];
140 int i;
141 int ok = 1;
142
143 {
144 va_list ap;
145 va_start(ap, name);
146 vsprintf(nbuf, name, ap);
147 va_end(ap);
148 }
149
150 if (sz > sizeof(u)) {
151 fprintf(stderr, "internal error: table `%s' too large\n", nbuf);
152 exit(EXIT_FAILURE);
153 }
154 memset(u, 0, sizeof(u));
155 for (i = 0; i < sz; i++) {
156 int x = t[i] - base;
157 if (x >= sz) {
158 fprintf(stderr, "validation error: %i too big (index %i) in %s\n",
159 x + base, i, nbuf);
160 ok = 0;
161 } else if (u[x]) {
162 fprintf(stderr, "validation error: duplicate %i (index %i) in %s\n",
163 x + base, i, nbuf);
164 ok = 0;
165 }
166 u[x] = 1;
167 }
168 for (i = 0; i < sz; i++) {
169 if (!u[i]) {
170 fprintf(stderr, "validation error: missing %i in %s\n",
171 i + base, nbuf);
172 ok = 0;
173 }
174 }
175
176 return (ok);
177 }
178
179 /* --- @validate@ --- *
180 *
181 * Arguments: ---
182 *
183 * Returns: Only if everything's OK.
184 *
185 * Use: Validates the tables. A bit. Not much at all...
186 */
187
188 static void validate(void)
189 {
190 int i, j;
191 int ok = 1;
192
193 for (i = 0; i < 8; i++) for (j = 0; j < 4; j++)
194 if (!unique(s[i][j], 0, 16, "sbox %i, row %i", i, j)) ok = 0;
195 if (!unique(p, 1, 32, "p")) ok = 0;
196 if (!ok)
197 exit(EXIT_FAILURE);
198 }
199
200 /* --- @permute@ --- *
201 *
202 * Arguments: @unsigned long x@ = value to permute
203 *
204 * Returns: Permuted version of @x@.
205 *
206 * Use: Permutes a number. The result is the input value after
207 * having been spewed through the @P@ permutation, and then
208 * (and this is important) rotated left one place.
209 */
210
211 static unsigned long permute(unsigned long x)
212 {
213 unsigned long y = 0;
214 unsigned i;
215
216 for (i = 0; i < 32; i++) {
217 if (x & (1 << (32 - p[i])))
218 y |= (1 << (31 - i));
219 }
220 return (ROL32(y, 1));
221 }
222
223 /* --- @mangle@ --- *
224 *
225 * Arguments: @const char s[4][16]@ = an s-box
226 * @unsigned long ss[64]@ = output buffer
227 * @int bitoff@ = bit offset to use
228 *
229 * Returns: ---
230 *
231 * Use: Mangles the s-box. Specifically, the bizarre indexing is
232 * transformed into something sensible, and the result is
233 * permuted according to the @p@ table.
234 */
235
236 static void mangle(const char s[4][16], unsigned long *ss, int bitoff)
237 {
238 unsigned i;
239 for (i = 0; i < 64; i++) {
240 unsigned row = ((i & 0x20) >> 4) | (i & 0x01);
241 unsigned col = (i & 0x1e) >> 1;
242 ss[i] = permute(s[row][col] << bitoff);
243 }
244 }
245
246 /* --- @main@ --- */
247
248 int main(void)
249 {
250 int i, j;
251 unsigned long ss[64];
252 const char *sep;
253
254 validate();
255
256 fputs("\
257 /* -*-c-*-\n\
258 *\n\
259 * DES SP table [generated]\n\
260 */\n\
261 \n\
262 #ifndef CATACOMB_DES_SP_H\n\
263 #define CATACOMB_DES_SP_H\n\
264 \n\
265 #define DES_SP { \\\n\
266 ", stdout);
267 for (i = 0; i < 8; i++) {
268 mangle(s[i], ss, 28 - 4 * i);
269 printf("\
270 \\\n\
271 /* --- SP[%i] --- */ \\\n\
272 \\\n\
273 ", i);
274 sep = " { ";
275 for (j = 0; j < 64; j++) {
276 printf("%s0x%08lx", sep, ss[j]);
277 if (j % 4 == 3)
278 sep = ", \\\n ";
279 else
280 sep = ", ";
281 }
282 printf(" }%s \\\n", i == 7 ? "" : ",");
283 }
284 fputs("\
285 }\n\
286 \n\
287 #endif\n\
288 ", stdout);
289 return (0);
290 }
291
292 /*----- That's all, folks -------------------------------------------------*/