progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / symm / des-base.h
1 /* -*-c-*-
2 *
3 * Common features for DES implementation
4 *
5 * (c) 1999 Straylight/Edgeware
6 */
7
8 /*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Catacomb.
11 *
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.
16 *
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.
21 *
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,
25 * MA 02111-1307, USA.
26 */
27
28 #ifndef CATACOMB_DES_BASE_H
29 #define CATACOMB_DES_BASE_H
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #include <mLib/bits.h>
38
39 #ifndef CATACOMB_PERMUTE_H
40 # include "permute.h"
41 #endif
42
43 /*----- External data -----------------------------------------------------*/
44
45 extern const uint32 des_sp[8][64];
46
47 /*----- Macros ------------------------------------------------------------*/
48
49 /* --- @DES_ROUND@ --- *
50 *
51 * This is the basic DES round function. The inputs are the two subkey
52 * halves, and the left and right block halves. Note that the block halves
53 * are rotated left one place at this point. This wraps what's meant to be
54 * the top bit around to the bottom, so I get a clear run at the S-boxes.
55 */
56
57 #define DES_ROUND(ka, kb, x, y) do { \
58 uint32 _t = (y) ^ (ka); \
59 (x) ^= des_sp[7][(_t >> 0) & 0x3f] ^ \
60 des_sp[5][(_t >> 8) & 0x3f] ^ \
61 des_sp[3][(_t >> 16) & 0x3f] ^ \
62 des_sp[1][(_t >> 24) & 0x3f]; \
63 _t = ROR32((y), 4) ^ (kb); \
64 (x) ^= des_sp[6][(_t >> 0) & 0x3f] ^ \
65 des_sp[4][(_t >> 8) & 0x3f] ^ \
66 des_sp[2][(_t >> 16) & 0x3f] ^ \
67 des_sp[0][(_t >> 24) & 0x3f]; \
68 } while (0)
69
70 /* --- @DES_IP@, @DES_IPINV@ --- *
71 *
72 * The cryptographically useless initial and final permutations. The initial
73 * permutation also rotates the two block halves left by one place. This is
74 * undone by the inverse permutation at the end.
75 *
76 * The initial permutation is traditionally given by the table
77 *
78 * 58 50 42 34 26 18 10 2
79 * 60 52 44 36 28 20 12 4
80 * 62 54 46 38 30 22 14 6
81 * 64 56 48 40 32 24 16 8
82 * 57 49 41 33 25 17 9 1
83 * 59 51 43 35 27 19 11 3
84 * 61 53 45 37 29 21 13 5
85 * 63 55 47 39 31 23 15 7
86 *
87 * The bit numbering is terrible. If the two halves are X and Y, then the
88 * numbering starts with the most significant bit of X, which is bit 1,
89 * working down towards the least significant bit, and then continuing with
90 * the bits of Y, again in order of decreasing significance. The table
91 * entries are in this same order, indicating that `bit 1' of the output is
92 * `bit 58' of the input and so on.
93 *
94 * I opt instead to number the bits starting from the least significant bit
95 * of Y, which is bit 0, up to the most significant bit of X, which is
96 * bit 63. This means that we need to reverse the table (because we're going
97 * to read it in the other direction) and subtract each entry from 64 (to
98 * correct the bit numbering). The resulting table is
99 *
100 * 57 49 41 33 25 17 9 1
101 * 59 51 43 35 27 19 11 3
102 * 61 53 45 37 29 21 13 5
103 * 63 55 47 39 31 23 15 7
104 * 56 48 40 32 24 16 8 0
105 * 58 50 42 34 26 18 10 2
106 * 60 52 44 36 28 20 12 4
107 * 62 54 46 38 30 22 14 6
108 *
109 * which, interestingly, is /also/ what you get if you just subtract one from
110 * each of the original table's entries.
111 *
112 * If we look at this table in binary, the patterns are much clearer.
113 *
114 * 111001 110001 101001 100001 011001 010001 001001 000001
115 * 111011 110011 101011 100011 011011 010011 001011 000011
116 * 111101 110101 101101 100101 011101 010101 001101 000101
117 * 111111 110111 101111 100111 011111 010111 001111 000111
118 * 111000 110000 101000 100000 011000 010000 001000 000000
119 * 111010 110010 101010 100010 011010 010010 001010 000010
120 * 111100 110100 101100 100100 011100 010100 001100 000100
121 * 111110 110110 101110 100110 011110 010110 001110 000110
122 *
123 * We can implement this efficiently using our permutation machinery.
124 * Writing ~k for index bit @k@ inverted, this permutation reflects the index
125 * transformation given by ~0, 2, 1, ~5, ~4, ~3. There's a traditional
126 * swizzle sequence for this, which we used to use, namely:
127 *
128 * // 5, 4, 3, 2, 1, 0
129 * TWIZZLE_XCPL (x, y, 2); // ~2, 4, 3, ~5, 1, 0
130 * SWIZZLE_XCPL2(x, y, 1, 4); // ~2, ~1, 3, ~5, ~4, 0
131 * SWIZZLE_XCPL2(x, y, 0, 3); // ~2, ~1, ~0, ~5, ~4, ~3
132 * SWIZZLE_XCPL2(x, y, 3, 4); // ~2, 0, 1, ~5, ~4, ~3
133 * TWIZZLE_XCPL (x, y, 4); // ~0, 2, 1, ~5, ~4, ~3
134 *
135 * Essentially this is an antitranspose -- a reflection about the
136 * antidiagonal -- followed by a couple of fixup stages. But the non-twizzle
137 * steps require more operations, and it's easy to find a sequence which
138 * always acts on the (current) index bit 5, moving it to where it's wanted,
139 * and inverting it if necessary, so we only need twizzles.
140 */
141
142 #define DES_IP(x, y) do { \
143 TWIZZLE_XCPL(x, y, 2); /* ~2, 4, 3, ~5, 1, 0 */ \
144 TWIZZLE_XCPL(x, y, 4); /* ~4, 2, 3, ~5, 1, 0 */ \
145 TWIZZLE_EXCH(x, y, 1); /* 1, 2, 3, ~5, ~4, 0 */ \
146 TWIZZLE_EXCH(x, y, 3); /* 3, 2, 1, ~5, ~4, 0 */ \
147 TWIZZLE_XCPL(x, y, 0); /* ~0, 2, 1, ~5, ~4, ~3 */ \
148 x = ROL32(x, 1); y = ROL32(y, 1); \
149 } while (0)
150
151 #define DES_IPINV(x, y) do { \
152 x = ROR32(x, 1); y = ROR32(y, 1); /* ~0, 2, 1, ~5, ~4, ~3 */ \
153 TWIZZLE_XCPL(x, y, 0); /* 3, 2, 1, ~5, ~4, 0 */ \
154 TWIZZLE_EXCH(x, y, 3); /* 1, 2, 3, ~5, ~4, 0 */ \
155 TWIZZLE_EXCH(x, y, 1); /* ~4, 2, 3, ~5, 1, 0 */ \
156 TWIZZLE_XCPL(x, y, 4); /* 3, 2, 1, ~5, ~4, 0 */ \
157 TWIZZLE_XCPL(x, y, 2); /* 5, 4, 3, 2, 1, 0 */ \
158 } while (0)
159
160 /* --- @DES_EBLK@, @DES_DBLK@ --- *
161 *
162 * Whole block encryption and decryption.
163 */
164
165 #define DES_EBLK(k, a, b, c, d) do { \
166 const uint32 *_k = (k); \
167 uint32 _x = (a), _y = (b); \
168 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
169 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
170 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
171 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
172 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
173 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
174 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
175 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
176 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
177 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
178 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
179 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
180 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
181 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
182 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
183 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
184 (c) = _y; \
185 (d) = _x; \
186 } while (0)
187
188 #define DES_DBLK(k, a, b, c, d) do { \
189 const uint32 *_k = (k) + 32; \
190 uint32 _x = (a), _y = (b); \
191 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
192 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
193 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
194 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
195 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
196 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
197 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
198 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
199 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
200 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
201 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
202 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
203 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
204 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
205 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
206 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
207 (c) = _y; \
208 (d) = _x; \
209 } while (0)
210
211 /*----- That's all, folks -------------------------------------------------*/
212
213 #ifdef __cplusplus
214 }
215 #endif
216
217 #endif