Rearrange the file tree.
[u/mdw/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 /*----- External data -----------------------------------------------------*/
40
41 extern const uint32 des_sp[8][64];
42
43 /*----- Macros ------------------------------------------------------------*/
44
45 /* --- @DES_ROUND@ --- *
46 *
47 * This is the basic DES round function. The inputs are the two subkey
48 * halves, and the left and right block halves. Note that the block halves
49 * are rotated left one place at this point. This wraps what's meant to be
50 * the top bit around to the bottom, so I get a clear run at the S-boxes.
51 */
52
53 #define DES_ROUND(ka, kb, x, y) do { \
54 uint32 _t = (y) ^ (ka); \
55 (x) ^= des_sp[7][(_t >> 0) & 0x3f] ^ \
56 des_sp[5][(_t >> 8) & 0x3f] ^ \
57 des_sp[3][(_t >> 16) & 0x3f] ^ \
58 des_sp[1][(_t >> 24) & 0x3f]; \
59 _t = ROR32((y), 4) ^ (kb); \
60 (x) ^= des_sp[6][(_t >> 0) & 0x3f] ^ \
61 des_sp[4][(_t >> 8) & 0x3f] ^ \
62 des_sp[2][(_t >> 16) & 0x3f] ^ \
63 des_sp[0][(_t >> 24) & 0x3f]; \
64 } while (0)
65
66 /* --- @DES_IP@, @DES_IPINV@ --- *
67 *
68 * The cryptographically useless initial and final permutations. The initial
69 * permutation also rotates the two block halves left by one place. This is
70 * undone by the inverse permutation at the end.
71 */
72
73 #define DES_IP(x, y) do { \
74 uint32 _t; \
75 _t = (y ^ (x >> 4)) & 0x0f0f0f0f; y ^= _t; x ^= _t << 4; \
76 _t = (x ^ (x >> 18)) & 0x00003333; x ^= _t; x ^= _t << 18; \
77 _t = (y ^ (y >> 18)) & 0x00003333; y ^= _t; y ^= _t << 18; \
78 _t = (x ^ (x >> 9)) & 0x00550055; x ^= _t; x ^= _t << 9; \
79 _t = (y ^ (y >> 9)) & 0x00550055; y ^= _t; y ^= _t << 9; \
80 _t = (x ^ (x >> 24)) & 0x000000ff; x ^= _t; x ^= _t << 24; \
81 _t = (y ^ (y >> 24)) & 0x000000ff; y ^= _t; y ^= _t << 24; \
82 _t = (y ^ (x >> 16)) & 0x0000ffff; y ^= _t; x ^= _t << 16; \
83 x = ROL32(x, 1); y = ROL32(y, 1); \
84 } while (0)
85
86 #define DES_IPINV(x, y) do { \
87 uint32 _t; \
88 x = ROR32(x, 1); y = ROR32(y, 1); \
89 _t = (y ^ (x >> 16)) & 0x0000ffff; y ^= _t; x ^= _t << 16; \
90 _t = (x ^ (x >> 24)) & 0x000000ff; x ^= _t; x ^= _t << 24; \
91 _t = (y ^ (y >> 24)) & 0x000000ff; y ^= _t; y ^= _t << 24; \
92 _t = (y ^ (x >> 4)) & 0x0f0f0f0f; y ^= _t; x ^= _t << 4; \
93 _t = (x ^ (x >> 18)) & 0x00003333; x ^= _t; x ^= _t << 18; \
94 _t = (y ^ (y >> 18)) & 0x00003333; y ^= _t; y ^= _t << 18; \
95 _t = (x ^ (x >> 9)) & 0x00550055; x ^= _t; x ^= _t << 9; \
96 _t = (y ^ (y >> 9)) & 0x00550055; y ^= _t; y ^= _t << 9; \
97 } while (0)
98
99 /* --- @DES_EBLK@, @DES_DBLK@ --- *
100 *
101 * Whole block encryption and decryption.
102 */
103
104 #define DES_EBLK(k, a, b, c, d) do { \
105 const uint32 *_k = (k); \
106 uint32 _x = (a), _y = (b); \
107 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
108 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
109 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
110 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
111 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
112 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
113 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
114 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
115 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
116 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
117 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
118 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
119 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
120 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
121 DES_ROUND(_k[0], _k[1], _x, _y); _k += 2; \
122 DES_ROUND(_k[0], _k[1], _y, _x); _k += 2; \
123 (c) = _y; \
124 (d) = _x; \
125 } while (0)
126
127 #define DES_DBLK(k, a, b, c, d) do { \
128 const uint32 *_k = (k) + 32; \
129 uint32 _x = (a), _y = (b); \
130 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
131 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
132 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
133 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
134 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
135 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
136 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
137 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
138 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
139 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
140 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
141 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
142 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
143 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
144 _k -= 2; DES_ROUND(_k[0], _k[1], _x, _y); \
145 _k -= 2; DES_ROUND(_k[0], _k[1], _y, _x); \
146 (c) = _y; \
147 (d) = _x; \
148 } while (0)
149
150 /*----- That's all, folks -------------------------------------------------*/
151
152 #ifdef __cplusplus
153 }
154 #endif
155
156 #endif