3 * $Id: des-mktab.c,v 1.3 2000/06/17 10:52:14 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.3 2000/06/17 10:52:14 mdw
34 * Change name for S-box header file.
36 * Revision 1.2 1999/12/22 16:02:30 mdw
37 * Output the table with the correct new header guard names.
39 * Revision 1.1 1999/09/03 08:41:11 mdw
44 /*----- Header files ------------------------------------------------------*/
51 #include <mLib/bits.h>
53 /*----- Static variables --------------------------------------------------*/
57 static char s
[8][4][16] = {
61 { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
62 { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
63 { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
64 { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } },
68 { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
69 { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
70 { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
71 { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } },
75 { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
76 { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
77 { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
78 { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } },
82 { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
83 { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
84 { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
85 { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } },
89 { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
90 { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
91 { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
92 { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } },
96 { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
97 { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
98 { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
99 { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } },
103 { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
104 { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
105 { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
106 { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } },
110 { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
111 { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
112 { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
113 { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } }
116 /* --- P table --- */
118 static char p
[32] = {
119 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
120 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
123 /*----- Main code ---------------------------------------------------------*/
125 /* --- @unique@ --- *
127 * Arguments: @const char *t@ = pointer to table
128 * @int base@ = base of the data
129 * @int sz@ = number of elements
130 * @const char *name@ = name of this table
131 * @...@ = things to fill in
133 * Returns: Zero if it failed, nonzero if it didn't.
135 * Use: Validates a table. All the elements must be in range and
139 static int unique(char *t
, int base
, int sz
, const char *name
, ...)
149 vsprintf(nbuf
, name
, ap
);
153 if (sz
> sizeof(u
)) {
154 fprintf(stderr
, "internal error: table `%s' too large\n", nbuf
);
157 memset(u
, 0, sizeof(u
));
158 for (i
= 0; i
< sz
; i
++) {
161 fprintf(stderr
, "validation error: %i too big (index %i) in %s\n",
165 fprintf(stderr
, "validation error: duplicate %i (index %i) in %s\n",
171 for (i
= 0; i
< sz
; i
++) {
173 fprintf(stderr
, "validation error: missing %i in %s\n",
182 /* --- @validate@ --- *
186 * Returns: Only if everything's OK.
188 * Use: Validates the tables. A bit. Not much at all...
191 static void validate(void)
196 for (i
= 0; i
< 8; i
++) for (j
= 0; j
< 4; j
++)
197 if (!unique(s
[i
][j
], 0, 16, "sbox %i, row %i", i
, j
)) ok
= 0;
198 if (!unique(p
, 1, 32, "p")) ok
= 0;
203 /* --- @permute@ --- *
205 * Arguments: @unsigned long x@ = value to permute
207 * Returns: Permuted version of @x@.
209 * Use: Permutes a number. The result is the input value after
210 * having been spewed through the @P@ permutation, and then
211 * (and this is important) rotated left one place.
214 static unsigned long permute(unsigned long x
)
219 for (i
= 0; i
< 32; i
++) {
220 if (x
& (1 << (32 - p
[i
])))
221 y
|= (1 << (31 - i
));
223 return (ROL32(y
, 1));
226 /* --- @mangle@ --- *
228 * Arguments: @const char s[4][16]@ = an s-box
229 * @unsigned long ss[64]@ = output buffer
230 * @int bitoff@ = bit offset to use
234 * Use: Mangles the s-box. Specifically, the bizarre indexing is
235 * transformed into something sensible, and the result is
236 * permuted according to the @p@ table.
239 static void mangle(const char s
[4][16], unsigned long *ss
, int bitoff
)
242 for (i
= 0; i
< 64; i
++) {
243 unsigned row
= ((i
& 0x20) >> 4) | (i
& 0x01);
244 unsigned col
= (i
& 0x1e) >> 1;
245 ss
[i
] = permute(s
[row
][col
] << bitoff
);
254 unsigned long ss
[64];
262 * DES tables [generated]\n\
265 #ifndef CATACOMB_DES_TAB_H\n\
266 #define CATACOMB_DES_TAB_H\n\
268 #define DES_SP { \\\n\
270 for (i
= 0; i
< 8; i
++) {
271 mangle(s
[i
], ss
, 28 - 4 * i
);
274 /* --- SP[%i] --- */ \\\n\
278 for (j
= 0; j
< 64; j
++) {
279 printf("%s0x%08lx", sep
, ss
[j
]);
285 printf(" }%s \\\n", i
== 7 ?
"" : ",");
293 if (fclose(stdout
)) {
294 fprintf(stderr
, "error writing data\n");
301 /*----- That's all, folks -------------------------------------------------*/