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