3 * $Id: des-mktab.c,v 1.5 2004/04/08 01:36:15 mdw Exp $
5 * Build combined S-P tables for DES
7 * (c) 1999 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
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.
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.
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,
30 /*----- Header files ------------------------------------------------------*/
37 #include <mLib/bits.h>
39 /*----- Static variables --------------------------------------------------*/
43 static const char s[8][4][16] = {
47 { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
48 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
49 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
50 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } },
54 { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
55 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
56 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
57 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } },
61 { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
62 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
63 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
64 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } },
68 { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
69 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
70 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
71 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } },
75 { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
76 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
77 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
78 { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } },
82 { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
83 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
84 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
85 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } },
89 { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
90 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
91 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
92 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } },
96 { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
97 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
98 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
99 { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } }
102 /* --- P table --- */
104 static char p[32] = {
105 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
106 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
109 /*----- Main code ---------------------------------------------------------*/
111 /* --- @unique@ --- *
113 * Arguments: @const char *t@ = pointer to table
114 * @int base@ = base of the data
115 * @int sz@ = number of elements
116 * @const char *name@ = name of this table
117 * @...@ = things to fill in
119 * Returns: Zero if it failed, nonzero if it didn't.
121 * Use: Validates a table. All the elements must be in range and
125 static int unique(const char *t, int base, int sz, const char *name, ...)
135 vsprintf(nbuf, name, ap);
139 if (sz > sizeof(u)) {
140 fprintf(stderr, "internal error: table `%s' too large\n", nbuf);
143 memset(u, 0, sizeof(u));
144 for (i = 0; i < sz; i++) {
147 fprintf(stderr, "validation error: %i too big (index %i) in %s\n",
151 fprintf(stderr, "validation error: duplicate %i (index %i) in %s\n",
157 for (i = 0; i < sz; i++) {
159 fprintf(stderr, "validation error: missing %i in %s\n",
168 /* --- @validate@ --- *
172 * Returns: Only if everything's OK.
174 * Use: Validates the tables. A bit. Not much at all...
177 static void validate(void)
182 for (i = 0; i < 8; i++) for (j = 0; j < 4; j++)
183 if (!unique(s[i][j], 0, 16, "sbox %i, row %i", i, j)) ok = 0;
184 if (!unique(p, 1, 32, "p")) ok = 0;
189 /* --- @permute@ --- *
191 * Arguments: @unsigned long x@ = value to permute
193 * Returns: Permuted version of @x@.
195 * Use: Permutes a number. The result is the input value after
196 * having been spewed through the @P@ permutation, and then
197 * (and this is important) rotated left one place.
200 static unsigned long permute(unsigned long x)
205 for (i = 0; i < 32; i++) {
206 if (x & (1 << (32 - p[i])))
207 y |= (1 << (31 - i));
209 return (ROL32(y, 1));
212 /* --- @mangle@ --- *
214 * Arguments: @const char s[4][16]@ = an s-box
215 * @unsigned long ss[64]@ = output buffer
216 * @int bitoff@ = bit offset to use
220 * Use: Mangles the s-box. Specifically, the bizarre indexing is
221 * transformed into something sensible, and the result is
222 * permuted according to the @p@ table.
225 static void mangle(const char s[4][16], unsigned long *ss, int bitoff)
228 for (i = 0; i < 64; i++) {
229 unsigned row = ((i & 0x20) >> 4) | (i & 0x01);
230 unsigned col = (i & 0x1e) >> 1;
231 ss[i] = permute(s[row][col] << bitoff);
240 unsigned long ss[64];
248 * DES tables [generated]\n\
251 #ifndef CATACOMB_DES_TAB_H\n\
252 #define CATACOMB_DES_TAB_H\n\
254 #define DES_SP { \\\n\
256 for (i = 0; i < 8; i++) {
257 mangle(s[i], ss, 28 - 4 * i);
260 /* --- SP[%i] --- */ \\\n\
264 for (j = 0; j < 64; j++) {
265 printf("%s0x%08lx", sep, ss[j]);
271 printf(" }%s \\\n", i == 7 ? "" : ",");
279 if (fclose(stdout)) {
280 fprintf(stderr, "error writing data\n");
287 /*----- That's all, folks -------------------------------------------------*/