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