3 * Build combined S-P tables for DES
5 * (c) 1999 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Catacomb.
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.
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.
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,
28 /*----- Header files ------------------------------------------------------*/
35 #include <mLib/bits.h>
37 /*----- Static variables --------------------------------------------------*/
41 static const char s[8][4][16] = {
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } }
100 /* --- P table --- */
102 static 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
107 /*----- Main code ---------------------------------------------------------*/
109 /* --- @unique@ --- *
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
117 * Returns: Zero if it failed, nonzero if it didn't.
119 * Use: Validates a table. All the elements must be in range and
123 static int unique(const char *t, int base, int sz, const char *name, ...)
133 vsprintf(nbuf, name, ap);
137 if (sz > sizeof(u)) {
138 fprintf(stderr, "internal error: table `%s' too large\n", nbuf);
141 memset(u, 0, sizeof(u));
142 for (i = 0; i < sz; i++) {
145 fprintf(stderr, "validation error: %i too big (index %i) in %s\n",
149 fprintf(stderr, "validation error: duplicate %i (index %i) in %s\n",
155 for (i = 0; i < sz; i++) {
157 fprintf(stderr, "validation error: missing %i in %s\n",
166 /* --- @validate@ --- *
170 * Returns: Only if everything's OK.
172 * Use: Validates the tables. A bit. Not much at all...
175 static void validate(void)
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;
187 /* --- @permute@ --- *
189 * Arguments: @unsigned long x@ = value to permute
191 * Returns: Permuted version of @x@.
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.
198 static unsigned long permute(unsigned long x)
203 for (i = 0; i < 32; i++) {
204 if (x & (1 << (32 - p[i])))
205 y |= (1 << (31 - i));
207 return (ROL32(y, 1));
210 /* --- @mangle@ --- *
212 * Arguments: @const char s[4][16]@ = an s-box
213 * @unsigned long ss[64]@ = output buffer
214 * @int bitoff@ = bit offset to use
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.
223 static void mangle(const char s[4][16], unsigned long *ss, int bitoff)
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);
238 unsigned long ss[64];
246 * DES tables [generated]\n\
249 #include \"des-base.h\"\n\
251 const uint32 des_sp[8][64] = {\n\
253 for (i = 0; i < 8; i++) {
254 mangle(s[i], ss, 28 - 4 * i);
255 printf("\n /* --- SP[%i] --- */\n\n", i);
257 for (j = 0; j < 64; j++) {
258 printf("%s0x%08lx", sep, ss[j]);
264 printf(" }%s\n", i == 7 ? "" : ",");
266 fputs("};\n", stdout);
268 if (fclose(stdout)) {
269 fprintf(stderr, "error writing data\n");
276 /*----- That's all, folks -------------------------------------------------*/