3 * $Id: des-mktab.c,v 1.1 1999/09/03 08:41:11 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 /*----- Revision history --------------------------------------------------*
32 * $Log: des-mktab.c,v $
33 * Revision 1.1 1999/09/03 08:41:11 mdw
38 /*----- Header files ------------------------------------------------------*/
45 #include <mLib/bits.h>
47 /*----- Static variables --------------------------------------------------*/
51 static char s
[8][4][16] = {
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } }
110 /* --- P table --- */
112 static 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
117 /*----- Main code ---------------------------------------------------------*/
119 /* --- @unique@ --- *
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
127 * Returns: Zero if it failed, nonzero if it didn't.
129 * Use: Validates a table. All the elements must be in range and
133 static int unique(char *t
, int base
, int sz
, const char *name
, ...)
143 vsprintf(nbuf
, name
, ap
);
147 if (sz
> sizeof(u
)) {
148 fprintf(stderr
, "internal error: table `%s' too large\n", nbuf
);
151 memset(u
, 0, sizeof(u
));
152 for (i
= 0; i
< sz
; i
++) {
155 fprintf(stderr
, "validation error: %i too big (index %i) in %s\n",
159 fprintf(stderr
, "validation error: duplicate %i (index %i) in %s\n",
165 for (i
= 0; i
< sz
; i
++) {
167 fprintf(stderr
, "validation error: missing %i in %s\n",
176 /* --- @validate@ --- *
180 * Returns: Only if everything's OK.
182 * Use: Validates the tables. A bit. Not much at all...
185 static void validate(void)
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;
197 /* --- @permute@ --- *
199 * Arguments: @unsigned long x@ = value to permute
201 * Returns: Permuted version of @x@.
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.
208 static unsigned long permute(unsigned long x
)
213 for (i
= 0; i
< 32; i
++) {
214 if (x
& (1 << (32 - p
[i
])))
215 y
|= (1 << (31 - i
));
217 return (ROL32(y
, 1));
220 /* --- @mangle@ --- *
222 * Arguments: @const char s[4][16]@ = an s-box
223 * @unsigned long ss[64]@ = output buffer
224 * @int bitoff@ = bit offset to use
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.
233 static void mangle(const char s
[4][16], unsigned long *ss
, int bitoff
)
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
);
248 unsigned long ss
[64];
254 /* DES SP table (generated) */\n\
256 #define DES_SP { \\\n\
258 for (i
= 0; i
< 8; i
++) {
259 mangle(s
[i
], ss
, 28 - 4 * i
);
262 /* --- SP[%i] --- */ \\\n\
266 for (j
= 0; j
< 64; j
++) {
267 printf("%s0x%08lx", sep
, ss
[j
]);
273 printf(" }%s \\\n", i
== 7 ?
"" : ",");
275 fputs("}\n", stdout
);
279 /*----- That's all, folks -------------------------------------------------*/