PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
des.c
1/*
2 * NB - This file is a modified version of one by Eric Young.
3 * It was modifed by jimmikaelkael <jimmikaelkael@wanadoo.fr>
4 */
5
6/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au)
7 * All rights reserved.
8 *
9 * This file is part of an SSL implementation written
10 * by Eric Young (eay@mincom.oz.au).
11 * The implementation was written so as to conform with Netscapes SSL
12 * specification. This library and applications are
13 * FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
14 * as long as the following conditions are aheared to.
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed. If this code is used in a product,
18 * Eric Young should be given attribution as the author of the parts used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * This product includes software developed by Eric Young (eay@mincom.oz.au)
33 *
34 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 *
46 * The licence and distribution terms for any publically available version or
47 * derivative of this code cannot be changed. i.e. this code cannot simply be
48 * copied and put under another distribution licence
49 * [including the GNU Public Licence.]
50 */
51
52#define c2l(c, l) (l = ((unsigned int)(*((c)++))), \
53 l |= ((unsigned int)(*((c)++))) << 8, \
54 l |= ((unsigned int)(*((c)++))) << 16, \
55 l |= ((unsigned int)(*((c)++))) << 24)
56
57#define l2c(l, c) (*((c)++) = (unsigned char)(((l)) & 0xff), \
58 *((c)++) = (unsigned char)(((l) >> 8) & 0xff), \
59 *((c)++) = (unsigned char)(((l) >> 16) & 0xff), \
60 *((c)++) = (unsigned char)(((l) >> 24) & 0xff))
61
62#define ITERATIONS 16
63#define HPERM_OP(a, t, n, m) ((t) = ((((a) << (16 - (n))) ^ (a)) & (m)), \
64 (a) = (a) ^ (t) ^ (t >> (16 - (n))))
65
66static const unsigned int des_SPtrans[8][64] = {
67 /* nibble 0 */
68 {
69 0x00820200, 0x00020000, 0x80800000, 0x80820200,
70 0x00800000, 0x80020200, 0x80020000, 0x80800000,
71 0x80020200, 0x00820200, 0x00820000, 0x80000200,
72 0x80800200, 0x00800000, 0x00000000, 0x80020000,
73 0x00020000, 0x80000000, 0x00800200, 0x00020200,
74 0x80820200, 0x00820000, 0x80000200, 0x00800200,
75 0x80000000, 0x00000200, 0x00020200, 0x80820000,
76 0x00000200, 0x80800200, 0x80820000, 0x00000000,
77 0x00000000, 0x80820200, 0x00800200, 0x80020000,
78 0x00820200, 0x00020000, 0x80000200, 0x00800200,
79 0x80820000, 0x00000200, 0x00020200, 0x80800000,
80 0x80020200, 0x80000000, 0x80800000, 0x00820000,
81 0x80820200, 0x00020200, 0x00820000, 0x80800200,
82 0x00800000, 0x80000200, 0x80020000, 0x00000000,
83 0x00020000, 0x00800000, 0x80800200, 0x00820200,
84 0x80000000, 0x80820000, 0x00000200, 0x80020200},
85 /* nibble 1 */
86 {
87 0x10042004, 0x00000000, 0x00042000, 0x10040000,
88 0x10000004, 0x00002004, 0x10002000, 0x00042000,
89 0x00002000, 0x10040004, 0x00000004, 0x10002000,
90 0x00040004, 0x10042000, 0x10040000, 0x00000004,
91 0x00040000, 0x10002004, 0x10040004, 0x00002000,
92 0x00042004, 0x10000000, 0x00000000, 0x00040004,
93 0x10002004, 0x00042004, 0x10042000, 0x10000004,
94 0x10000000, 0x00040000, 0x00002004, 0x10042004,
95 0x00040004, 0x10042000, 0x10002000, 0x00042004,
96 0x10042004, 0x00040004, 0x10000004, 0x00000000,
97 0x10000000, 0x00002004, 0x00040000, 0x10040004,
98 0x00002000, 0x10000000, 0x00042004, 0x10002004,
99 0x10042000, 0x00002000, 0x00000000, 0x10000004,
100 0x00000004, 0x10042004, 0x00042000, 0x10040000,
101 0x10040004, 0x00040000, 0x00002004, 0x10002000,
102 0x10002004, 0x00000004, 0x10040000, 0x00042000},
103 /* nibble 2 */
104 {
105 0x41000000, 0x01010040, 0x00000040, 0x41000040,
106 0x40010000, 0x01000000, 0x41000040, 0x00010040,
107 0x01000040, 0x00010000, 0x01010000, 0x40000000,
108 0x41010040, 0x40000040, 0x40000000, 0x41010000,
109 0x00000000, 0x40010000, 0x01010040, 0x00000040,
110 0x40000040, 0x41010040, 0x00010000, 0x41000000,
111 0x41010000, 0x01000040, 0x40010040, 0x01010000,
112 0x00010040, 0x00000000, 0x01000000, 0x40010040,
113 0x01010040, 0x00000040, 0x40000000, 0x00010000,
114 0x40000040, 0x40010000, 0x01010000, 0x41000040,
115 0x00000000, 0x01010040, 0x00010040, 0x41010000,
116 0x40010000, 0x01000000, 0x41010040, 0x40000000,
117 0x40010040, 0x41000000, 0x01000000, 0x41010040,
118 0x00010000, 0x01000040, 0x41000040, 0x00010040,
119 0x01000040, 0x00000000, 0x41010000, 0x40000040,
120 0x41000000, 0x40010040, 0x00000040, 0x01010000},
121 /* nibble 3 */
122 {
123 0x00100402, 0x04000400, 0x00000002, 0x04100402,
124 0x00000000, 0x04100000, 0x04000402, 0x00100002,
125 0x04100400, 0x04000002, 0x04000000, 0x00000402,
126 0x04000002, 0x00100402, 0x00100000, 0x04000000,
127 0x04100002, 0x00100400, 0x00000400, 0x00000002,
128 0x00100400, 0x04000402, 0x04100000, 0x00000400,
129 0x00000402, 0x00000000, 0x00100002, 0x04100400,
130 0x04000400, 0x04100002, 0x04100402, 0x00100000,
131 0x04100002, 0x00000402, 0x00100000, 0x04000002,
132 0x00100400, 0x04000400, 0x00000002, 0x04100000,
133 0x04000402, 0x00000000, 0x00000400, 0x00100002,
134 0x00000000, 0x04100002, 0x04100400, 0x00000400,
135 0x04000000, 0x04100402, 0x00100402, 0x00100000,
136 0x04100402, 0x00000002, 0x04000400, 0x00100402,
137 0x00100002, 0x00100400, 0x04100000, 0x04000402,
138 0x00000402, 0x04000000, 0x04000002, 0x04100400},
139 /* nibble 4 */
140 {
141 0x02000000, 0x00004000, 0x00000100, 0x02004108,
142 0x02004008, 0x02000100, 0x00004108, 0x02004000,
143 0x00004000, 0x00000008, 0x02000008, 0x00004100,
144 0x02000108, 0x02004008, 0x02004100, 0x00000000,
145 0x00004100, 0x02000000, 0x00004008, 0x00000108,
146 0x02000100, 0x00004108, 0x00000000, 0x02000008,
147 0x00000008, 0x02000108, 0x02004108, 0x00004008,
148 0x02004000, 0x00000100, 0x00000108, 0x02004100,
149 0x02004100, 0x02000108, 0x00004008, 0x02004000,
150 0x00004000, 0x00000008, 0x02000008, 0x02000100,
151 0x02000000, 0x00004100, 0x02004108, 0x00000000,
152 0x00004108, 0x02000000, 0x00000100, 0x00004008,
153 0x02000108, 0x00000100, 0x00000000, 0x02004108,
154 0x02004008, 0x02004100, 0x00000108, 0x00004000,
155 0x00004100, 0x02004008, 0x02000100, 0x00000108,
156 0x00000008, 0x00004108, 0x02004000, 0x02000008},
157 /* nibble 5 */
158 {
159 0x20000010, 0x00080010, 0x00000000, 0x20080800,
160 0x00080010, 0x00000800, 0x20000810, 0x00080000,
161 0x00000810, 0x20080810, 0x00080800, 0x20000000,
162 0x20000800, 0x20000010, 0x20080000, 0x00080810,
163 0x00080000, 0x20000810, 0x20080010, 0x00000000,
164 0x00000800, 0x00000010, 0x20080800, 0x20080010,
165 0x20080810, 0x20080000, 0x20000000, 0x00000810,
166 0x00000010, 0x00080800, 0x00080810, 0x20000800,
167 0x00000810, 0x20000000, 0x20000800, 0x00080810,
168 0x20080800, 0x00080010, 0x00000000, 0x20000800,
169 0x20000000, 0x00000800, 0x20080010, 0x00080000,
170 0x00080010, 0x20080810, 0x00080800, 0x00000010,
171 0x20080810, 0x00080800, 0x00080000, 0x20000810,
172 0x20000010, 0x20080000, 0x00080810, 0x00000000,
173 0x00000800, 0x20000010, 0x20000810, 0x20080800,
174 0x20080000, 0x00000810, 0x00000010, 0x20080010},
175 /* nibble 6 */
176 {
177 0x00001000, 0x00000080, 0x00400080, 0x00400001,
178 0x00401081, 0x00001001, 0x00001080, 0x00000000,
179 0x00400000, 0x00400081, 0x00000081, 0x00401000,
180 0x00000001, 0x00401080, 0x00401000, 0x00000081,
181 0x00400081, 0x00001000, 0x00001001, 0x00401081,
182 0x00000000, 0x00400080, 0x00400001, 0x00001080,
183 0x00401001, 0x00001081, 0x00401080, 0x00000001,
184 0x00001081, 0x00401001, 0x00000080, 0x00400000,
185 0x00001081, 0x00401000, 0x00401001, 0x00000081,
186 0x00001000, 0x00000080, 0x00400000, 0x00401001,
187 0x00400081, 0x00001081, 0x00001080, 0x00000000,
188 0x00000080, 0x00400001, 0x00000001, 0x00400080,
189 0x00000000, 0x00400081, 0x00400080, 0x00001080,
190 0x00000081, 0x00001000, 0x00401081, 0x00400000,
191 0x00401080, 0x00000001, 0x00001001, 0x00401081,
192 0x00400001, 0x00401080, 0x00401000, 0x00001001},
193 /* nibble 7 */
194 {
195 0x08200020, 0x08208000, 0x00008020, 0x00000000,
196 0x08008000, 0x00200020, 0x08200000, 0x08208020,
197 0x00000020, 0x08000000, 0x00208000, 0x00008020,
198 0x00208020, 0x08008020, 0x08000020, 0x08200000,
199 0x00008000, 0x00208020, 0x00200020, 0x08008000,
200 0x08208020, 0x08000020, 0x00000000, 0x00208000,
201 0x08000000, 0x00200000, 0x08008020, 0x08200020,
202 0x00200000, 0x00008000, 0x08208000, 0x00000020,
203 0x00200000, 0x00008000, 0x08000020, 0x08208020,
204 0x00008020, 0x08000000, 0x00000000, 0x00208000,
205 0x08200020, 0x08008020, 0x08008000, 0x00200020,
206 0x08208000, 0x00000020, 0x00200020, 0x08008000,
207 0x08208020, 0x00200000, 0x08200000, 0x08000020,
208 0x00208000, 0x00008020, 0x08008020, 0x08200000,
209 0x00000020, 0x08208000, 0x00208020, 0x00000000,
210 0x08000000, 0x08200020, 0x00008000, 0x00208020}};
211static const unsigned int des_skb[8][64] = {
212 /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
213 {
214 0x00000000, 0x00000010, 0x20000000, 0x20000010,
215 0x00010000, 0x00010010, 0x20010000, 0x20010010,
216 0x00000800, 0x00000810, 0x20000800, 0x20000810,
217 0x00010800, 0x00010810, 0x20010800, 0x20010810,
218 0x00000020, 0x00000030, 0x20000020, 0x20000030,
219 0x00010020, 0x00010030, 0x20010020, 0x20010030,
220 0x00000820, 0x00000830, 0x20000820, 0x20000830,
221 0x00010820, 0x00010830, 0x20010820, 0x20010830,
222 0x00080000, 0x00080010, 0x20080000, 0x20080010,
223 0x00090000, 0x00090010, 0x20090000, 0x20090010,
224 0x00080800, 0x00080810, 0x20080800, 0x20080810,
225 0x00090800, 0x00090810, 0x20090800, 0x20090810,
226 0x00080020, 0x00080030, 0x20080020, 0x20080030,
227 0x00090020, 0x00090030, 0x20090020, 0x20090030,
228 0x00080820, 0x00080830, 0x20080820, 0x20080830,
229 0x00090820, 0x00090830, 0x20090820, 0x20090830},
230 /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
231 {
232 0x00000000, 0x02000000, 0x00002000, 0x02002000,
233 0x00200000, 0x02200000, 0x00202000, 0x02202000,
234 0x00000004, 0x02000004, 0x00002004, 0x02002004,
235 0x00200004, 0x02200004, 0x00202004, 0x02202004,
236 0x00000400, 0x02000400, 0x00002400, 0x02002400,
237 0x00200400, 0x02200400, 0x00202400, 0x02202400,
238 0x00000404, 0x02000404, 0x00002404, 0x02002404,
239 0x00200404, 0x02200404, 0x00202404, 0x02202404,
240 0x10000000, 0x12000000, 0x10002000, 0x12002000,
241 0x10200000, 0x12200000, 0x10202000, 0x12202000,
242 0x10000004, 0x12000004, 0x10002004, 0x12002004,
243 0x10200004, 0x12200004, 0x10202004, 0x12202004,
244 0x10000400, 0x12000400, 0x10002400, 0x12002400,
245 0x10200400, 0x12200400, 0x10202400, 0x12202400,
246 0x10000404, 0x12000404, 0x10002404, 0x12002404,
247 0x10200404, 0x12200404, 0x10202404, 0x12202404},
248 /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
249 {
250 0x00000000, 0x00000001, 0x00040000, 0x00040001,
251 0x01000000, 0x01000001, 0x01040000, 0x01040001,
252 0x00000002, 0x00000003, 0x00040002, 0x00040003,
253 0x01000002, 0x01000003, 0x01040002, 0x01040003,
254 0x00000200, 0x00000201, 0x00040200, 0x00040201,
255 0x01000200, 0x01000201, 0x01040200, 0x01040201,
256 0x00000202, 0x00000203, 0x00040202, 0x00040203,
257 0x01000202, 0x01000203, 0x01040202, 0x01040203,
258 0x08000000, 0x08000001, 0x08040000, 0x08040001,
259 0x09000000, 0x09000001, 0x09040000, 0x09040001,
260 0x08000002, 0x08000003, 0x08040002, 0x08040003,
261 0x09000002, 0x09000003, 0x09040002, 0x09040003,
262 0x08000200, 0x08000201, 0x08040200, 0x08040201,
263 0x09000200, 0x09000201, 0x09040200, 0x09040201,
264 0x08000202, 0x08000203, 0x08040202, 0x08040203,
265 0x09000202, 0x09000203, 0x09040202, 0x09040203},
266 /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
267 {
268 0x00000000, 0x00100000, 0x00000100, 0x00100100,
269 0x00000008, 0x00100008, 0x00000108, 0x00100108,
270 0x00001000, 0x00101000, 0x00001100, 0x00101100,
271 0x00001008, 0x00101008, 0x00001108, 0x00101108,
272 0x04000000, 0x04100000, 0x04000100, 0x04100100,
273 0x04000008, 0x04100008, 0x04000108, 0x04100108,
274 0x04001000, 0x04101000, 0x04001100, 0x04101100,
275 0x04001008, 0x04101008, 0x04001108, 0x04101108,
276 0x00020000, 0x00120000, 0x00020100, 0x00120100,
277 0x00020008, 0x00120008, 0x00020108, 0x00120108,
278 0x00021000, 0x00121000, 0x00021100, 0x00121100,
279 0x00021008, 0x00121008, 0x00021108, 0x00121108,
280 0x04020000, 0x04120000, 0x04020100, 0x04120100,
281 0x04020008, 0x04120008, 0x04020108, 0x04120108,
282 0x04021000, 0x04121000, 0x04021100, 0x04121100,
283 0x04021008, 0x04121008, 0x04021108, 0x04121108},
284 /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
285 {
286 0x00000000, 0x10000000, 0x00010000, 0x10010000,
287 0x00000004, 0x10000004, 0x00010004, 0x10010004,
288 0x20000000, 0x30000000, 0x20010000, 0x30010000,
289 0x20000004, 0x30000004, 0x20010004, 0x30010004,
290 0x00100000, 0x10100000, 0x00110000, 0x10110000,
291 0x00100004, 0x10100004, 0x00110004, 0x10110004,
292 0x20100000, 0x30100000, 0x20110000, 0x30110000,
293 0x20100004, 0x30100004, 0x20110004, 0x30110004,
294 0x00001000, 0x10001000, 0x00011000, 0x10011000,
295 0x00001004, 0x10001004, 0x00011004, 0x10011004,
296 0x20001000, 0x30001000, 0x20011000, 0x30011000,
297 0x20001004, 0x30001004, 0x20011004, 0x30011004,
298 0x00101000, 0x10101000, 0x00111000, 0x10111000,
299 0x00101004, 0x10101004, 0x00111004, 0x10111004,
300 0x20101000, 0x30101000, 0x20111000, 0x30111000,
301 0x20101004, 0x30101004, 0x20111004, 0x30111004},
302 /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
303 {
304 0x00000000, 0x08000000, 0x00000008, 0x08000008,
305 0x00000400, 0x08000400, 0x00000408, 0x08000408,
306 0x00020000, 0x08020000, 0x00020008, 0x08020008,
307 0x00020400, 0x08020400, 0x00020408, 0x08020408,
308 0x00000001, 0x08000001, 0x00000009, 0x08000009,
309 0x00000401, 0x08000401, 0x00000409, 0x08000409,
310 0x00020001, 0x08020001, 0x00020009, 0x08020009,
311 0x00020401, 0x08020401, 0x00020409, 0x08020409,
312 0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
313 0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
314 0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
315 0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
316 0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
317 0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
318 0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
319 0x02020401, 0x0A020401, 0x02020409, 0x0A020409},
320 /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
321 {
322 0x00000000, 0x00000100, 0x00080000, 0x00080100,
323 0x01000000, 0x01000100, 0x01080000, 0x01080100,
324 0x00000010, 0x00000110, 0x00080010, 0x00080110,
325 0x01000010, 0x01000110, 0x01080010, 0x01080110,
326 0x00200000, 0x00200100, 0x00280000, 0x00280100,
327 0x01200000, 0x01200100, 0x01280000, 0x01280100,
328 0x00200010, 0x00200110, 0x00280010, 0x00280110,
329 0x01200010, 0x01200110, 0x01280010, 0x01280110,
330 0x00000200, 0x00000300, 0x00080200, 0x00080300,
331 0x01000200, 0x01000300, 0x01080200, 0x01080300,
332 0x00000210, 0x00000310, 0x00080210, 0x00080310,
333 0x01000210, 0x01000310, 0x01080210, 0x01080310,
334 0x00200200, 0x00200300, 0x00280200, 0x00280300,
335 0x01200200, 0x01200300, 0x01280200, 0x01280300,
336 0x00200210, 0x00200310, 0x00280210, 0x00280310,
337 0x01200210, 0x01200310, 0x01280210, 0x01280310},
338 /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
339 {
340 0x00000000, 0x04000000, 0x00040000, 0x04040000,
341 0x00000002, 0x04000002, 0x00040002, 0x04040002,
342 0x00002000, 0x04002000, 0x00042000, 0x04042000,
343 0x00002002, 0x04002002, 0x00042002, 0x04042002,
344 0x00000020, 0x04000020, 0x00040020, 0x04040020,
345 0x00000022, 0x04000022, 0x00040022, 0x04040022,
346 0x00002020, 0x04002020, 0x00042020, 0x04042020,
347 0x00002022, 0x04002022, 0x00042022, 0x04042022,
348 0x00000800, 0x04000800, 0x00040800, 0x04040800,
349 0x00000802, 0x04000802, 0x00040802, 0x04040802,
350 0x00002800, 0x04002800, 0x00042800, 0x04042800,
351 0x00002802, 0x04002802, 0x00042802, 0x04042802,
352 0x00000820, 0x04000820, 0x00040820, 0x04040820,
353 0x00000822, 0x04000822, 0x00040822, 0x04040822,
354 0x00002820, 0x04002820, 0x00042820, 0x04042820,
355 0x00002822, 0x04002822, 0x00042822, 0x04042822}};
356
357
358/* The changes to this macro may help or hinder, depending on the
359 * compiler and the achitecture. gcc2 always seems to do well :-).
360 * Inspired by Dana How <how@isl.stanford.edu>
361 * DO NOT use the alternative version on machines with 8 byte longs. */
362
363/* original version */
364#define D_ENCRYPT(L, R, S) \
365 u = (R ^ s[S]); \
366 t = R ^ s[S + 1]; \
367 t = ((t >> 4) + (t << 28)); \
368 L ^= des_SPtrans[1][(t)&0x3f] | \
369 des_SPtrans[3][(t >> 8) & 0x3f] | \
370 des_SPtrans[5][(t >> 16) & 0x3f] | \
371 des_SPtrans[7][(t >> 24) & 0x3f] | \
372 des_SPtrans[0][(u)&0x3f] | \
373 des_SPtrans[2][(u >> 8) & 0x3f] | \
374 des_SPtrans[4][(u >> 16) & 0x3f] | \
375 des_SPtrans[6][(u >> 24) & 0x3f];
376
377/* IP and FP
378 * The problem is more of a geometric problem that random bit fiddling.
379 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
380 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
38116 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
38224 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
383
38432 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
38540 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
38648 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
38756 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
388
389The output has been subject to swaps of the form
3900 1 -> 3 1 but the odd and even bits have been put into
3912 3 2 0
392different words. The main trick is to remember that
393t=((l>>size)^r)&(mask);
394r^=t;
395l^=(t<<size);
396can be used to swap and move bits between words.
397
398So l = 0 1 2 3 r = 16 17 18 19
399 4 5 6 7 20 21 22 23
400 8 9 10 11 24 25 26 27
401 12 13 14 15 28 29 30 31
402becomes (for size == 2 and mask == 0x3333)
403 t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
404 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
405 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
406 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
407
408Thanks for hints from Richard Outerbridge - he told me IP&FP
409could be done in 15 xor, 10 shifts and 5 ands.
410When I finally started to think of the problem in 2D
411I first got ~42 operations without xors. When I remembered
412how to use xors :-) I got it to its final state.
413*/
414#define PERM_OP(a, b, t, n, m) ((t) = ((((a) >> (n)) ^ (b)) & (m)), \
415 (b) ^= (t), \
416 (a) ^= ((t) << (n)))
417
418
419static unsigned char *key7TOkey8(const unsigned char *key7, unsigned char *key8)
420{
421 int i;
422
423 key8[0] = ((key7[0] >> 1) & 0xff);
424 key8[1] = ((((key7[0] & 0x01) << 6) | (((key7[1] & 0xff) >> 2) & 0xff)) & 0xff);
425 key8[2] = ((((key7[1] & 0x03) << 5) | (((key7[2] & 0xff) >> 3) & 0xff)) & 0xff);
426 key8[3] = ((((key7[2] & 0x07) << 4) | (((key7[3] & 0xff) >> 4) & 0xff)) & 0xff);
427 key8[4] = ((((key7[3] & 0x0F) << 3) | (((key7[4] & 0xff) >> 5) & 0xff)) & 0xff);
428 key8[5] = ((((key7[4] & 0x1F) << 2) | (((key7[5] & 0xff) >> 6) & 0xff)) & 0xff);
429 key8[6] = ((((key7[5] & 0x3F) << 1) | (((key7[6] & 0xff) >> 7) & 0xff)) & 0xff);
430 key8[7] = (key7[6] & 0x7F);
431
432 for (i = 0; i < 8; i++) {
433 key8[i] = (key8[i] << 1);
434 }
435
436 return (unsigned char *)key8;
437}
438
439static unsigned char DES_Keys[128] __attribute__((aligned(16)));
440
441/*
442 * des_create_keys: take 64bit user key (key) as input and outputs
443 * 16 48bit keys (keys)
444 */
445static unsigned char *DES_createkeys(const unsigned char *key)
446{
447 unsigned int c, d, t;
448 unsigned char *in;
449 unsigned int *k;
450 unsigned char k8[8];
451 int i;
452 static unsigned char shifts[16] = {0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
453
454 key7TOkey8(key, k8);
455
456 k = (unsigned int *)DES_Keys;
457 in = (unsigned char *)k8;
458
459 c2l(in, c);
460 c2l(in, d);
461
462 /* I now do it in 47 simple operations :-)
463 * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
464 * for the inspiration. :-) */
465 PERM_OP(d, c, t, 4, 0x0f0f0f0f);
466 HPERM_OP(c, t, -2, 0xcccc0000);
467 HPERM_OP(d, t, -2, 0xcccc0000);
468 PERM_OP(d, c, t, 1, 0x55555555);
469 PERM_OP(c, d, t, 8, 0x00ff00ff);
470 PERM_OP(d, c, t, 1, 0x55555555);
471 d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
472 ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4));
473 c &= 0x0fffffff;
474
475 for (i = 0; i < ITERATIONS; i++) {
476 unsigned int s;
477
478 if (shifts[i]) {
479 c = ((c >> 2) | (c << 26));
480 d = ((d >> 2) | (d << 26));
481 } else {
482 c = ((c >> 1) | (c << 27));
483 d = ((d >> 1) | (d << 27));
484 }
485 c &= 0x0fffffff;
486 d &= 0x0fffffff;
487 /* could be a few less shifts but I am to lazy at this
488 * point in time to investigate */
489 s = des_skb[0][(c)&0x3f] |
490 des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] |
491 des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] |
492 des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38)];
493
494 t = des_skb[4][(d)&0x3f] |
495 des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] |
496 des_skb[6][(d >> 15) & 0x3f] |
497 des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];
498
499 /* table contained 0213 4657 */
500 *(k++) = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
501 s = ((s >> 16) | (t & 0xffff0000));
502
503 s = (s << 4) | (s >> 28);
504 *(k++) = s & 0xffffffff;
505 }
506
507 return (unsigned char *)DES_Keys;
508}
509
510unsigned char *DES(const unsigned char *key, const unsigned char *message, unsigned char *cipher)
511{
512 unsigned int l, r, t;
513 int i;
514 unsigned int *s;
515 unsigned char *keys;
516
517 keys = DES_createkeys(key);
518
519 c2l(message, l); /* get endian free int from input block */
520 c2l(message, r); /* get endian free int from input block */
521
522 /* do IP */
523 PERM_OP(r, l, t, 4, 0x0f0f0f0f);
524 PERM_OP(l, r, t, 16, 0x0000ffff);
525 PERM_OP(r, l, t, 2, 0x33333333);
526 PERM_OP(l, r, t, 8, 0x00ff00ff);
527 PERM_OP(r, l, t, 1, 0x55555555);
528 /* r and l are reversed - remember that :-) - fix
529 * it in the next step */
530
531 /* Things have been modified so that the initial rotate is
532 * done outside the loop. This required the
533 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
534 * One perl script later and things have a 5% speed up on a sparc2.
535 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
536 * for pointing this out. */
537 t = (r << 1) | (r >> 31);
538 r = (l << 1) | (l >> 31);
539 l = t;
540
541 s = (unsigned int *)keys;
542 /* I don't know if it is worth the effort of loop unrolling the
543 * inner loop */
544 for (i = 0; i < 32; i += 4) {
545 unsigned int u;
546
547 D_ENCRYPT(l, r, i + 0); /* 1 */
548 D_ENCRYPT(r, l, i + 2); /* 2 */
549 }
550 l = (l >> 1) | (l << 31);
551 r = (r >> 1) | (r << 31);
552
553 /* swap l and r
554 * we will not do the swap so just remember they are
555 * reversed for the rest of the subroutine
556 * luckily FP fixes this problem :-) */
557
558 PERM_OP(r, l, t, 1, 0x55555555);
559 PERM_OP(l, r, t, 8, 0x00ff00ff);
560 PERM_OP(r, l, t, 2, 0x33333333);
561 PERM_OP(l, r, t, 16, 0x0000ffff);
562 PERM_OP(r, l, t, 4, 0x0f0f0f0f);
563
564 l2c(l, cipher); /* get endian free int from input block */
565 l2c(r, cipher); /* get endian free int from input block */
566
567 return (unsigned char *)cipher;
568}