Generate precomputed tables as sources in `precomps/'.
[u/mdw/catacomb] / symm / des-mktab.c
CommitLineData
d03ab969 1/* -*-c-*-
2 *
d03ab969 3 * Build combined S-P tables for DES
4 *
5 * (c) 1999 Straylight/Edgeware
6 */
7
45c0fd36 8/*----- Licensing notice --------------------------------------------------*
d03ab969 9 *
10 * This file is part of Catacomb.
11 *
12 * Catacomb is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
45c0fd36 16 *
d03ab969 17 * Catacomb is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
45c0fd36 21 *
d03ab969 22 * You should have received a copy of the GNU Library General Public
23 * License along with Catacomb; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * MA 02111-1307, USA.
26 */
27
d03ab969 28/*----- Header files ------------------------------------------------------*/
29
30#include <stdarg.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34
35#include <mLib/bits.h>
36
37/*----- Static variables --------------------------------------------------*/
38
39/* --- S boxes --- */
40
5f271fe6 41static const char s[8][4][16] = {
d03ab969 42
43 /* --- S1 --- */
44
45 { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
46 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
47 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
48 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } },
49
50 /* --- S2 --- */
51
52 { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
53 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
54 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
55 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } },
56
57 /* --- S3 --- */
58
59 { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
60 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
61 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
62 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } },
63
64 /* --- S4 --- */
65
66 { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
67 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
68 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
69 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } },
70
71 /* --- S5 --- */
72
73 { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
74 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
75 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
76 { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } },
77
78 /* --- S6 --- */
79
80 { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
81 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
82 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
83 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } },
84
85 /* --- S7 --- */
86
87 { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
88 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
89 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
90 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } },
91
92 /* --- S8 --- */
93
94 { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
95 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
96 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
97 { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } }
98};
99
100/* --- P table --- */
101
102static char p[32] = {
103 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
104 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
105};
106
107/*----- Main code ---------------------------------------------------------*/
108
109/* --- @unique@ --- *
110 *
111 * Arguments: @const char *t@ = pointer to table
112 * @int base@ = base of the data
113 * @int sz@ = number of elements
114 * @const char *name@ = name of this table
115 * @...@ = things to fill in
116 *
117 * Returns: Zero if it failed, nonzero if it didn't.
118 *
119 * Use: Validates a table. All the elements must be in range and
120 * unique.
121 */
122
5f271fe6 123static int unique(const char *t, int base, int sz, const char *name, ...)
d03ab969 124{
125 char u[32];
126 char nbuf[128];
127 int i;
128 int ok = 1;
129
130 {
131 va_list ap;
132 va_start(ap, name);
133 vsprintf(nbuf, name, ap);
134 va_end(ap);
135 }
136
137 if (sz > sizeof(u)) {
138 fprintf(stderr, "internal error: table `%s' too large\n", nbuf);
139 exit(EXIT_FAILURE);
140 }
141 memset(u, 0, sizeof(u));
142 for (i = 0; i < sz; i++) {
143 int x = t[i] - base;
144 if (x >= sz) {
145 fprintf(stderr, "validation error: %i too big (index %i) in %s\n",
146 x + base, i, nbuf);
147 ok = 0;
148 } else if (u[x]) {
149 fprintf(stderr, "validation error: duplicate %i (index %i) in %s\n",
150 x + base, i, nbuf);
151 ok = 0;
152 }
153 u[x] = 1;
154 }
155 for (i = 0; i < sz; i++) {
156 if (!u[i]) {
157 fprintf(stderr, "validation error: missing %i in %s\n",
158 i + base, nbuf);
159 ok = 0;
160 }
161 }
162
163 return (ok);
164}
165
166/* --- @validate@ --- *
167 *
168 * Arguments: ---
169 *
170 * Returns: Only if everything's OK.
171 *
172 * Use: Validates the tables. A bit. Not much at all...
173 */
174
175static void validate(void)
176{
177 int i, j;
178 int ok = 1;
179
180 for (i = 0; i < 8; i++) for (j = 0; j < 4; j++)
181 if (!unique(s[i][j], 0, 16, "sbox %i, row %i", i, j)) ok = 0;
182 if (!unique(p, 1, 32, "p")) ok = 0;
183 if (!ok)
184 exit(EXIT_FAILURE);
185}
186
187/* --- @permute@ --- *
188 *
189 * Arguments: @unsigned long x@ = value to permute
190 *
191 * Returns: Permuted version of @x@.
192 *
193 * Use: Permutes a number. The result is the input value after
194 * having been spewed through the @P@ permutation, and then
195 * (and this is important) rotated left one place.
196 */
197
198static unsigned long permute(unsigned long x)
199{
200 unsigned long y = 0;
201 unsigned i;
202
203 for (i = 0; i < 32; i++) {
204 if (x & (1 << (32 - p[i])))
205 y |= (1 << (31 - i));
206 }
207 return (ROL32(y, 1));
208}
209
210/* --- @mangle@ --- *
211 *
212 * Arguments: @const char s[4][16]@ = an s-box
213 * @unsigned long ss[64]@ = output buffer
214 * @int bitoff@ = bit offset to use
215 *
216 * Returns: ---
217 *
218 * Use: Mangles the s-box. Specifically, the bizarre indexing is
219 * transformed into something sensible, and the result is
220 * permuted according to the @p@ table.
221 */
222
223static void mangle(const char s[4][16], unsigned long *ss, int bitoff)
224{
225 unsigned i;
226 for (i = 0; i < 64; i++) {
227 unsigned row = ((i & 0x20) >> 4) | (i & 0x01);
228 unsigned col = (i & 0x1e) >> 1;
229 ss[i] = permute(s[row][col] << bitoff);
230 }
231}
232
233/* --- @main@ --- */
234
235int main(void)
236{
237 int i, j;
238 unsigned long ss[64];
239 const char *sep;
240
241 validate();
242
243 fputs("\
3636b349 244/* -*-c-*-\n\
245 *\n\
680bedf8 246 * DES tables [generated]\n\
3636b349 247 */\n\
248\n\
e5b61a8d 249#include \"des-base.h\"\n\
d03ab969 250\n\
e5b61a8d 251const uint32 des_sp[8][64] = {\n\
d03ab969 252", stdout);
253 for (i = 0; i < 8; i++) {
254 mangle(s[i], ss, 28 - 4 * i);
e5b61a8d 255 printf("\n /* --- SP[%i] --- */\n\n", i);
d03ab969 256 sep = " { ";
257 for (j = 0; j < 64; j++) {
258 printf("%s0x%08lx", sep, ss[j]);
259 if (j % 4 == 3)
e5b61a8d 260 sep = ",\n ";
d03ab969 261 else
262 sep = ", ";
263 }
e5b61a8d 264 printf(" }%s\n", i == 7 ? "" : ",");
d03ab969 265 }
e5b61a8d 266 fputs("};\n", stdout);
680bedf8 267
268 if (fclose(stdout)) {
269 fprintf(stderr, "error writing data\n");
270 exit(EXIT_FAILURE);
271 }
272
d03ab969 273 return (0);
274}
275
276/*----- That's all, folks -------------------------------------------------*/