1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3
4 /* Based on serpent.cpp - originally written and placed in the public domain by Wei Dai
5 https://github.com/weidai11/cryptopp/blob/master/serpent.cpp
6
7 On 2017-10-16 wikipedia says:
8 "The Serpent cipher algorithm is in the public domain and has not been patented."
9 https://en.wikipedia.org/wiki/Serpent_(cipher)
10 */
11
12 #include "tomcrypt_private.h"
13
14 #ifdef LTC_SERPENT
15
16 const struct ltc_cipher_descriptor serpent_desc = {
17 "serpent",
18 25, /* cipher_ID */
19 16, 32, 16, 32, /* min_key_len, max_key_len, block_len, default_rounds */
20 &serpent_setup,
21 &serpent_ecb_encrypt,
22 &serpent_ecb_decrypt,
23 &serpent_test,
24 &serpent_done,
25 &serpent_keysize,
26 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
27 };
28
29 /* linear transformation */
30 #define s_lt(i,a,b,c,d,e) { \
31 a = ROLc(a, 13); \
32 c = ROLc(c, 3); \
33 d = ROLc(d ^ c ^ (a << 3), 7); \
34 b = ROLc(b ^ a ^ c, 1); \
35 a = ROLc(a ^ b ^ d, 5); \
36 c = ROLc(c ^ d ^ (b << 7), 22); \
37 }
38
39 /* inverse linear transformation */
40 #define s_ilt(i,a,b,c,d,e) { \
41 c = RORc(c, 22); \
42 a = RORc(a, 5); \
43 c ^= d ^ (b << 7); \
44 a ^= b ^ d; \
45 b = RORc(b, 1); \
46 d = RORc(d, 7) ^ c ^ (a << 3); \
47 b ^= a ^ c; \
48 c = RORc(c, 3); \
49 a = RORc(a, 13); \
50 }
51
52 /* order of output from S-box functions */
53 #define s_beforeS0(f) f(0,a,b,c,d,e)
54 #define s_afterS0(f) f(1,b,e,c,a,d)
55 #define s_afterS1(f) f(2,c,b,a,e,d)
56 #define s_afterS2(f) f(3,a,e,b,d,c)
57 #define s_afterS3(f) f(4,e,b,d,c,a)
58 #define s_afterS4(f) f(5,b,a,e,c,d)
59 #define s_afterS5(f) f(6,a,c,b,e,d)
60 #define s_afterS6(f) f(7,a,c,d,b,e)
61 #define s_afterS7(f) f(8,d,e,b,a,c)
62
63 /* order of output from inverse S-box functions */
64 #define s_beforeI7(f) f(8,a,b,c,d,e)
65 #define s_afterI7(f) f(7,d,a,b,e,c)
66 #define s_afterI6(f) f(6,a,b,c,e,d)
67 #define s_afterI5(f) f(5,b,d,e,c,a)
68 #define s_afterI4(f) f(4,b,c,e,a,d)
69 #define s_afterI3(f) f(3,a,b,e,c,d)
70 #define s_afterI2(f) f(2,b,d,e,c,a)
71 #define s_afterI1(f) f(1,a,b,c,e,d)
72 #define s_afterI0(f) f(0,a,d,b,e,c)
73
74 /* The instruction sequences for the S-box functions
75 * come from Dag Arne Osvik's paper "Speeding up Serpent".
76 */
77
78 #define s_s0(i, r0, r1, r2, r3, r4) { \
79 r3 ^= r0; \
80 r4 = r1; \
81 r1 &= r3; \
82 r4 ^= r2; \
83 r1 ^= r0; \
84 r0 |= r3; \
85 r0 ^= r4; \
86 r4 ^= r3; \
87 r3 ^= r2; \
88 r2 |= r1; \
89 r2 ^= r4; \
90 r4 = ~r4; \
91 r4 |= r1; \
92 r1 ^= r3; \
93 r1 ^= r4; \
94 r3 |= r0; \
95 r1 ^= r3; \
96 r4 ^= r3; \
97 }
98
99 #define s_i0(i, r0, r1, r2, r3, r4) { \
100 r2 = ~r2; \
101 r4 = r1; \
102 r1 |= r0; \
103 r4 = ~r4; \
104 r1 ^= r2; \
105 r2 |= r4; \
106 r1 ^= r3; \
107 r0 ^= r4; \
108 r2 ^= r0; \
109 r0 &= r3; \
110 r4 ^= r0; \
111 r0 |= r1; \
112 r0 ^= r2; \
113 r3 ^= r4; \
114 r2 ^= r1; \
115 r3 ^= r0; \
116 r3 ^= r1; \
117 r2 &= r3; \
118 r4 ^= r2; \
119 }
120
121 #define s_s1(i, r0, r1, r2, r3, r4) { \
122 r0 = ~r0; \
123 r2 = ~r2; \
124 r4 = r0; \
125 r0 &= r1; \
126 r2 ^= r0; \
127 r0 |= r3; \
128 r3 ^= r2; \
129 r1 ^= r0; \
130 r0 ^= r4; \
131 r4 |= r1; \
132 r1 ^= r3; \
133 r2 |= r0; \
134 r2 &= r4; \
135 r0 ^= r1; \
136 r1 &= r2; \
137 r1 ^= r0; \
138 r0 &= r2; \
139 r0 ^= r4; \
140 }
141
142 #define s_i1(i, r0, r1, r2, r3, r4) { \
143 r4 = r1; \
144 r1 ^= r3; \
145 r3 &= r1; \
146 r4 ^= r2; \
147 r3 ^= r0; \
148 r0 |= r1; \
149 r2 ^= r3; \
150 r0 ^= r4; \
151 r0 |= r2; \
152 r1 ^= r3; \
153 r0 ^= r1; \
154 r1 |= r3; \
155 r1 ^= r0; \
156 r4 = ~r4; \
157 r4 ^= r1; \
158 r1 |= r0; \
159 r1 ^= r0; \
160 r1 |= r4; \
161 r3 ^= r1; \
162 }
163
164 #define s_s2(i, r0, r1, r2, r3, r4) { \
165 r4 = r0; \
166 r0 &= r2; \
167 r0 ^= r3; \
168 r2 ^= r1; \
169 r2 ^= r0; \
170 r3 |= r4; \
171 r3 ^= r1; \
172 r4 ^= r2; \
173 r1 = r3; \
174 r3 |= r4; \
175 r3 ^= r0; \
176 r0 &= r1; \
177 r4 ^= r0; \
178 r1 ^= r3; \
179 r1 ^= r4; \
180 r4 = ~r4; \
181 }
182
183 #define s_i2(i, r0, r1, r2, r3, r4) { \
184 r2 ^= r3; \
185 r3 ^= r0; \
186 r4 = r3; \
187 r3 &= r2; \
188 r3 ^= r1; \
189 r1 |= r2; \
190 r1 ^= r4; \
191 r4 &= r3; \
192 r2 ^= r3; \
193 r4 &= r0; \
194 r4 ^= r2; \
195 r2 &= r1; \
196 r2 |= r0; \
197 r3 = ~r3; \
198 r2 ^= r3; \
199 r0 ^= r3; \
200 r0 &= r1; \
201 r3 ^= r4; \
202 r3 ^= r0; \
203 }
204
205 #define s_s3(i, r0, r1, r2, r3, r4) { \
206 r4 = r0; \
207 r0 |= r3; \
208 r3 ^= r1; \
209 r1 &= r4; \
210 r4 ^= r2; \
211 r2 ^= r3; \
212 r3 &= r0; \
213 r4 |= r1; \
214 r3 ^= r4; \
215 r0 ^= r1; \
216 r4 &= r0; \
217 r1 ^= r3; \
218 r4 ^= r2; \
219 r1 |= r0; \
220 r1 ^= r2; \
221 r0 ^= r3; \
222 r2 = r1; \
223 r1 |= r3; \
224 r1 ^= r0; \
225 }
226
227 #define s_i3(i, r0, r1, r2, r3, r4) { \
228 r4 = r2; \
229 r2 ^= r1; \
230 r1 &= r2; \
231 r1 ^= r0; \
232 r0 &= r4; \
233 r4 ^= r3; \
234 r3 |= r1; \
235 r3 ^= r2; \
236 r0 ^= r4; \
237 r2 ^= r0; \
238 r0 |= r3; \
239 r0 ^= r1; \
240 r4 ^= r2; \
241 r2 &= r3; \
242 r1 |= r3; \
243 r1 ^= r2; \
244 r4 ^= r0; \
245 r2 ^= r4; \
246 }
247
248 #define s_s4(i, r0, r1, r2, r3, r4) { \
249 r1 ^= r3; \
250 r3 = ~r3; \
251 r2 ^= r3; \
252 r3 ^= r0; \
253 r4 = r1; \
254 r1 &= r3; \
255 r1 ^= r2; \
256 r4 ^= r3; \
257 r0 ^= r4; \
258 r2 &= r4; \
259 r2 ^= r0; \
260 r0 &= r1; \
261 r3 ^= r0; \
262 r4 |= r1; \
263 r4 ^= r0; \
264 r0 |= r3; \
265 r0 ^= r2; \
266 r2 &= r3; \
267 r0 = ~r0; \
268 r4 ^= r2; \
269 }
270
271 #define s_i4(i, r0, r1, r2, r3, r4) { \
272 r4 = r2; \
273 r2 &= r3; \
274 r2 ^= r1; \
275 r1 |= r3; \
276 r1 &= r0; \
277 r4 ^= r2; \
278 r4 ^= r1; \
279 r1 &= r2; \
280 r0 = ~r0; \
281 r3 ^= r4; \
282 r1 ^= r3; \
283 r3 &= r0; \
284 r3 ^= r2; \
285 r0 ^= r1; \
286 r2 &= r0; \
287 r3 ^= r0; \
288 r2 ^= r4; \
289 r2 |= r3; \
290 r3 ^= r0; \
291 r2 ^= r1; \
292 }
293
294 #define s_s5(i, r0, r1, r2, r3, r4) { \
295 r0 ^= r1; \
296 r1 ^= r3; \
297 r3 = ~r3; \
298 r4 = r1; \
299 r1 &= r0; \
300 r2 ^= r3; \
301 r1 ^= r2; \
302 r2 |= r4; \
303 r4 ^= r3; \
304 r3 &= r1; \
305 r3 ^= r0; \
306 r4 ^= r1; \
307 r4 ^= r2; \
308 r2 ^= r0; \
309 r0 &= r3; \
310 r2 = ~r2; \
311 r0 ^= r4; \
312 r4 |= r3; \
313 r2 ^= r4; \
314 }
315
316 #define s_i5(i, r0, r1, r2, r3, r4) { \
317 r1 = ~r1; \
318 r4 = r3; \
319 r2 ^= r1; \
320 r3 |= r0; \
321 r3 ^= r2; \
322 r2 |= r1; \
323 r2 &= r0; \
324 r4 ^= r3; \
325 r2 ^= r4; \
326 r4 |= r0; \
327 r4 ^= r1; \
328 r1 &= r2; \
329 r1 ^= r3; \
330 r4 ^= r2; \
331 r3 &= r4; \
332 r4 ^= r1; \
333 r3 ^= r0; \
334 r3 ^= r4; \
335 r4 = ~r4; \
336 }
337
338 #define s_s6(i, r0, r1, r2, r3, r4) { \
339 r2 = ~r2; \
340 r4 = r3; \
341 r3 &= r0; \
342 r0 ^= r4; \
343 r3 ^= r2; \
344 r2 |= r4; \
345 r1 ^= r3; \
346 r2 ^= r0; \
347 r0 |= r1; \
348 r2 ^= r1; \
349 r4 ^= r0; \
350 r0 |= r3; \
351 r0 ^= r2; \
352 r4 ^= r3; \
353 r4 ^= r0; \
354 r3 = ~r3; \
355 r2 &= r4; \
356 r2 ^= r3; \
357 }
358
359 #define s_i6(i, r0, r1, r2, r3, r4) { \
360 r0 ^= r2; \
361 r4 = r2; \
362 r2 &= r0; \
363 r4 ^= r3; \
364 r2 = ~r2; \
365 r3 ^= r1; \
366 r2 ^= r3; \
367 r4 |= r0; \
368 r0 ^= r2; \
369 r3 ^= r4; \
370 r4 ^= r1; \
371 r1 &= r3; \
372 r1 ^= r0; \
373 r0 ^= r3; \
374 r0 |= r2; \
375 r3 ^= r1; \
376 r4 ^= r0; \
377 }
378
379 #define s_s7(i, r0, r1, r2, r3, r4) { \
380 r4 = r2; \
381 r2 &= r1; \
382 r2 ^= r3; \
383 r3 &= r1; \
384 r4 ^= r2; \
385 r2 ^= r1; \
386 r1 ^= r0; \
387 r0 |= r4; \
388 r0 ^= r2; \
389 r3 ^= r1; \
390 r2 ^= r3; \
391 r3 &= r0; \
392 r3 ^= r4; \
393 r4 ^= r2; \
394 r2 &= r0; \
395 r4 = ~r4; \
396 r2 ^= r4; \
397 r4 &= r0; \
398 r1 ^= r3; \
399 r4 ^= r1; \
400 }
401
402 #define s_i7(i, r0, r1, r2, r3, r4) { \
403 r4 = r2; \
404 r2 ^= r0; \
405 r0 &= r3; \
406 r2 = ~r2; \
407 r4 |= r3; \
408 r3 ^= r1; \
409 r1 |= r0; \
410 r0 ^= r2; \
411 r2 &= r4; \
412 r1 ^= r2; \
413 r2 ^= r0; \
414 r0 |= r2; \
415 r3 &= r4; \
416 r0 ^= r3; \
417 r4 ^= r1; \
418 r3 ^= r4; \
419 r4 |= r0; \
420 r3 ^= r2; \
421 r4 ^= r2; \
422 }
423
424 /* key xor */
425 #define s_kx(r, a, b, c, d, e) { \
426 a ^= k[4 * r + 0]; \
427 b ^= k[4 * r + 1]; \
428 c ^= k[4 * r + 2]; \
429 d ^= k[4 * r + 3]; \
430 }
431
432 #define s_lk(r, a, b, c, d, e) { \
433 a = k[(8-r)*4 + 0]; \
434 b = k[(8-r)*4 + 1]; \
435 c = k[(8-r)*4 + 2]; \
436 d = k[(8-r)*4 + 3]; \
437 }
438
439 #define s_sk(r, a, b, c, d, e) { \
440 k[(8-r)*4 + 4] = a; \
441 k[(8-r)*4 + 5] = b; \
442 k[(8-r)*4 + 6] = c; \
443 k[(8-r)*4 + 7] = d; \
444 }
445
s_setup_key(const unsigned char * key,int keylen,int rounds,ulong32 * k)446 static int s_setup_key(const unsigned char *key, int keylen, int rounds, ulong32 *k)
447 {
448 int i;
449 ulong32 t;
450 ulong32 k0[8] = { 0 }; /* zero-initialize */
451 ulong32 a, b, c, d, e;
452
453 for (i = 0; i < 8 && i < keylen/4; ++i) {
454 LOAD32L(k0[i], key + i * 4);
455 }
456 if (keylen < 32) {
457 k0[keylen/4] |= (ulong32)1 << ((keylen%4)*8);
458 }
459
460 t = k0[7];
461 for (i = 0; i < 8; ++i) {
462 k[i] = k0[i] = t = ROLc(k0[i] ^ k0[(i+3)%8] ^ k0[(i+5)%8] ^ t ^ 0x9e3779b9 ^ i, 11);
463 }
464 for (i = 8; i < 4*(rounds+1); ++i) {
465 k[i] = t = ROLc(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11);
466 }
467 k -= 20;
468
469 for (i = 0; i < rounds/8; i++) {
470 s_afterS2(s_lk); s_afterS2(s_s3); s_afterS3(s_sk);
471 s_afterS1(s_lk); s_afterS1(s_s2); s_afterS2(s_sk);
472 s_afterS0(s_lk); s_afterS0(s_s1); s_afterS1(s_sk);
473 s_beforeS0(s_lk); s_beforeS0(s_s0); s_afterS0(s_sk);
474 k += 8*4;
475 s_afterS6(s_lk); s_afterS6(s_s7); s_afterS7(s_sk);
476 s_afterS5(s_lk); s_afterS5(s_s6); s_afterS6(s_sk);
477 s_afterS4(s_lk); s_afterS4(s_s5); s_afterS5(s_sk);
478 s_afterS3(s_lk); s_afterS3(s_s4); s_afterS4(s_sk);
479 }
480 s_afterS2(s_lk); s_afterS2(s_s3); s_afterS3(s_sk);
481
482 return CRYPT_OK;
483 }
484
s_enc_block(const unsigned char * in,unsigned char * out,const ulong32 * k)485 static int s_enc_block(const unsigned char *in, unsigned char *out, const ulong32 *k)
486 {
487 ulong32 a, b, c, d, e;
488 unsigned int i = 1;
489
490 LOAD32L(a, in + 0);
491 LOAD32L(b, in + 4);
492 LOAD32L(c, in + 8);
493 LOAD32L(d, in + 12);
494
495 do {
496 s_beforeS0(s_kx); s_beforeS0(s_s0); s_afterS0(s_lt);
497 s_afterS0(s_kx); s_afterS0(s_s1); s_afterS1(s_lt);
498 s_afterS1(s_kx); s_afterS1(s_s2); s_afterS2(s_lt);
499 s_afterS2(s_kx); s_afterS2(s_s3); s_afterS3(s_lt);
500 s_afterS3(s_kx); s_afterS3(s_s4); s_afterS4(s_lt);
501 s_afterS4(s_kx); s_afterS4(s_s5); s_afterS5(s_lt);
502 s_afterS5(s_kx); s_afterS5(s_s6); s_afterS6(s_lt);
503 s_afterS6(s_kx); s_afterS6(s_s7);
504
505 if (i == 4) break;
506
507 ++i;
508 c = b;
509 b = e;
510 e = d;
511 d = a;
512 a = e;
513 k += 32;
514 s_beforeS0(s_lt);
515 } while (1);
516
517 s_afterS7(s_kx);
518
519 STORE32L(d, out + 0);
520 STORE32L(e, out + 4);
521 STORE32L(b, out + 8);
522 STORE32L(a, out + 12);
523
524 return CRYPT_OK;
525 }
526
s_dec_block(const unsigned char * in,unsigned char * out,const ulong32 * k)527 static int s_dec_block(const unsigned char *in, unsigned char *out, const ulong32 *k)
528 {
529 ulong32 a, b, c, d, e;
530 unsigned int i;
531
532 LOAD32L(a, in + 0);
533 LOAD32L(b, in + 4);
534 LOAD32L(c, in + 8);
535 LOAD32L(d, in + 12);
536 e = 0; LTC_UNUSED_PARAM(e); /* avoid scan-build warning */
537 i = 4;
538 k += 96;
539
540 s_beforeI7(s_kx);
541 goto start;
542
543 do {
544 c = b;
545 b = d;
546 d = e;
547 k -= 32;
548 s_beforeI7(s_ilt);
549 start:
550 s_beforeI7(s_i7); s_afterI7(s_kx);
551 s_afterI7(s_ilt); s_afterI7(s_i6); s_afterI6(s_kx);
552 s_afterI6(s_ilt); s_afterI6(s_i5); s_afterI5(s_kx);
553 s_afterI5(s_ilt); s_afterI5(s_i4); s_afterI4(s_kx);
554 s_afterI4(s_ilt); s_afterI4(s_i3); s_afterI3(s_kx);
555 s_afterI3(s_ilt); s_afterI3(s_i2); s_afterI2(s_kx);
556 s_afterI2(s_ilt); s_afterI2(s_i1); s_afterI1(s_kx);
557 s_afterI1(s_ilt); s_afterI1(s_i0); s_afterI0(s_kx);
558 } while (--i != 0);
559
560 STORE32L(a, out + 0);
561 STORE32L(d, out + 4);
562 STORE32L(b, out + 8);
563 STORE32L(e, out + 12);
564
565 return CRYPT_OK;
566 }
567
serpent_setup(const unsigned char * key,int keylen,int num_rounds,symmetric_key * skey)568 int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
569 {
570 int err;
571
572 LTC_ARGCHK(key != NULL);
573 LTC_ARGCHK(skey != NULL);
574
575 if (num_rounds != 0 && num_rounds != 32) return CRYPT_INVALID_ROUNDS;
576 if (keylen != 16 && keylen != 24 && keylen != 32) return CRYPT_INVALID_KEYSIZE;
577
578 err = s_setup_key(key, keylen, 32, skey->serpent.k);
579 #ifdef LTC_CLEAN_STACK
580 burn_stack(sizeof(ulong32) * 14 + sizeof(int));
581 #endif
582 return err;
583 }
584
serpent_ecb_encrypt(const unsigned char * pt,unsigned char * ct,const symmetric_key * skey)585 int serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
586 {
587 int err = s_enc_block(pt, ct, skey->serpent.k);
588 #ifdef LTC_CLEAN_STACK
589 burn_stack(sizeof(ulong32) * 5 + sizeof(int));
590 #endif
591 return err;
592 }
593
serpent_ecb_decrypt(const unsigned char * ct,unsigned char * pt,const symmetric_key * skey)594 int serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
595 {
596 int err = s_dec_block(ct, pt, skey->serpent.k);
597 #ifdef LTC_CLEAN_STACK
598 burn_stack(sizeof(ulong32) * 5 + sizeof(int));
599 #endif
600 return err;
601 }
602
serpent_done(symmetric_key * skey)603 void serpent_done(symmetric_key *skey)
604 {
605 LTC_UNUSED_PARAM(skey);
606 }
607
serpent_keysize(int * keysize)608 int serpent_keysize(int *keysize)
609 {
610 LTC_ARGCHK(keysize != NULL);
611
612 if (*keysize >= 32) { *keysize = 32; }
613 else if (*keysize >= 24) { *keysize = 24; }
614 else if (*keysize >= 16) { *keysize = 16; }
615 else return CRYPT_INVALID_KEYSIZE;
616 return CRYPT_OK;
617 }
618
serpent_test(void)619 int serpent_test(void)
620 {
621 #ifndef LTC_TEST
622 return CRYPT_NOP;
623 #else
624 static const struct {
625 unsigned char key[32];
626 int keylen;
627 unsigned char pt[16], ct[16];
628 } tests[] = {
629 {
630 /* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
631 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
632 /* keylen */ 32,
633 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
634 /* ct */ {0xA2,0x23,0xAA,0x12,0x88,0x46,0x3C,0x0E,0x2B,0xE3,0x8E,0xBD,0x82,0x56,0x16,0xC0}
635 },
636 {
637 /* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
638 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
639 /* keylen */ 32,
640 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
641 /* ct */ {0xEA,0xE1,0xD4,0x05,0x57,0x01,0x74,0xDF,0x7D,0xF2,0xF9,0x96,0x6D,0x50,0x91,0x59}
642 },
643 {
644 /* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
645 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
646 /* keylen */ 32,
647 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
648 /* ct */ {0x65,0xF3,0x76,0x84,0x47,0x1E,0x92,0x1D,0xC8,0xA3,0x0F,0x45,0xB4,0x3C,0x44,0x99}
649 },
650 {
651 /* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
652 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
653 /* keylen */ 24,
654 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
655 /* ct */ {0x9E,0x27,0x4E,0xAD,0x9B,0x73,0x7B,0xB2,0x1E,0xFC,0xFC,0xA5,0x48,0x60,0x26,0x89}
656 },
657 {
658 /* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
659 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
660 /* keylen */ 24,
661 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
662 /* ct */ {0x92,0xFC,0x8E,0x51,0x03,0x99,0xE4,0x6A,0x04,0x1B,0xF3,0x65,0xE7,0xB3,0xAE,0x82}
663 },
664 {
665 /* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
666 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
667 /* keylen */ 24,
668 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
669 /* ct */ {0x5E,0x0D,0xA3,0x86,0xC4,0x6A,0xD4,0x93,0xDE,0xA2,0x03,0xFD,0xC6,0xF5,0x7D,0x70}
670 },
671 {
672 /* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
673 /* keylen */ 16,
674 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
675 /* ct */ {0x26,0x4E,0x54,0x81,0xEF,0xF4,0x2A,0x46,0x06,0xAB,0xDA,0x06,0xC0,0xBF,0xDA,0x3D}
676 },
677 {
678 /* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
679 /* keylen */ 16,
680 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
681 /* ct */ {0x4A,0x23,0x1B,0x3B,0xC7,0x27,0x99,0x34,0x07,0xAC,0x6E,0xC8,0x35,0x0E,0x85,0x24}
682 },
683 {
684 /* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
685 /* keylen */ 16,
686 /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
687 /* ct */ {0xE0,0x32,0x69,0xF9,0xE9,0xFD,0x85,0x3C,0x7D,0x81,0x56,0xDF,0x14,0xB9,0x8D,0x56}
688 }
689 };
690
691 unsigned char buf[2][16];
692 symmetric_key key;
693 int err, x;
694
695 for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
696 if ((err = serpent_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
697 return err;
698 }
699 if ((err = serpent_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) {
700 return err;
701 }
702 if (compare_testvector(buf[0], 16, tests[x].ct, 16, "SERPENT Encrypt", x)) {
703 return CRYPT_FAIL_TESTVECTOR;
704 }
705 if ((err = serpent_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) {
706 return err;
707 }
708 if (compare_testvector(buf[1], 16, tests[x].pt, 16, "SERPENT Decrypt", x)) {
709 return CRYPT_FAIL_TESTVECTOR;
710 }
711 }
712
713 return CRYPT_OK;
714 #endif
715 }
716
717 #endif
718