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