Initial revision
[silc.git] / lib / silccrypt / serpent.c
1 /* Modified for SILC. -Pekka */x\r
2 \r
3 /* This is an independent implementation of the encryption algorithm:   */\r
4 /*                                                                      */\r
5 /*         Serpent by Ross Anderson, Eli Biham and Lars Knudsen         */\r
6 /*                                                                      */\r
7 /* which is a candidate algorithm in the Advanced Encryption Standard   */\r
8 /* programme of the US National Institute of Standards and Technology.  */\r
9 /*                                                                      */\r
10 /* Copyright in this implementation is held by Dr B R Gladman but I     */\r
11 /* hereby give permission for its free direct or derivative use subject */\r
12 /* to acknowledgment of its origin and compliance with any conditions   */\r
13 /* that the originators of the algorithm place on its exploitation.     */\r
14 /*                                                                      */\r
15 /* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999     */\r
16 \r
17 /* Timing data for Serpent (serpent.c)\r
18 \r
19 Core timing without I/O endian conversion:\r
20 \r
21 128 bit key:\r
22 Key Setup:    2402 cycles\r
23 Encrypt:       952 cycles =    26.9 mbits/sec\r
24 Decrypt:       914 cycles =    28.0 mbits/sec\r
25 Mean:          933 cycles =    27.4 mbits/sec\r
26 \r
27 192 bit key:\r
28 Key Setup:    2449 cycles\r
29 Encrypt:       952 cycles =    26.9 mbits/sec\r
30 Decrypt:       914 cycles =    28.0 mbits/sec\r
31 Mean:          933 cycles =    27.4 mbits/sec\r
32 \r
33 256 bit key:\r
34 Key Setup:    2349 cycles\r
35 Encrypt:       952 cycles =    26.9 mbits/sec\r
36 Decrypt:       914 cycles =    28.0 mbits/sec\r
37 Mean:          933 cycles =    27.4 mbits/sec\r
38 \r
39 Full timing with I/O endian conversion:\r
40 \r
41 128 bit key:\r
42 Key Setup:    2415 cycles\r
43 Encrypt:       985 cycles =    26.0 mbits/sec\r
44 Decrypt:       954 cycles =    26.8 mbits/sec\r
45 Mean:          970 cycles =    26.4 mbits/sec\r
46 \r
47 192 bit key:\r
48 Key Setup:    2438 cycles\r
49 Encrypt:       985 cycles =    26.0 mbits/sec\r
50 Decrypt:       954 cycles =    26.8 mbits/sec\r
51 Mean:          970 cycles =    26.4 mbits/sec\r
52 \r
53 256 bit key:\r
54 Key Setup:    2463 cycles\r
55 Encrypt:       985 cycles =    26.0 mbits/sec\r
56 Decrypt:       954 cycles =    26.8 mbits/sec\r
57 Mean:          970 cycles =    26.4 mbits/sec\r
58 \r
59 */\r
60 \r
61 #include <stdio.h>\r
62 #include <sys/types.h>\r
63 #include "serpent_internal.h"\r
64 \r
65 /* Partially optimised Serpent S Box boolean functions derived  */\r
66 /* using a recursive descent analyser but without a full search */\r
67 /* of all subtrees. This set of S boxes is the result of work   */\r
68 /* by Sam Simpson and Brian Gladman using the spare time on a   */\r
69 /* cluster of high capacity servers to search for S boxes with  */\r
70 /* this customised search engine.                               */\r
71 /*                                                              */\r
72 /* Copyright:   Dr B. R Gladman (gladman@seven77.demon.co.uk)   */\r
73 /*              and Sam Simpson (s.simpson@mia.co.uk)           */ \r
74 /*              17th December 1998                              */\r
75 /*                                                              */\r
76 /* We hereby give permission for information in this file to be */\r
77 /* used freely subject only to acknowledgement of its origin    */\r
78 \r
79 /* 15 terms */\r
80 \r
81 #define sb0(a,b,c,d,e,f,g,h)    \\r
82     t1 = a ^ d;     \\r
83     t2 = a & d;     \\r
84     t3 = c ^ t1;    \\r
85     t6 = b & t1;    \\r
86     t4 = b ^ t3;    \\r
87     t10 = ~t3;      \\r
88     h = t2 ^ t4;    \\r
89     t7 = a ^ t6;    \\r
90     t14 = ~t7;      \\r
91     t8 = c | t7;    \\r
92     t11 = t3 ^ t7;  \\r
93     g = t4 ^ t8;    \\r
94     t12 = h & t11;  \\r
95     f = t10 ^ t12;  \\r
96     e = t12 ^ t14\r
97 \r
98 /* 15 terms */\r
99 \r
100 #define ib0(a,b,c,d,e,f,g,h)    \\r
101     t1 = ~a;        \\r
102     t2 = a ^ b;     \\r
103     t3 = t1 | t2;   \\r
104     t4 = d ^ t3;    \\r
105     t7 = d & t2;    \\r
106     t5 = c ^ t4;    \\r
107     t8 = t1 ^ t7;   \\r
108     g = t2 ^ t5;    \\r
109     t11 = a & t4;   \\r
110     t9 = g & t8;    \\r
111     t14 = t5 ^ t8;  \\r
112     f = t4 ^ t9;    \\r
113     t12 = t5 | f;   \\r
114     h = t11 ^ t12;  \\r
115     e = h ^ t14\r
116 \r
117 /* 14 terms!  */\r
118 \r
119 #define sb1(a,b,c,d,e,f,g,h)    \\r
120     t1 = ~a;        \\r
121     t2 = b ^ t1;    \\r
122     t3 = a | t2;    \\r
123     t4 = d | t2;    \\r
124     t5 = c ^ t3;    \\r
125     g = d ^ t5;     \\r
126     t7 = b ^ t4;    \\r
127     t8 = t2 ^ g;    \\r
128     t9 = t5 & t7;   \\r
129     h = t8 ^ t9;    \\r
130     t11 = t5 ^ t7;  \\r
131     f = h ^ t11;    \\r
132     t13 = t8 & t11; \\r
133     e = t5 ^ t13\r
134 \r
135 /* 17 terms */\r
136 \r
137 #define ib1(a,b,c,d,e,f,g,h)    \\r
138     t1 = a ^ d;     \\r
139     t2 = a & b;     \\r
140     t3 = b ^ c;     \\r
141     t4 = a ^ t3;    \\r
142     t5 = b | d;     \\r
143     t7 = c | t1;    \\r
144     h = t4 ^ t5;    \\r
145     t8 = b ^ t7;    \\r
146     t11 = ~t2;      \\r
147     t9 = t4 & t8;   \\r
148     f = t1 ^ t9;    \\r
149     t13 = t9 ^ t11; \\r
150     t12 = h & f;    \\r
151     g = t12 ^ t13;  \\r
152     t15 = a & d;    \\r
153     t16 = c ^ t13;  \\r
154     e = t15 ^ t16\r
155 \r
156 /* 16 terms */\r
157 \r
158 #define sb2(a,b,c,d,e,f,g,h)    \\r
159     t1 = ~a;        \\r
160     t2 = b ^ d;     \\r
161     t3 = c & t1;    \\r
162     t13 = d | t1;   \\r
163     e = t2 ^ t3;    \\r
164     t5 = c ^ t1;    \\r
165     t6 = c ^ e;     \\r
166     t7 = b & t6;    \\r
167     t10 = e | t5;   \\r
168     h = t5 ^ t7;    \\r
169     t9 = d | t7;    \\r
170     t11 = t9 & t10; \\r
171     t14 = t2 ^ h;   \\r
172     g = a ^ t11;    \\r
173     t15 = g ^ t13;  \\r
174     f = t14 ^ t15\r
175 \r
176 /* 16 terms */\r
177 \r
178 #define ib2(a,b,c,d,e,f,g,h)    \\r
179     t1 = b ^ d;     \\r
180     t2 = ~t1;       \\r
181     t3 = a ^ c;     \\r
182     t4 = c ^ t1;    \\r
183     t7 = a | t2;    \\r
184     t5 = b & t4;    \\r
185     t8 = d ^ t7;    \\r
186     t11 = ~t4;      \\r
187     e = t3 ^ t5;    \\r
188     t9 = t3 | t8;   \\r
189     t14 = d & t11;  \\r
190     h = t1 ^ t9;    \\r
191     t12 = e | h;    \\r
192     f = t11 ^ t12;  \\r
193     t15 = t3 ^ t12; \\r
194     g = t14 ^ t15\r
195 \r
196 /* 17 terms */\r
197 \r
198 #define sb3(a,b,c,d,e,f,g,h)    \\r
199     t1 = a ^ c;     \\r
200     t2 = d ^ t1;    \\r
201     t3 = a & t2;    \\r
202     t4 = d ^ t3;    \\r
203     t5 = b & t4;    \\r
204     g = t2 ^ t5;    \\r
205     t7 = a | g;     \\r
206     t8 = b | d;     \\r
207     t11 = a | d;    \\r
208     t9 = t4 & t7;   \\r
209     f = t8 ^ t9;    \\r
210     t12 = b ^ t11;  \\r
211     t13 = g ^ t9;   \\r
212     t15 = t3 ^ t8;  \\r
213     h = t12 ^ t13;  \\r
214     t16 = c & t15;  \\r
215     e = t12 ^ t16\r
216 \r
217 /* 16 term solution that performs less well than 17 term one\r
218    in my environment (PPro/PII)                                  \r
219 \r
220 #define sb3(a,b,c,d,e,f,g,h)    \\r
221     t1 = a ^ b;     \\r
222     t2 = a & c;     \\r
223     t3 = a | d;     \\r
224     t4 = c ^ d;     \\r
225     t5 = t1 & t3;   \\r
226     t6 = t2 | t5;   \\r
227     g = t4 ^ t6;    \\r
228     t8 = b ^ t3;    \\r
229     t9 = t6 ^ t8;   \\r
230     t10 = t4 & t9;  \\r
231     e = t1 ^ t10;   \\r
232     t12 = g & e;    \\r
233     f = t9 ^ t12;   \\r
234     t14 = b | d;    \\r
235     t15 = t4 ^ t12; \\r
236     h = t14 ^ t15\r
237 */\r
238 \r
239 /* 17 terms */\r
240 \r
241 #define ib3(a,b,c,d,e,f,g,h)    \\r
242     t1 = b ^ c;     \\r
243     t2 = b | c;     \\r
244     t3 = a ^ c;     \\r
245     t7 = a ^ d;     \\r
246     t4 = t2 ^ t3;   \\r
247     t5 = d | t4;    \\r
248     t9 = t2 ^ t7;   \\r
249     e = t1 ^ t5;    \\r
250     t8 = t1 | t5;   \\r
251     t11 = a & t4;   \\r
252     g = t8 ^ t9;    \\r
253     t12 = e | t9;   \\r
254     f = t11 ^ t12;  \\r
255     t14 = a & g;    \\r
256     t15 = t2 ^ t14; \\r
257     t16 = e & t15;  \\r
258     h = t4 ^ t16\r
259 \r
260 /* 15 terms */\r
261 \r
262 #define sb4(a,b,c,d,e,f,g,h)    \\r
263     t1 = a ^ d;     \\r
264     t2 = d & t1;    \\r
265     t3 = c ^ t2;    \\r
266     t4 = b | t3;    \\r
267     h = t1 ^ t4;    \\r
268     t6 = ~b;        \\r
269     t7 = t1 | t6;   \\r
270     e = t3 ^ t7;    \\r
271     t9 = a & e;     \\r
272     t10 = t1 ^ t6;  \\r
273     t11 = t4 & t10; \\r
274     g = t9 ^ t11;   \\r
275     t13 = a ^ t3;   \\r
276     t14 = t10 & g;  \\r
277     f = t13 ^ t14\r
278 \r
279 /* 17 terms */\r
280 \r
281 #define ib4(a,b,c,d,e,f,g,h)    \\r
282     t1 = c ^ d;     \\r
283     t2 = c | d;     \\r
284     t3 = b ^ t2;    \\r
285     t4 = a & t3;    \\r
286     f = t1 ^ t4;    \\r
287     t6 = a ^ d;     \\r
288     t7 = b | d;     \\r
289     t8 = t6 & t7;   \\r
290     h = t3 ^ t8;    \\r
291     t10 = ~a;       \\r
292     t11 = c ^ h;    \\r
293     t12 = t10 | t11;\\r
294     e = t3 ^ t12;   \\r
295     t14 = c | t4;   \\r
296     t15 = t7 ^ t14; \\r
297     t16 = h | t10;  \\r
298     g = t15 ^ t16\r
299 \r
300 /* 16 terms */\r
301 \r
302 #define sb5(a,b,c,d,e,f,g,h)    \\r
303     t1 = ~a;        \\r
304     t2 = a ^ b;     \\r
305     t3 = a ^ d;     \\r
306     t4 = c ^ t1;    \\r
307     t5 = t2 | t3;   \\r
308     e = t4 ^ t5;    \\r
309     t7 = d & e;     \\r
310     t8 = t2 ^ e;    \\r
311     t10 = t1 | e;   \\r
312     f = t7 ^ t8;    \\r
313     t11 = t2 | t7;  \\r
314     t12 = t3 ^ t10; \\r
315     t14 = b ^ t7;   \\r
316     g = t11 ^ t12;  \\r
317     t15 = f & t12;  \\r
318     h = t14 ^ t15\r
319 \r
320 /* 16 terms */\r
321 \r
322 #define ib5(a,b,c,d,e,f,g,h)    \\r
323     t1 = ~c;        \\r
324     t2 = b & t1;    \\r
325     t3 = d ^ t2;    \\r
326     t4 = a & t3;    \\r
327     t5 = b ^ t1;    \\r
328     h = t4 ^ t5;    \\r
329     t7 = b | h;     \\r
330     t8 = a & t7;    \\r
331     f = t3 ^ t8;    \\r
332     t10 = a | d;    \\r
333     t11 = t1 ^ t7;  \\r
334     e = t10 ^ t11;  \\r
335     t13 = a ^ c;    \\r
336     t14 = b & t10;  \\r
337     t15 = t4 | t13; \\r
338     g = t14 ^ t15\r
339 \r
340 /* 15 terms */\r
341 \r
342 #define sb6(a,b,c,d,e,f,g,h)    \\r
343     t1 = ~a;        \\r
344     t2 = a ^ d;     \\r
345     t3 = b ^ t2;    \\r
346     t4 = t1 | t2;   \\r
347     t5 = c ^ t4;    \\r
348     f = b ^ t5;     \\r
349     t13 = ~t5;      \\r
350     t7 = t2 | f;    \\r
351     t8 = d ^ t7;    \\r
352     t9 = t5 & t8;   \\r
353     g = t3 ^ t9;    \\r
354     t11 = t5 ^ t8;  \\r
355     e = g ^ t11;    \\r
356     t14 = t3 & t11; \\r
357     h = t13 ^ t14\r
358 \r
359 /* 15 terms */\r
360 \r
361 #define ib6(a,b,c,d,e,f,g,h)    \\r
362     t1 = ~a;        \\r
363     t2 = a ^ b;     \\r
364     t3 = c ^ t2;    \\r
365     t4 = c | t1;    \\r
366     t5 = d ^ t4;    \\r
367     t13 = d & t1;   \\r
368     f = t3 ^ t5;    \\r
369     t7 = t3 & t5;   \\r
370     t8 = t2 ^ t7;   \\r
371     t9 = b | t8;    \\r
372     h = t5 ^ t9;    \\r
373     t11 = b | h;    \\r
374     e = t8 ^ t11;   \\r
375     t14 = t3 ^ t11; \\r
376     g = t13 ^ t14\r
377 \r
378 /* 17 terms */\r
379 \r
380 #define sb7(a,b,c,d,e,f,g,h)    \\r
381     t1 = ~c;        \\r
382     t2 = b ^ c;     \\r
383     t3 = b | t1;    \\r
384     t4 = d ^ t3;    \\r
385     t5 = a & t4;    \\r
386     t7 = a ^ d;     \\r
387     h = t2 ^ t5;    \\r
388     t8 = b ^ t5;    \\r
389     t9 = t2 | t8;   \\r
390     t11 = d & t3;   \\r
391     f = t7 ^ t9;    \\r
392     t12 = t5 ^ f;   \\r
393     t15 = t1 | t4;  \\r
394     t13 = h & t12;  \\r
395     g = t11 ^ t13;  \\r
396     t16 = t12 ^ g;  \\r
397     e = t15 ^ t16\r
398 \r
399 /* 17 terms */\r
400 \r
401 #define ib7(a,b,c,d,e,f,g,h)    \\r
402     t1 = a & b;     \\r
403     t2 = a | b;     \\r
404     t3 = c | t1;    \\r
405     t4 = d & t2;    \\r
406     h = t3 ^ t4;    \\r
407     t6 = ~d;        \\r
408     t7 = b ^ t4;    \\r
409     t8 = h ^ t6;    \\r
410     t11 = c ^ t7;   \\r
411     t9 = t7 | t8;   \\r
412     f = a ^ t9;     \\r
413     t12 = d | f;    \\r
414     e = t11 ^ t12;  \\r
415     t14 = a & h;    \\r
416     t15 = t3 ^ f;   \\r
417     t16 = e ^ t14;  \\r
418     g = t15 ^ t16\r
419 \r
420 #define k_xor(r,a,b,c,d)    \\r
421     a ^= l_key[4 * r +  8]; \\r
422     b ^= l_key[4 * r +  9]; \\r
423     c ^= l_key[4 * r + 10]; \\r
424     d ^= l_key[4 * r + 11]\r
425 \r
426 #define k_set(r,a,b,c,d)    \\r
427     a = l_key[4 * r +  8];  \\r
428     b = l_key[4 * r +  9];  \\r
429     c = l_key[4 * r + 10];  \\r
430     d = l_key[4 * r + 11]\r
431 \r
432 #define k_get(r,a,b,c,d)    \\r
433     l_key[4 * r +  8] = a;  \\r
434     l_key[4 * r +  9] = b;  \\r
435     l_key[4 * r + 10] = c;  \\r
436     l_key[4 * r + 11] = d\r
437 \r
438 /* the linear transformation and its inverse    */\r
439 \r
440 #define rot(a,b,c,d)    \\r
441     a = rotl(a, 13);    \\r
442     c = rotl(c, 3);     \\r
443     d ^= c ^ (a << 3);  \\r
444     b ^= a ^ c;         \\r
445     d = rotl(d, 7);     \\r
446     b = rotl(b, 1);     \\r
447     a ^= b ^ d;         \\r
448     c ^= d ^ (b << 7);  \\r
449     a = rotl(a, 5);     \\r
450     c = rotl(c, 22)\r
451 \r
452 #define irot(a,b,c,d)   \\r
453     c = rotr(c, 22);    \\r
454     a = rotr(a, 5);     \\r
455     c ^= d ^ (b << 7);  \\r
456     a ^= b ^ d;         \\r
457     d = rotr(d, 7);     \\r
458     b = rotr(b, 1);     \\r
459     d ^= c ^ (a << 3);  \\r
460     b ^= a ^ c;         \\r
461     c = rotr(c, 3);     \\r
462     a = rotr(a, 13)\r
463 \r
464 /* initialise the key schedule from the user supplied key   */\r
465 \r
466 u4byte *serpent_set_key(SerpentContext *ctx,\r
467                         const u4byte in_key[], const u4byte key_len)\r
468 {   \r
469     u4byte  i,lk,a,b,c,d,e,f,g,h;\r
470     u4byte  t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;\r
471     u4byte *l_key = ctx->l_key;\r
472 \r
473     if(key_len < 0 || key_len > 256)\r
474 \r
475         return (u4byte*)0;\r
476 \r
477     i = 0; lk = (key_len + 31) / 32;\r
478     \r
479     while(i < lk)\r
480     {\r
481 #ifdef  BLOCK_SWAP\r
482         l_key[i] = io_swap(in_key[lk - i - 1]);\r
483 #else\r
484         l_key[i] = in_key[i];\r
485 #endif  \r
486         i++;\r
487     }\r
488 \r
489     if(key_len < 256)\r
490     {\r
491         while(i < 8)\r
492 \r
493             l_key[i++] = 0;\r
494 \r
495         i = key_len / 32; lk = 1 << key_len % 32; \r
496 \r
497         l_key[i] = l_key[i] & (lk - 1) | lk;\r
498     }\r
499 \r
500     for(i = 0; i < 132; ++i)\r
501     {\r
502         lk = l_key[i] ^ l_key[i + 3] ^ l_key[i + 5] \r
503                                 ^ l_key[i + 7] ^ 0x9e3779b9 ^ i;\r
504 \r
505         l_key[i + 8] = (lk << 11) | (lk >> 21); \r
506     }\r
507 \r
508     k_set( 0,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get( 0,e,f,g,h);\r
509     k_set( 1,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get( 1,e,f,g,h);\r
510     k_set( 2,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get( 2,e,f,g,h);\r
511     k_set( 3,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get( 3,e,f,g,h);\r
512     k_set( 4,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get( 4,e,f,g,h);\r
513     k_set( 5,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get( 5,e,f,g,h);\r
514     k_set( 6,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get( 6,e,f,g,h);\r
515     k_set( 7,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get( 7,e,f,g,h);\r
516     k_set( 8,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get( 8,e,f,g,h);\r
517     k_set( 9,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get( 9,e,f,g,h);\r
518     k_set(10,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(10,e,f,g,h);\r
519     k_set(11,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(11,e,f,g,h);\r
520     k_set(12,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(12,e,f,g,h);\r
521     k_set(13,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(13,e,f,g,h);\r
522     k_set(14,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(14,e,f,g,h);\r
523     k_set(15,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(15,e,f,g,h);\r
524     k_set(16,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(16,e,f,g,h);\r
525     k_set(17,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get(17,e,f,g,h);\r
526     k_set(18,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(18,e,f,g,h);\r
527     k_set(19,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(19,e,f,g,h);\r
528     k_set(20,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(20,e,f,g,h);\r
529     k_set(21,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(21,e,f,g,h);\r
530     k_set(22,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(22,e,f,g,h);\r
531     k_set(23,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(23,e,f,g,h);\r
532     k_set(24,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(24,e,f,g,h);\r
533     k_set(25,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get(25,e,f,g,h);\r
534     k_set(26,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(26,e,f,g,h);\r
535     k_set(27,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(27,e,f,g,h);\r
536     k_set(28,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(28,e,f,g,h);\r
537     k_set(29,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(29,e,f,g,h);\r
538     k_set(30,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(30,e,f,g,h);\r
539     k_set(31,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(31,e,f,g,h);\r
540     k_set(32,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(32,e,f,g,h);\r
541 \r
542     return l_key;\r
543 };\r
544 \r
545 /* encrypt a block of text  */\r
546 \r
547 void serpent_encrypt(SerpentContext *ctx,\r
548                      const u4byte in_blk[4], u4byte out_blk[])\r
549 {   \r
550     u4byte  a,b,c,d,e,f,g,h;\r
551     u4byte  t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;\r
552     u4byte *l_key = ctx->l_key;\r
553 \r
554 #ifdef  BLOCK_SWAP\r
555     a = io_swap(in_blk[3]); b = io_swap(in_blk[2]); \r
556     c = io_swap(in_blk[1]); d = io_swap(in_blk[0]);\r
557 #else\r
558     a = in_blk[0]; b = in_blk[1]; c = in_blk[2]; d = in_blk[3];\r
559 #endif\r
560 \r
561     k_xor( 0,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
562     k_xor( 1,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
563     k_xor( 2,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
564     k_xor( 3,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
565     k_xor( 4,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
566     k_xor( 5,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
567     k_xor( 6,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
568     k_xor( 7,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
569     k_xor( 8,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
570     k_xor( 9,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
571     k_xor(10,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
572     k_xor(11,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
573     k_xor(12,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
574     k_xor(13,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
575     k_xor(14,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
576     k_xor(15,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
577     k_xor(16,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
578     k_xor(17,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
579     k_xor(18,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
580     k_xor(19,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
581     k_xor(20,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
582     k_xor(21,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
583     k_xor(22,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
584     k_xor(23,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
585     k_xor(24,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
586     k_xor(25,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
587     k_xor(26,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
588     k_xor(27,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
589     k_xor(28,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
590     k_xor(29,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); \r
591     k_xor(30,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); \r
592     k_xor(31,e,f,g,h); sb7(e,f,g,h,a,b,c,d); k_xor(32,a,b,c,d); \r
593     \r
594 #ifdef  BLOCK_SWAP\r
595     out_blk[3] = io_swap(a); out_blk[2] = io_swap(b); \r
596     out_blk[1] = io_swap(c); out_blk[0] = io_swap(d);\r
597 #else\r
598     out_blk[0] = a; out_blk[1] = b; out_blk[2] = c; out_blk[3] = d;\r
599 #endif\r
600 };\r
601 \r
602 /* decrypt a block of text  */\r
603 \r
604 void serpent_decrypt(SerpentContext *ctx,\r
605                      const u4byte in_blk[4], u4byte out_blk[4])\r
606 {   \r
607     u4byte  a,b,c,d,e,f,g,h;\r
608     u4byte  t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;\r
609     u4byte *l_key = ctx->l_key;\r
610     \r
611 #ifdef  BLOCK_SWAP\r
612     a = io_swap(in_blk[3]); b = io_swap(in_blk[2]); \r
613     c = io_swap(in_blk[1]); d = io_swap(in_blk[0]);\r
614 #else\r
615     a = in_blk[0]; b = in_blk[1]; c = in_blk[2]; d = in_blk[3];\r
616 #endif\r
617 \r
618     k_xor(32,a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(31,e,f,g,h);\r
619     irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(30,a,b,c,d);\r
620     irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(29,e,f,g,h);\r
621     irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(28,a,b,c,d);\r
622     irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(27,e,f,g,h);\r
623     irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(26,a,b,c,d);\r
624     irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(25,e,f,g,h);\r
625     irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(24,a,b,c,d);\r
626     irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(23,e,f,g,h);\r
627     irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(22,a,b,c,d);\r
628     irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(21,e,f,g,h);\r
629     irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(20,a,b,c,d);\r
630     irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(19,e,f,g,h);\r
631     irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(18,a,b,c,d);\r
632     irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(17,e,f,g,h);\r
633     irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(16,a,b,c,d);\r
634     irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(15,e,f,g,h);\r
635     irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(14,a,b,c,d);\r
636     irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(13,e,f,g,h);\r
637     irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(12,a,b,c,d);\r
638     irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(11,e,f,g,h);\r
639     irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(10,a,b,c,d);\r
640     irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 9,e,f,g,h);\r
641     irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 8,a,b,c,d);\r
642     irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor( 7,e,f,g,h);\r
643     irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor( 6,a,b,c,d);\r
644     irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor( 5,e,f,g,h);\r
645     irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor( 4,a,b,c,d);\r
646     irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor( 3,e,f,g,h);\r
647     irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor( 2,a,b,c,d);\r
648     irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 1,e,f,g,h);\r
649     irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 0,a,b,c,d);\r
650     \r
651 #ifdef  BLOCK_SWAP\r
652     out_blk[3] = io_swap(a); out_blk[2] = io_swap(b); \r
653     out_blk[1] = io_swap(c); out_blk[0] = io_swap(d);\r
654 #else\r
655     out_blk[0] = a; out_blk[1] = b; out_blk[2] = c; out_blk[3] = d;\r
656 #endif\r
657 };\r