]>
Commit | Line | Data |
---|---|---|
d02b48c6 RE |
1 | /* crypto/des/des_locl.org */ |
2 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) | |
3 | * All rights reserved. | |
4 | * | |
5 | * This package is an SSL implementation written | |
6 | * by Eric Young (eay@cryptsoft.com). | |
7 | * The implementation was written so as to conform with Netscapes SSL. | |
8 | * | |
9 | * This library is free for commercial and non-commercial use as long as | |
10 | * the following conditions are aheared to. The following conditions | |
11 | * apply to all code found in this distribution, be it the RC4, RSA, | |
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | |
13 | * included with this distribution is covered by the same copyright terms | |
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | |
15 | * | |
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | |
17 | * the code are not to be removed. | |
18 | * If this package is used in a product, Eric Young should be given attribution | |
19 | * as the author of the parts of the library used. | |
20 | * This can be in the form of a textual message at program startup or | |
21 | * in documentation (online or textual) provided with the package. | |
22 | * | |
23 | * Redistribution and use in source and binary forms, with or without | |
24 | * modification, are permitted provided that the following conditions | |
25 | * are met: | |
26 | * 1. Redistributions of source code must retain the copyright | |
27 | * notice, this list of conditions and the following disclaimer. | |
28 | * 2. Redistributions in binary form must reproduce the above copyright | |
29 | * notice, this list of conditions and the following disclaimer in the | |
30 | * documentation and/or other materials provided with the distribution. | |
31 | * 3. All advertising materials mentioning features or use of this software | |
32 | * must display the following acknowledgement: | |
33 | * "This product includes cryptographic software written by | |
34 | * Eric Young (eay@cryptsoft.com)" | |
35 | * The word 'cryptographic' can be left out if the rouines from the library | |
36 | * being used are not cryptographic related :-). | |
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | |
38 | * the apps directory (application code) you must include an acknowledgement: | |
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |
40 | * | |
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | |
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
51 | * SUCH DAMAGE. | |
52 | * | |
53 | * The licence and distribution terms for any publically available version or | |
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | |
55 | * copied and put under another distribution licence | |
56 | * [including the GNU Public Licence.] | |
57 | */ | |
58 | ||
59 | /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING | |
60 | * | |
61 | * Always modify des_locl.org since des_locl.h is automatically generated from | |
62 | * it during SSLeay configuration. | |
63 | * | |
64 | * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING | |
65 | */ | |
66 | ||
67 | #ifndef HEADER_DES_LOCL_H | |
68 | #define HEADER_DES_LOCL_H | |
69 | ||
70 | #if defined(WIN32) || defined(WIN16) | |
71 | #ifndef MSDOS | |
72 | #define MSDOS | |
73 | #endif | |
74 | #endif | |
75 | ||
76 | #include <stdio.h> | |
77 | #include <stdlib.h> | |
78 | #ifndef MSDOS | |
79 | #include <unistd.h> | |
80 | #endif | |
81 | #include "des.h" | |
82 | ||
83 | #ifndef DES_DEFAULT_OPTIONS | |
84 | /* the following is tweaked from a config script, that is why it is a | |
85 | * protected undef/define */ | |
86 | #ifndef DES_PTR | |
87 | #undef DES_PTR | |
88 | #endif | |
89 | ||
90 | /* This helps C compiler generate the correct code for multiple functional | |
91 | * units. It reduces register dependancies at the expense of 2 more | |
92 | * registers */ | |
93 | #ifndef DES_RISC1 | |
94 | #undef DES_RISC1 | |
95 | #endif | |
96 | ||
97 | #ifndef DES_RISC2 | |
98 | #undef DES_RISC2 | |
99 | #endif | |
100 | ||
101 | #if defined(DES_RISC1) && defined(DES_RISC2) | |
102 | YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! | |
103 | #endif | |
104 | ||
105 | /* Unroll the inner loop, this sometimes helps, sometimes hinders. | |
106 | * Very mucy CPU dependant */ | |
107 | #ifndef DES_UNROLL | |
108 | #undef DES_UNROLL | |
109 | #endif | |
110 | ||
111 | /* These default values were supplied by | |
112 | * Peter Gutman <pgut001@cs.auckland.ac.nz> | |
113 | * They are only used if nothing else has been defined */ | |
114 | #if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) | |
115 | /* Special defines which change the way the code is built depending on the | |
116 | CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find | |
117 | even newer MIPS CPU's, but at the moment one size fits all for | |
118 | optimization options. Older Sparc's work better with only UNROLL, but | |
119 | there's no way to tell at compile time what it is you're running on */ | |
120 | ||
121 | #if defined( sun ) /* Newer Sparc's */ | |
dfeab068 RE |
122 | # define DES_PTR |
123 | # define DES_RISC1 | |
124 | # define DES_UNROLL | |
d02b48c6 | 125 | #elif defined( __ultrix ) /* Older MIPS */ |
dfeab068 RE |
126 | # define DES_PTR |
127 | # define DES_RISC2 | |
128 | # define DES_UNROLL | |
d02b48c6 | 129 | #elif defined( __osf1__ ) /* Alpha */ |
dfeab068 RE |
130 | # define DES_PTR |
131 | # define DES_RISC2 | |
d02b48c6 RE |
132 | #elif defined ( _AIX ) /* RS6000 */ |
133 | /* Unknown */ | |
134 | #elif defined( __hpux ) /* HP-PA */ | |
135 | /* Unknown */ | |
136 | #elif defined( __aux ) /* 68K */ | |
137 | /* Unknown */ | |
138 | #elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ | |
dfeab068 | 139 | # define DES_UNROLL |
d02b48c6 | 140 | #elif defined( __sgi ) /* Newer MIPS */ |
dfeab068 RE |
141 | # define DES_PTR |
142 | # define DES_RISC2 | |
143 | # define DES_UNROLL | |
d02b48c6 | 144 | #elif defined( i386 ) /* x86 boxes, should be gcc */ |
dfeab068 RE |
145 | # define DES_PTR |
146 | # define DES_RISC1 | |
147 | # define DES_UNROLL | |
d02b48c6 RE |
148 | #endif /* Systems-specific speed defines */ |
149 | #endif | |
150 | ||
151 | #endif /* DES_DEFAULT_OPTIONS */ | |
152 | ||
153 | #ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */ | |
154 | #include <stdlib.h> | |
155 | #include <errno.h> | |
156 | #include <time.h> | |
157 | #include <io.h> | |
158 | #ifndef RAND | |
159 | #define RAND | |
160 | #endif | |
161 | #undef NOPROTO | |
162 | #endif | |
163 | ||
164 | #if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS) | |
165 | #include <string.h> | |
166 | #endif | |
167 | ||
168 | #ifndef RAND | |
169 | #define RAND | |
170 | #endif | |
171 | ||
172 | #ifdef linux | |
173 | #undef RAND | |
174 | #endif | |
175 | ||
176 | #ifdef MSDOS | |
177 | #define getpid() 2 | |
178 | #define RAND | |
179 | #undef NOPROTO | |
180 | #endif | |
181 | ||
182 | #if defined(NOCONST) | |
183 | #define const | |
184 | #endif | |
185 | ||
186 | #ifdef __STDC__ | |
187 | #undef NOPROTO | |
188 | #endif | |
189 | ||
190 | #ifdef RAND | |
191 | #define srandom(s) srand(s) | |
192 | #define random rand | |
193 | #endif | |
194 | ||
195 | #define ITERATIONS 16 | |
196 | #define HALF_ITERATIONS 8 | |
197 | ||
198 | /* used in des_read and des_write */ | |
199 | #define MAXWRITE (1024*16) | |
200 | #define BSIZE (MAXWRITE+4) | |
201 | ||
202 | #define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ | |
203 | l|=((DES_LONG)(*((c)++)))<< 8L, \ | |
204 | l|=((DES_LONG)(*((c)++)))<<16L, \ | |
205 | l|=((DES_LONG)(*((c)++)))<<24L) | |
206 | ||
207 | /* NOTE - c is not incremented as per c2l */ | |
208 | #define c2ln(c,l1,l2,n) { \ | |
209 | c+=n; \ | |
210 | l1=l2=0; \ | |
211 | switch (n) { \ | |
212 | case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ | |
213 | case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ | |
214 | case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ | |
215 | case 5: l2|=((DES_LONG)(*(--(c)))); \ | |
216 | case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ | |
217 | case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ | |
218 | case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ | |
219 | case 1: l1|=((DES_LONG)(*(--(c)))); \ | |
220 | } \ | |
221 | } | |
222 | ||
223 | #define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ | |
224 | *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ | |
225 | *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ | |
226 | *((c)++)=(unsigned char)(((l)>>24L)&0xff)) | |
227 | ||
228 | /* replacements for htonl and ntohl since I have no idea what to do | |
229 | * when faced with machines with 8 byte longs. */ | |
230 | #define HDRSIZE 4 | |
231 | ||
232 | #define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ | |
233 | l|=((DES_LONG)(*((c)++)))<<16L, \ | |
234 | l|=((DES_LONG)(*((c)++)))<< 8L, \ | |
235 | l|=((DES_LONG)(*((c)++)))) | |
236 | ||
237 | #define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ | |
238 | *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ | |
239 | *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ | |
240 | *((c)++)=(unsigned char)(((l) )&0xff)) | |
241 | ||
242 | /* NOTE - c is not incremented as per l2c */ | |
243 | #define l2cn(l1,l2,c,n) { \ | |
244 | c+=n; \ | |
245 | switch (n) { \ | |
246 | case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ | |
247 | case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ | |
248 | case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ | |
249 | case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ | |
250 | case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ | |
251 | case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ | |
252 | case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ | |
253 | case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ | |
254 | } \ | |
255 | } | |
256 | ||
257 | #if defined(WIN32) | |
258 | #define ROTATE(a,n) (_lrotr(a,n)) | |
259 | #else | |
260 | #define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) | |
261 | #endif | |
262 | ||
263 | /* Don't worry about the LOAD_DATA() stuff, that is used by | |
264 | * fcrypt() to add it's little bit to the front */ | |
265 | ||
266 | #ifdef DES_FCRYPT | |
267 | ||
268 | #define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ | |
269 | { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } | |
270 | ||
271 | #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ | |
272 | t=R^(R>>16L); \ | |
273 | u=t&E0; t&=E1; \ | |
274 | tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ | |
275 | tmp=(t<<16); t^=R^s[S+1]; t^=tmp | |
276 | #else | |
277 | #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) | |
278 | #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ | |
279 | u=R^s[S ]; \ | |
280 | t=R^s[S+1] | |
281 | #endif | |
282 | ||
283 | /* The changes to this macro may help or hinder, depending on the | |
284 | * compiler and the achitecture. gcc2 always seems to do well :-). | |
285 | * Inspired by Dana How <how@isl.stanford.edu> | |
286 | * DO NOT use the alternative version on machines with 8 byte longs. | |
287 | * It does not seem to work on the Alpha, even when DES_LONG is 4 | |
288 | * bytes, probably an issue of accessing non-word aligned objects :-( */ | |
289 | #ifdef DES_PTR | |
290 | ||
291 | /* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there | |
292 | * is no reason to not xor all the sub items together. This potentially | |
293 | * saves a register since things can be xored directly into L */ | |
294 | ||
295 | #if defined(DES_RISC1) || defined(DES_RISC2) | |
296 | #ifdef DES_RISC1 | |
297 | #define D_ENCRYPT(LL,R,S) { \ | |
298 | unsigned int u1,u2,u3; \ | |
299 | LOAD_DATA(R,S,u,t,E0,E1,u1); \ | |
300 | u2=(int)u>>8L; \ | |
301 | u1=(int)u&0xfc; \ | |
302 | u2&=0xfc; \ | |
303 | t=ROTATE(t,4); \ | |
304 | u>>=16L; \ | |
305 | LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \ | |
306 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \ | |
307 | u3=(int)(u>>8L); \ | |
308 | u1=(int)u&0xfc; \ | |
309 | u3&=0xfc; \ | |
310 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \ | |
311 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \ | |
312 | u2=(int)t>>8L; \ | |
313 | u1=(int)t&0xfc; \ | |
314 | u2&=0xfc; \ | |
315 | t>>=16L; \ | |
316 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \ | |
317 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \ | |
318 | u3=(int)t>>8L; \ | |
319 | u1=(int)t&0xfc; \ | |
320 | u3&=0xfc; \ | |
321 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \ | |
322 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); } | |
323 | #endif | |
324 | #ifdef DES_RISC2 | |
325 | #define D_ENCRYPT(LL,R,S) { \ | |
326 | unsigned int u1,u2,s1,s2; \ | |
327 | LOAD_DATA(R,S,u,t,E0,E1,u1); \ | |
328 | u2=(int)u>>8L; \ | |
329 | u1=(int)u&0xfc; \ | |
330 | u2&=0xfc; \ | |
331 | t=ROTATE(t,4); \ | |
332 | LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \ | |
333 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \ | |
334 | s1=(int)(u>>16L); \ | |
335 | s2=(int)(u>>24L); \ | |
336 | s1&=0xfc; \ | |
337 | s2&=0xfc; \ | |
338 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \ | |
339 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \ | |
340 | u2=(int)t>>8L; \ | |
341 | u1=(int)t&0xfc; \ | |
342 | u2&=0xfc; \ | |
343 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \ | |
344 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \ | |
345 | s1=(int)(t>>16L); \ | |
346 | s2=(int)(t>>24L); \ | |
347 | s1&=0xfc; \ | |
348 | s2&=0xfc; \ | |
349 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \ | |
350 | LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); } | |
351 | #endif | |
352 | #else | |
353 | #define D_ENCRYPT(LL,R,S) { \ | |
354 | LOAD_DATA_tmp(R,S,u,t,E0,E1); \ | |
355 | t=ROTATE(t,4); \ | |
356 | LL^= \ | |
357 | *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \ | |
358 | *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \ | |
359 | *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \ | |
360 | *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \ | |
361 | *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \ | |
362 | *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \ | |
363 | *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \ | |
364 | *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); } | |
365 | #endif | |
366 | ||
367 | #else /* original version */ | |
368 | ||
369 | #if defined(DES_RISC1) || defined(DES_RISC2) | |
370 | #ifdef DES_RISC1 | |
371 | #define D_ENCRYPT(LL,R,S) {\ | |
372 | unsigned int u1,u2,u3; \ | |
373 | LOAD_DATA(R,S,u,t,E0,E1,u1); \ | |
374 | u>>=2L; \ | |
375 | t=ROTATE(t,6); \ | |
376 | u2=(int)u>>8L; \ | |
377 | u1=(int)u&0x3f; \ | |
378 | u2&=0x3f; \ | |
379 | u>>=16L; \ | |
380 | LL^=des_SPtrans[0][u1]; \ | |
381 | LL^=des_SPtrans[2][u2]; \ | |
382 | u3=(int)u>>8L; \ | |
383 | u1=(int)u&0x3f; \ | |
384 | u3&=0x3f; \ | |
385 | LL^=des_SPtrans[4][u1]; \ | |
386 | LL^=des_SPtrans[6][u3]; \ | |
387 | u2=(int)t>>8L; \ | |
388 | u1=(int)t&0x3f; \ | |
389 | u2&=0x3f; \ | |
390 | t>>=16L; \ | |
391 | LL^=des_SPtrans[1][u1]; \ | |
392 | LL^=des_SPtrans[3][u2]; \ | |
393 | u3=(int)t>>8L; \ | |
394 | u1=(int)t&0x3f; \ | |
395 | u3&=0x3f; \ | |
396 | LL^=des_SPtrans[5][u1]; \ | |
397 | LL^=des_SPtrans[7][u3]; } | |
398 | #endif | |
399 | #ifdef DES_RISC2 | |
400 | #define D_ENCRYPT(LL,R,S) {\ | |
401 | unsigned int u1,u2,s1,s2; \ | |
402 | LOAD_DATA(R,S,u,t,E0,E1,u1); \ | |
403 | u>>=2L; \ | |
404 | t=ROTATE(t,6); \ | |
405 | u2=(int)u>>8L; \ | |
406 | u1=(int)u&0x3f; \ | |
407 | u2&=0x3f; \ | |
408 | LL^=des_SPtrans[0][u1]; \ | |
409 | LL^=des_SPtrans[2][u2]; \ | |
410 | s1=(int)u>>16L; \ | |
411 | s2=(int)u>>24L; \ | |
412 | s1&=0x3f; \ | |
413 | s2&=0x3f; \ | |
414 | LL^=des_SPtrans[4][s1]; \ | |
415 | LL^=des_SPtrans[6][s2]; \ | |
416 | u2=(int)t>>8L; \ | |
417 | u1=(int)t&0x3f; \ | |
418 | u2&=0x3f; \ | |
419 | LL^=des_SPtrans[1][u1]; \ | |
420 | LL^=des_SPtrans[3][u2]; \ | |
421 | s1=(int)t>>16; \ | |
422 | s2=(int)t>>24L; \ | |
423 | s1&=0x3f; \ | |
424 | s2&=0x3f; \ | |
425 | LL^=des_SPtrans[5][s1]; \ | |
426 | LL^=des_SPtrans[7][s2]; } | |
427 | #endif | |
428 | ||
429 | #else | |
430 | ||
431 | #define D_ENCRYPT(LL,R,S) {\ | |
432 | LOAD_DATA_tmp(R,S,u,t,E0,E1); \ | |
433 | t=ROTATE(t,4); \ | |
434 | LL^=\ | |
435 | des_SPtrans[0][(u>> 2L)&0x3f]^ \ | |
436 | des_SPtrans[2][(u>>10L)&0x3f]^ \ | |
437 | des_SPtrans[4][(u>>18L)&0x3f]^ \ | |
438 | des_SPtrans[6][(u>>26L)&0x3f]^ \ | |
439 | des_SPtrans[1][(t>> 2L)&0x3f]^ \ | |
440 | des_SPtrans[3][(t>>10L)&0x3f]^ \ | |
441 | des_SPtrans[5][(t>>18L)&0x3f]^ \ | |
442 | des_SPtrans[7][(t>>26L)&0x3f]; } | |
443 | #endif | |
444 | #endif | |
445 | ||
446 | /* IP and FP | |
447 | * The problem is more of a geometric problem that random bit fiddling. | |
448 | 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 | |
449 | 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 | |
450 | 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 | |
451 | 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 | |
452 | ||
453 | 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 | |
454 | 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 | |
455 | 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 | |
456 | 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 | |
457 | ||
458 | The output has been subject to swaps of the form | |
459 | 0 1 -> 3 1 but the odd and even bits have been put into | |
460 | 2 3 2 0 | |
461 | different words. The main trick is to remember that | |
462 | t=((l>>size)^r)&(mask); | |
463 | r^=t; | |
464 | l^=(t<<size); | |
465 | can be used to swap and move bits between words. | |
466 | ||
467 | So l = 0 1 2 3 r = 16 17 18 19 | |
468 | 4 5 6 7 20 21 22 23 | |
469 | 8 9 10 11 24 25 26 27 | |
470 | 12 13 14 15 28 29 30 31 | |
471 | becomes (for size == 2 and mask == 0x3333) | |
472 | t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19 | |
473 | 6^20 7^21 -- -- 4 5 20 21 6 7 22 23 | |
474 | 10^24 11^25 -- -- 8 9 24 25 10 11 24 25 | |
475 | 14^28 15^29 -- -- 12 13 28 29 14 15 28 29 | |
476 | ||
477 | Thanks for hints from Richard Outerbridge - he told me IP&FP | |
478 | could be done in 15 xor, 10 shifts and 5 ands. | |
479 | When I finally started to think of the problem in 2D | |
480 | I first got ~42 operations without xors. When I remembered | |
481 | how to use xors :-) I got it to its final state. | |
482 | */ | |
483 | #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ | |
484 | (b)^=(t),\ | |
485 | (a)^=((t)<<(n))) | |
486 | ||
487 | #define IP(l,r) \ | |
488 | { \ | |
489 | register DES_LONG tt; \ | |
490 | PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ | |
491 | PERM_OP(l,r,tt,16,0x0000ffffL); \ | |
492 | PERM_OP(r,l,tt, 2,0x33333333L); \ | |
493 | PERM_OP(l,r,tt, 8,0x00ff00ffL); \ | |
494 | PERM_OP(r,l,tt, 1,0x55555555L); \ | |
495 | } | |
496 | ||
497 | #define FP(l,r) \ | |
498 | { \ | |
499 | register DES_LONG tt; \ | |
500 | PERM_OP(l,r,tt, 1,0x55555555L); \ | |
501 | PERM_OP(r,l,tt, 8,0x00ff00ffL); \ | |
502 | PERM_OP(l,r,tt, 2,0x33333333L); \ | |
503 | PERM_OP(r,l,tt,16,0x0000ffffL); \ | |
504 | PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ | |
505 | } | |
506 | ||
507 | extern const DES_LONG des_SPtrans[8][64]; | |
508 | ||
509 | #ifndef NOPROTO | |
510 | void fcrypt_body(DES_LONG *out,des_key_schedule ks, | |
511 | DES_LONG Eswap0, DES_LONG Eswap1); | |
512 | #else | |
513 | void fcrypt_body(); | |
514 | #endif | |
515 | ||
516 | #endif |