Diffstat (limited to 'pwmanager/libcrypt/cipher/serpent.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | pwmanager/libcrypt/cipher/serpent.c | 979 |
1 files changed, 979 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/cipher/serpent.c b/pwmanager/libcrypt/cipher/serpent.c new file mode 100644 index 0000000..d606d9f --- a/dev/null +++ b/pwmanager/libcrypt/cipher/serpent.c | |||
@@ -0,0 +1,979 @@ | |||
1 | /* serpent.c - Implementation of the Serpent encryption algorithm. | ||
2 | *Copyright (C) 2003 Free Software Foundation, Inc. | ||
3 | * | ||
4 | * This file is part of Libgcrypt. | ||
5 | * | ||
6 | * Libgcrypt is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Lesser general Public License as | ||
8 | * published by the Free Software Foundation; either version 2.1 of | ||
9 | * the License, or (at your option) any later version. | ||
10 | * | ||
11 | * Libgcrypt is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU Lesser General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU Lesser General Public | ||
17 | * License along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
19 | * 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include <config.h> | ||
23 | |||
24 | #include <string.h> | ||
25 | #include <stdio.h> | ||
26 | |||
27 | #include "types.h" | ||
28 | #include "g10lib.h" | ||
29 | #include "cipher.h" | ||
30 | #include "bithelp.h" | ||
31 | |||
32 | /* Number of rounds per Serpent encrypt/decrypt operation. */ | ||
33 | #define ROUNDS 32 | ||
34 | |||
35 | /* Magic number, used during generating of the subkeys. */ | ||
36 | #define PHI 0x9E3779B9 | ||
37 | |||
38 | /* Internal types. */ | ||
39 | typedef byte byte_t; | ||
40 | typedef u32 u32_t; | ||
41 | |||
42 | /* Serpent works on 128 bit blocks. */ | ||
43 | typedef u32_t serpent_block_t[4]; | ||
44 | |||
45 | /* Serpent key, provided by the user. If the original key is shorter | ||
46 | than 256 bits, it is padded. */ | ||
47 | typedef u32_t serpent_key_t[8]; | ||
48 | |||
49 | /* The key schedule consists of 33 128 bit subkeys. */ | ||
50 | typedef u32_t serpent_subkeys_t[ROUNDS + 1][4]; | ||
51 | |||
52 | /* A Serpent context. */ | ||
53 | typedef struct serpent_context | ||
54 | { | ||
55 | serpent_subkeys_t keys;/* Generated subkeys. */ | ||
56 | } serpent_context_t; | ||
57 | |||
58 | #define byte_swap_32(x) \ | ||
59 | (0 \ | ||
60 | | (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \ | ||
61 | | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)); | ||
62 | |||
63 | /* These are the S-Boxes of Serpent. They are copied from Serpents | ||
64 | reference implementation (the optimized one, contained in | ||
65 | `floppy2') and are therefore: | ||
66 | |||
67 | Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen. | ||
68 | |||
69 | To quote the Serpent homepage | ||
70 | (http://www.cl.cam.ac.uk/~rja14/serpent.html): | ||
71 | |||
72 | "Serpent is now completely in the public domain, and we impose no | ||
73 | restrictions on its use. This was announced on the 21st August at | ||
74 | the First AES Candidate Conference. The optimised implementations | ||
75 | in the submission package are now under the GNU PUBLIC LICENSE | ||
76 | (GPL), although some comments in the code still say otherwise. You | ||
77 | are welcome to use Serpent for any application." */ | ||
78 | |||
79 | #define SBOX0(a, b, c, d, w, x, y, z) \ | ||
80 | { \ | ||
81 | register unsigned long t02, t03, t05, t06, t07, t08, t09; \ | ||
82 | register unsigned long t11, t12, t13, t14, t15, t17, t01; \ | ||
83 | t01 = b ^ c ; \ | ||
84 | t02 = a | d ; \ | ||
85 | t03 = a ^ b ; \ | ||
86 | z = t02 ^ t01; \ | ||
87 | t05 = c | z ; \ | ||
88 | t06 = a ^ d ; \ | ||
89 | t07 = b | c ; \ | ||
90 | t08 = d & t05; \ | ||
91 | t09 = t03 & t07; \ | ||
92 | y = t09 ^ t08; \ | ||
93 | t11 = t09 & y ; \ | ||
94 | t12 = c ^ d ; \ | ||
95 | t13 = t07 ^ t11; \ | ||
96 | t14 = b & t06; \ | ||
97 | t15 = t06 ^ t13; \ | ||
98 | w = ~ t15; \ | ||
99 | t17 = w ^ t14; \ | ||
100 | x = t12 ^ t17; \ | ||
101 | } | ||
102 | |||
103 | #define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \ | ||
104 | { \ | ||
105 | register unsigned long t02, t03, t04, t05, t06, t08, t09, t10; \ | ||
106 | register unsigned long t12, t13, t14, t15, t17, t18, t01; \ | ||
107 | t01 = c ^ d ; \ | ||
108 | t02 = a | b ; \ | ||
109 | t03 = b | c ; \ | ||
110 | t04 = c & t01; \ | ||
111 | t05 = t02 ^ t01; \ | ||
112 | t06 = a | t04; \ | ||
113 | y = ~ t05; \ | ||
114 | t08 = b ^ d ; \ | ||
115 | t09 = t03 & t08; \ | ||
116 | t10 = d | y ; \ | ||
117 | x = t09 ^ t06; \ | ||
118 | t12 = a | t05; \ | ||
119 | t13 = x ^ t12; \ | ||
120 | t14 = t03 ^ t10; \ | ||
121 | t15 = a ^ c ; \ | ||
122 | z = t14 ^ t13; \ | ||
123 | t17 = t05 & t13; \ | ||
124 | t18 = t14 | t17; \ | ||
125 | w = t15 ^ t18; \ | ||
126 | } | ||
127 | |||
128 | #define SBOX1(a, b, c, d, w, x, y, z) \ | ||
129 | { \ | ||
130 | register unsigned long t02, t03, t04, t05, t06, t07, t08; \ | ||
131 | register unsigned long t10, t11, t12, t13, t16, t17, t01; \ | ||
132 | t01 = a | d ; \ | ||
133 | t02 = c ^ d ; \ | ||
134 | t03 = ~ b ; \ | ||
135 | t04 = a ^ c ; \ | ||
136 | t05 = a | t03; \ | ||
137 | t06 = d & t04; \ | ||
138 | t07 = t01 & t02; \ | ||
139 | t08 = b | t06; \ | ||
140 | y = t02 ^ t05; \ | ||
141 | t10 = t07 ^ t08; \ | ||
142 | t11 = t01 ^ t10; \ | ||
143 | t12 = y ^ t11; \ | ||
144 | t13 = b & d ; \ | ||
145 | z = ~ t10; \ | ||
146 | x = t13 ^ t12; \ | ||
147 | t16 = t10 | x ; \ | ||
148 | t17 = t05 & t16; \ | ||
149 | w = c ^ t17; \ | ||
150 | } | ||
151 | |||
152 | #define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \ | ||
153 | { \ | ||
154 | register unsigned long t02, t03, t04, t05, t06, t07, t08; \ | ||
155 | register unsigned long t09, t10, t11, t14, t15, t17, t01; \ | ||
156 | t01 = a ^ b ; \ | ||
157 | t02 = b | d ; \ | ||
158 | t03 = a & c ; \ | ||
159 | t04 = c ^ t02; \ | ||
160 | t05 = a | t04; \ | ||
161 | t06 = t01 & t05; \ | ||
162 | t07 = d | t03; \ | ||
163 | t08 = b ^ t06; \ | ||
164 | t09 = t07 ^ t06; \ | ||
165 | t10 = t04 | t03; \ | ||
166 | t11 = d & t08; \ | ||
167 | y = ~ t09; \ | ||
168 | x = t10 ^ t11; \ | ||
169 | t14 = a | y ; \ | ||
170 | t15 = t06 ^ x ; \ | ||
171 | z = t01 ^ t04; \ | ||
172 | t17 = c ^ t15; \ | ||
173 | w = t14 ^ t17; \ | ||
174 | } | ||
175 | |||
176 | #define SBOX2(a, b, c, d, w, x, y, z) \ | ||
177 | { \ | ||
178 | register unsigned long t02, t03, t05, t06, t07, t08; \ | ||
179 | register unsigned long t09, t10, t12, t13, t14, t01; \ | ||
180 | t01 = a | c ; \ | ||
181 | t02 = a ^ b ; \ | ||
182 | t03 = d ^ t01; \ | ||
183 | w = t02 ^ t03; \ | ||
184 | t05 = c ^ w ; \ | ||
185 | t06 = b ^ t05; \ | ||
186 | t07 = b | t05; \ | ||
187 | t08 = t01 & t06; \ | ||
188 | t09 = t03 ^ t07; \ | ||
189 | t10 = t02 | t09; \ | ||
190 | x = t10 ^ t08; \ | ||
191 | t12 = a | d ; \ | ||
192 | t13 = t09 ^ x ; \ | ||
193 | t14 = b ^ t13; \ | ||
194 | z = ~ t09; \ | ||
195 | y = t12 ^ t14; \ | ||
196 | } | ||
197 | |||
198 | #define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \ | ||
199 | { \ | ||
200 | register unsigned long t02, t03, t04, t06, t07, t08, t09; \ | ||
201 | register unsigned long t10, t11, t12, t15, t16, t17, t01; \ | ||
202 | t01 = a ^ d ; \ | ||
203 | t02 = c ^ d ; \ | ||
204 | t03 = a & c ; \ | ||
205 | t04 = b | t02; \ | ||
206 | w = t01 ^ t04; \ | ||
207 | t06 = a | c ; \ | ||
208 | t07 = d | w ; \ | ||
209 | t08 = ~ d ; \ | ||
210 | t09 = b & t06; \ | ||
211 | t10 = t08 | t03; \ | ||
212 | t11 = b & t07; \ | ||
213 | t12 = t06 & t02; \ | ||
214 | z = t09 ^ t10; \ | ||
215 | x = t12 ^ t11; \ | ||
216 | t15 = c & z ; \ | ||
217 | t16 = w ^ x ; \ | ||
218 | t17 = t10 ^ t15; \ | ||
219 | y = t16 ^ t17; \ | ||
220 | } | ||
221 | |||
222 | #define SBOX3(a, b, c, d, w, x, y, z) \ | ||
223 | { \ | ||
224 | register unsigned long t02, t03, t04, t05, t06, t07, t08; \ | ||
225 | register unsigned long t09, t10, t11, t13, t14, t15, t01; \ | ||
226 | t01 = a ^ c ; \ | ||
227 | t02 = a | d ; \ | ||
228 | t03 = a & d ; \ | ||
229 | t04 = t01 & t02; \ | ||
230 | t05 = b | t03; \ | ||
231 | t06 = a & b ; \ | ||
232 | t07 = d ^ t04; \ | ||
233 | t08 = c | t06; \ | ||
234 | t09 = b ^ t07; \ | ||
235 | t10 = d & t05; \ | ||
236 | t11 = t02 ^ t10; \ | ||
237 | z = t08 ^ t09; \ | ||
238 | t13 = d | z ; \ | ||
239 | t14 = a | t07; \ | ||
240 | t15 = b & t13; \ | ||
241 | y = t08 ^ t11; \ | ||
242 | w = t14 ^ t15; \ | ||
243 | x = t05 ^ t04; \ | ||
244 | } | ||
245 | |||
246 | #define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \ | ||
247 | { \ | ||
248 | register unsigned long t02, t03, t04, t05, t06, t07, t09; \ | ||
249 | register unsigned long t11, t12, t13, t14, t16, t01; \ | ||
250 | t01 = c | d ; \ | ||
251 | t02 = a | d ; \ | ||
252 | t03 = c ^ t02; \ | ||
253 | t04 = b ^ t02; \ | ||
254 | t05 = a ^ d ; \ | ||
255 | t06 = t04 & t03; \ | ||
256 | t07 = b & t01; \ | ||
257 | y = t05 ^ t06; \ | ||
258 | t09 = a ^ t03; \ | ||
259 | w = t07 ^ t03; \ | ||
260 | t11 = w | t05; \ | ||
261 | t12 = t09 & t11; \ | ||
262 | t13 = a & y ; \ | ||
263 | t14 = t01 ^ t05; \ | ||
264 | x = b ^ t12; \ | ||
265 | t16 = b | t13; \ | ||
266 | z = t14 ^ t16; \ | ||
267 | } | ||
268 | |||
269 | #define SBOX4(a, b, c, d, w, x, y, z) \ | ||
270 | { \ | ||
271 | register unsigned long t02, t03, t04, t05, t06, t08, t09; \ | ||
272 | register unsigned long t10, t11, t12, t13, t14, t15, t16, t01; \ | ||
273 | t01 = a | b ; \ | ||
274 | t02 = b | c ; \ | ||
275 | t03 = a ^ t02; \ | ||
276 | t04 = b ^ d ; \ | ||
277 | t05 = d | t03; \ | ||
278 | t06 = d & t01; \ | ||
279 | z = t03 ^ t06; \ | ||
280 | t08 = z & t04; \ | ||
281 | t09 = t04 & t05; \ | ||
282 | t10 = c ^ t06; \ | ||
283 | t11 = b & c ; \ | ||
284 | t12 = t04 ^ t08; \ | ||
285 | t13 = t11 | t03; \ | ||
286 | t14 = t10 ^ t09; \ | ||
287 | t15 = a & t05; \ | ||
288 | t16 = t11 | t12; \ | ||
289 | y = t13 ^ t08; \ | ||
290 | x = t15 ^ t16; \ | ||
291 | w = ~ t14; \ | ||
292 | } | ||
293 | |||
294 | #define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \ | ||
295 | { \ | ||
296 | register unsigned long t02, t03, t04, t05, t06, t07, t09; \ | ||
297 | register unsigned long t10, t11, t12, t13, t15, t01; \ | ||
298 | t01 = b | d ; \ | ||
299 | t02 = c | d ; \ | ||
300 | t03 = a & t01; \ | ||
301 | t04 = b ^ t02; \ | ||
302 | t05 = c ^ d ; \ | ||
303 | t06 = ~ t03; \ | ||
304 | t07 = a & t04; \ | ||
305 | x = t05 ^ t07; \ | ||
306 | t09 = x | t06; \ | ||
307 | t10 = a ^ t07; \ | ||
308 | t11 = t01 ^ t09; \ | ||
309 | t12 = d ^ t04; \ | ||
310 | t13 = c | t10; \ | ||
311 | z = t03 ^ t12; \ | ||
312 | t15 = a ^ t04; \ | ||
313 | y = t11 ^ t13; \ | ||
314 | w = t15 ^ t09; \ | ||
315 | } | ||
316 | |||
317 | #define SBOX5(a, b, c, d, w, x, y, z) \ | ||
318 | { \ | ||
319 | register unsigned long t02, t03, t04, t05, t07, t08, t09; \ | ||
320 | register unsigned long t10, t11, t12, t13, t14, t01; \ | ||
321 | t01 = b ^ d ; \ | ||
322 | t02 = b | d ; \ | ||
323 | t03 = a & t01; \ | ||
324 | t04 = c ^ t02; \ | ||
325 | t05 = t03 ^ t04; \ | ||
326 | w = ~ t05; \ | ||
327 | t07 = a ^ t01; \ | ||
328 | t08 = d | w ; \ | ||
329 | t09 = b | t05; \ | ||
330 | t10 = d ^ t08; \ | ||
331 | t11 = b | t07; \ | ||
332 | t12 = t03 | w ; \ | ||
333 | t13 = t07 | t10; \ | ||
334 | t14 = t01 ^ t11; \ | ||
335 | y = t09 ^ t13; \ | ||
336 | x = t07 ^ t08; \ | ||
337 | z = t12 ^ t14; \ | ||
338 | } | ||
339 | |||
340 | #define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \ | ||
341 | { \ | ||
342 | register unsigned long t02, t03, t04, t05, t07, t08, t09; \ | ||
343 | register unsigned long t10, t12, t13, t15, t16, t01; \ | ||
344 | t01 = a & d ; \ | ||
345 | t02 = c ^ t01; \ | ||
346 | t03 = a ^ d ; \ | ||
347 | t04 = b & t02; \ | ||
348 | t05 = a & c ; \ | ||
349 | w = t03 ^ t04; \ | ||
350 | t07 = a & w ; \ | ||
351 | t08 = t01 ^ w ; \ | ||
352 | t09 = b | t05; \ | ||
353 | t10 = ~ b ; \ | ||
354 | x = t08 ^ t09; \ | ||
355 | t12 = t10 | t07; \ | ||
356 | t13 = w | x ; \ | ||
357 | z = t02 ^ t12; \ | ||
358 | t15 = t02 ^ t13; \ | ||
359 | t16 = b ^ d ; \ | ||
360 | y = t16 ^ t15; \ | ||
361 | } | ||
362 | |||
363 | #define SBOX6(a, b, c, d, w, x, y, z) \ | ||
364 | { \ | ||
365 | register unsigned long t02, t03, t04, t05, t07, t08, t09, t10; \ | ||
366 | register unsigned long t11, t12, t13, t15, t17, t18, t01; \ | ||
367 | t01 = a & d ; \ | ||
368 | t02 = b ^ c ; \ | ||
369 | t03 = a ^ d ; \ | ||
370 | t04 = t01 ^ t02; \ | ||
371 | t05 = b | c ; \ | ||
372 | x = ~ t04; \ | ||
373 | t07 = t03 & t05; \ | ||
374 | t08 = b & x ; \ | ||
375 | t09 = a | c ; \ | ||
376 | t10 = t07 ^ t08; \ | ||
377 | t11 = b | d ; \ | ||
378 | t12 = c ^ t11; \ | ||
379 | t13 = t09 ^ t10; \ | ||
380 | y = ~ t13; \ | ||
381 | t15 = x & t03; \ | ||
382 | z = t12 ^ t07; \ | ||
383 | t17 = a ^ b ; \ | ||
384 | t18 = y ^ t15; \ | ||
385 | w = t17 ^ t18; \ | ||
386 | } | ||
387 | |||
388 | #define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \ | ||
389 | { \ | ||
390 | register unsigned long t02, t03, t04, t05, t06, t07, t08, t09; \ | ||
391 | register unsigned long t12, t13, t14, t15, t16, t17, t01; \ | ||
392 | t01 = a ^ c ; \ | ||
393 | t02 = ~ c ; \ | ||
394 | t03 = b & t01; \ | ||
395 | t04 = b | t02; \ | ||
396 | t05 = d | t03; \ | ||
397 | t06 = b ^ d ; \ | ||
398 | t07 = a & t04; \ | ||
399 | t08 = a | t02; \ | ||
400 | t09 = t07 ^ t05; \ | ||
401 | x = t06 ^ t08; \ | ||
402 | w = ~ t09; \ | ||
403 | t12 = b & w ; \ | ||
404 | t13 = t01 & t05; \ | ||
405 | t14 = t01 ^ t12; \ | ||
406 | t15 = t07 ^ t13; \ | ||
407 | t16 = d | t02; \ | ||
408 | t17 = a ^ x ; \ | ||
409 | z = t17 ^ t15; \ | ||
410 | y = t16 ^ t14; \ | ||
411 | } | ||
412 | |||
413 | #define SBOX7(a, b, c, d, w, x, y, z) \ | ||
414 | { \ | ||
415 | register unsigned long t02, t03, t04, t05, t06, t08, t09, t10; \ | ||
416 | register unsigned long t11, t13, t14, t15, t16, t17, t01; \ | ||
417 | t01 = a & c ; \ | ||
418 | t02 = ~ d ; \ | ||
419 | t03 = a & t02; \ | ||
420 | t04 = b | t01; \ | ||
421 | t05 = a & b ; \ | ||
422 | t06 = c ^ t04; \ | ||
423 | z = t03 ^ t06; \ | ||
424 | t08 = c | z ; \ | ||
425 | t09 = d | t05; \ | ||
426 | t10 = a ^ t08; \ | ||
427 | t11 = t04 & z ; \ | ||
428 | x = t09 ^ t10; \ | ||
429 | t13 = b ^ x ; \ | ||
430 | t14 = t01 ^ x ; \ | ||
431 | t15 = c ^ t05; \ | ||
432 | t16 = t11 | t13; \ | ||
433 | t17 = t02 | t14; \ | ||
434 | w = t15 ^ t17; \ | ||
435 | y = a ^ t16; \ | ||
436 | } | ||
437 | |||
438 | #define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \ | ||
439 | { \ | ||
440 | register unsigned long t02, t03, t04, t06, t07, t08, t09; \ | ||
441 | register unsigned long t10, t11, t13, t14, t15, t16, t01; \ | ||
442 | t01 = a & b ; \ | ||
443 | t02 = a | b ; \ | ||
444 | t03 = c | t01; \ | ||
445 | t04 = d & t02; \ | ||
446 | z = t03 ^ t04; \ | ||
447 | t06 = b ^ t04; \ | ||
448 | t07 = d ^ z ; \ | ||
449 | t08 = ~ t07; \ | ||
450 | t09 = t06 | t08; \ | ||
451 | t10 = b ^ d ; \ | ||
452 | t11 = a | d ; \ | ||
453 | x = a ^ t09; \ | ||
454 | t13 = c ^ t06; \ | ||
455 | t14 = c & t11; \ | ||
456 | t15 = d | x ; \ | ||
457 | t16 = t01 | t10; \ | ||
458 | w = t13 ^ t15; \ | ||
459 | y = t14 ^ t16; \ | ||
460 | } | ||
461 | |||
462 | /* XOR BLOCK1 into BLOCK0. */ | ||
463 | #define BLOCK_XOR(block0, block1) \ | ||
464 | { \ | ||
465 | block0[0] ^= block1[0]; \ | ||
466 | block0[1] ^= block1[1]; \ | ||
467 | block0[2] ^= block1[2]; \ | ||
468 | block0[3] ^= block1[3]; \ | ||
469 | } | ||
470 | |||
471 | /* Copy BLOCK_SRC to BLOCK_DST. */ | ||
472 | #define BLOCK_COPY(block_dst, block_src) \ | ||
473 | { \ | ||
474 | block_dst[0] = block_src[0]; \ | ||
475 | block_dst[1] = block_src[1]; \ | ||
476 | block_dst[2] = block_src[2]; \ | ||
477 | block_dst[3] = block_src[3]; \ | ||
478 | } | ||
479 | |||
480 | /* Apply SBOX number WHICH to to the block found in ARRAY0 at index | ||
481 | INDEX, writing the output to the block found in ARRAY1 at index | ||
482 | INDEX. */ | ||
483 | #define SBOX(which, array0, array1, index) \ | ||
484 | SBOX##which (array0[index + 0], array0[index + 1], \ | ||
485 | array0[index + 2], array0[index + 3], \ | ||
486 | array1[index + 0], array1[index + 1], \ | ||
487 | array1[index + 2], array1[index + 3]); | ||
488 | |||
489 | /* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at | ||
490 | index INDEX, writing the output to the block found in ARRAY1 at | ||
491 | index INDEX. */ | ||
492 | #define SBOX_INVERSE(which, array0, array1, index) \ | ||
493 | SBOX##which##_INVERSE (array0[index + 0], array0[index + 1], \ | ||
494 | array0[index + 2], array0[index + 3], \ | ||
495 | array1[index + 0], array1[index + 1], \ | ||
496 | array1[index + 2], array1[index + 3]); | ||
497 | |||
498 | /* Apply the linear transformation to BLOCK. */ | ||
499 | #define LINEAR_TRANSFORMATION(block) \ | ||
500 | { \ | ||
501 | block[0] = rol (block[0], 13); \ | ||
502 | block[2] = rol (block[2], 3); \ | ||
503 | block[1] = block[1] ^ block[0] ^ block[2]; \ | ||
504 | block[3] = block[3] ^ block[2] ^ (block[0] << 3); \ | ||
505 | block[1] = rol (block[1], 1); \ | ||
506 | block[3] = rol (block[3], 7); \ | ||
507 | block[0] = block[0] ^ block[1] ^ block[3]; \ | ||
508 | block[2] = block[2] ^ block[3] ^ (block[1] << 7); \ | ||
509 | block[0] = rol (block[0], 5); \ | ||
510 | block[2] = rol (block[2], 22); \ | ||
511 | } | ||
512 | |||
513 | /* Apply the inverse linear transformation to BLOCK. */ | ||
514 | #define LINEAR_TRANSFORMATION_INVERSE(block) \ | ||
515 | { \ | ||
516 | block[2] = ror (block[2], 22); \ | ||
517 | block[0] = ror (block[0] , 5); \ | ||
518 | block[2] = block[2] ^ block[3] ^ (block[1] << 7); \ | ||
519 | block[0] = block[0] ^ block[1] ^ block[3]; \ | ||
520 | block[3] = ror (block[3], 7); \ | ||
521 | block[1] = ror (block[1], 1); \ | ||
522 | block[3] = block[3] ^ block[2] ^ (block[0] << 3); \ | ||
523 | block[1] = block[1] ^ block[0] ^ block[2]; \ | ||
524 | block[2] = ror (block[2], 3); \ | ||
525 | block[0] = ror (block[0], 13); \ | ||
526 | } | ||
527 | |||
528 | /* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the | ||
529 | subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage. | ||
530 | This macro increments `round'. */ | ||
531 | #define ROUND(which, subkeys, block, block_tmp) \ | ||
532 | { \ | ||
533 | BLOCK_XOR (block, subkeys[round]); \ | ||
534 | round++; \ | ||
535 | SBOX (which, block, block_tmp, 0); \ | ||
536 | LINEAR_TRANSFORMATION (block_tmp); \ | ||
537 | BLOCK_COPY (block, block_tmp); \ | ||
538 | } | ||
539 | |||
540 | /* Apply the last Serpent round to BLOCK, using the SBOX number WHICH | ||
541 | and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary | ||
542 | storage. The result will be stored in BLOCK_TMP. This macro | ||
543 | increments `round'. */ | ||
544 | #define ROUND_LAST(which, subkeys, block, block_tmp) \ | ||
545 | { \ | ||
546 | BLOCK_XOR (block, subkeys[round]); \ | ||
547 | round++; \ | ||
548 | SBOX (which, block, block_tmp, 0); \ | ||
549 | BLOCK_XOR (block_tmp, subkeys[round]); \ | ||
550 | round++; \ | ||
551 | } | ||
552 | |||
553 | /* Apply an inverse Serpent round to BLOCK, using the SBOX number | ||
554 | WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as | ||
555 | temporary storage. This macro increments `round'. */ | ||
556 | #define ROUND_INVERSE(which, subkey, block, block_tmp) \ | ||
557 | { \ | ||
558 | LINEAR_TRANSFORMATION_INVERSE (block); \ | ||
559 | SBOX_INVERSE (which, block, block_tmp, 0); \ | ||
560 | BLOCK_XOR (block_tmp, subkey[round]); \ | ||
561 | round--; \ | ||
562 | BLOCK_COPY (block, block_tmp); \ | ||
563 | } | ||
564 | |||
565 | /* Apply the first Serpent round to BLOCK, using the SBOX number WHICH | ||
566 | and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary | ||
567 | storage. The result will be stored in BLOCK_TMP. This macro | ||
568 | increments `round'. */ | ||
569 | #define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \ | ||
570 | { \ | ||
571 | BLOCK_XOR (block, subkeys[round]); \ | ||
572 | round--; \ | ||
573 | SBOX_INVERSE (which, block, block_tmp, 0); \ | ||
574 | BLOCK_XOR (block_tmp, subkeys[round]); \ | ||
575 | round--; \ | ||
576 | } | ||
577 | |||
578 | /* Convert the user provided key KEY of KEY_LENGTH bytes into the | ||
579 | internally used format. */ | ||
580 | static void | ||
581 | serpent_key_prepare (const byte_t *key, unsigned int key_length, | ||
582 | serpent_key_t key_prepared) | ||
583 | { | ||
584 | int i; | ||
585 | |||
586 | /* Copy key. */ | ||
587 | for (i = 0; i < key_length / 4; i++) | ||
588 | { | ||
589 | #ifdef WORDS_BIGENDIAN | ||
590 | key_prepared[i] = byte_swap_32 (((u32_t *) key)[i]); | ||
591 | #else | ||
592 | key_prepared[i] = ((u32_t *) key)[i]; | ||
593 | #endif | ||
594 | } | ||
595 | |||
596 | if (i < 8) | ||
597 | { | ||
598 | /* Key must be padded according to the Serpent | ||
599 | specification. */ | ||
600 | key_prepared[i] = 0x00000001; | ||
601 | |||
602 | for (i++; i < 8; i++) | ||
603 | key_prepared[i] = 0; | ||
604 | } | ||
605 | } | ||
606 | |||
607 | /* Derive the 33 subkeys from KEY and store them in SUBKEYS. */ | ||
608 | static void | ||
609 | serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys) | ||
610 | { | ||
611 | u32_t w_real[140]; /* The `prekey'. */ | ||
612 | u32_t k[132]; | ||
613 | u32_t *w = &w_real[8]; | ||
614 | int i, j; | ||
615 | |||
616 | /* Initialize with key values. */ | ||
617 | for (i = 0; i < 8; i++) | ||
618 | w[i - 8] = key[i]; | ||
619 | |||
620 | /* Expand to intermediate key using the affine recurrence. */ | ||
621 | for (i = 0; i < 132; i++) | ||
622 | w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11); | ||
623 | |||
624 | /* Calculate subkeys via S-Boxes, in bitslice mode. */ | ||
625 | SBOX (3, w, k, 0); | ||
626 | SBOX (2, w, k, 4); | ||
627 | SBOX (1, w, k, 8); | ||
628 | SBOX (0, w, k, 12); | ||
629 | SBOX (7, w, k, 16); | ||
630 | SBOX (6, w, k, 20); | ||
631 | SBOX (5, w, k, 24); | ||
632 | SBOX (4, w, k, 28); | ||
633 | SBOX (3, w, k, 32); | ||
634 | SBOX (2, w, k, 36); | ||
635 | SBOX (1, w, k, 40); | ||
636 | SBOX (0, w, k, 44); | ||
637 | SBOX (7, w, k, 48); | ||
638 | SBOX (6, w, k, 52); | ||
639 | SBOX (5, w, k, 56); | ||
640 | SBOX (4, w, k, 60); | ||
641 | SBOX (3, w, k, 64); | ||
642 | SBOX (2, w, k, 68); | ||
643 | SBOX (1, w, k, 72); | ||
644 | SBOX (0, w, k, 76); | ||
645 | SBOX (7, w, k, 80); | ||
646 | SBOX (6, w, k, 84); | ||
647 | SBOX (5, w, k, 88); | ||
648 | SBOX (4, w, k, 92); | ||
649 | SBOX (3, w, k, 96); | ||
650 | SBOX (2, w, k, 100); | ||
651 | SBOX (1, w, k, 104); | ||
652 | SBOX (0, w, k, 108); | ||
653 | SBOX (7, w, k, 112); | ||
654 | SBOX (6, w, k, 116); | ||
655 | SBOX (5, w, k, 120); | ||
656 | SBOX (4, w, k, 124); | ||
657 | SBOX (3, w, k, 128); | ||
658 | |||
659 | /* Renumber subkeys. */ | ||
660 | for (i = 0; i < ROUNDS + 1; i++) | ||
661 | for (j = 0; j < 4; j++) | ||
662 | subkeys[i][j] = k[4 * i + j]; | ||
663 | } | ||
664 | |||
665 | /* Initialize CONTEXT with the key KEY of KEY_LENGTH bits. */ | ||
666 | static void | ||
667 | serpent_setkey_internal (serpent_context_t *context, | ||
668 | const byte_t *key, unsigned int key_length) | ||
669 | { | ||
670 | serpent_key_t key_prepared; | ||
671 | |||
672 | serpent_key_prepare (key, key_length, key_prepared); | ||
673 | serpent_subkeys_generate (key_prepared, context->keys); | ||
674 | _gcry_burn_stack (272 * sizeof (u32_t)); | ||
675 | } | ||
676 | |||
677 | /* Initialize CTX with the key KEY of KEY_LENGTH bytes. */ | ||
678 | static gcry_err_code_t | ||
679 | serpent_setkey (void *ctx, | ||
680 | const byte_t *key, unsigned int key_length) | ||
681 | { | ||
682 | serpent_context_t *context = ctx; | ||
683 | static const char *serpent_test_ret; | ||
684 | static int serpent_init_done; | ||
685 | gcry_err_code_t ret = GPG_ERR_NO_ERROR; | ||
686 | |||
687 | if (! serpent_init_done) | ||
688 | { | ||
689 | /* Execute a self-test the first time, Serpent is used. */ | ||
690 | static const char *serpent_test (void); | ||
691 | |||
692 | serpent_test_ret = serpent_test (); | ||
693 | if (serpent_test_ret) | ||
694 | log_error ("Serpent test failure: %s\n", serpent_test_ret); | ||
695 | serpent_init_done = 1; | ||
696 | } | ||
697 | |||
698 | if (serpent_test_ret) | ||
699 | ret = GPG_ERR_SELFTEST_FAILED; | ||
700 | else | ||
701 | { | ||
702 | serpent_setkey_internal (context, key, key_length); | ||
703 | _gcry_burn_stack (sizeof (serpent_key_t)); | ||
704 | } | ||
705 | |||
706 | return ret; | ||
707 | } | ||
708 | |||
709 | static void | ||
710 | serpent_encrypt_internal (serpent_context_t *context, | ||
711 | const serpent_block_t input, serpent_block_t output) | ||
712 | { | ||
713 | serpent_block_t b, b_next; | ||
714 | int round = 0; | ||
715 | |||
716 | #ifdef WORDS_BIGENDIAN | ||
717 | b[0] = byte_swap_32 (input[0]); | ||
718 | b[1] = byte_swap_32 (input[1]); | ||
719 | b[2] = byte_swap_32 (input[2]); | ||
720 | b[3] = byte_swap_32 (input[3]); | ||
721 | #else | ||
722 | b[0] = input[0]; | ||
723 | b[1] = input[1]; | ||
724 | b[2] = input[2]; | ||
725 | b[3] = input[3]; | ||
726 | #endif | ||
727 | |||
728 | ROUND (0, context->keys, b, b_next); | ||
729 | ROUND (1, context->keys, b, b_next); | ||
730 | ROUND (2, context->keys, b, b_next); | ||
731 | ROUND (3, context->keys, b, b_next); | ||
732 | ROUND (4, context->keys, b, b_next); | ||
733 | ROUND (5, context->keys, b, b_next); | ||
734 | ROUND (6, context->keys, b, b_next); | ||
735 | ROUND (7, context->keys, b, b_next); | ||
736 | ROUND (0, context->keys, b, b_next); | ||
737 | ROUND (1, context->keys, b, b_next); | ||
738 | ROUND (2, context->keys, b, b_next); | ||
739 | ROUND (3, context->keys, b, b_next); | ||
740 | ROUND (4, context->keys, b, b_next); | ||
741 | ROUND (5, context->keys, b, b_next); | ||
742 | ROUND (6, context->keys, b, b_next); | ||
743 | ROUND (7, context->keys, b, b_next); | ||
744 | ROUND (0, context->keys, b, b_next); | ||
745 | ROUND (1, context->keys, b, b_next); | ||
746 | ROUND (2, context->keys, b, b_next); | ||
747 | ROUND (3, context->keys, b, b_next); | ||
748 | ROUND (4, context->keys, b, b_next); | ||
749 | ROUND (5, context->keys, b, b_next); | ||
750 | ROUND (6, context->keys, b, b_next); | ||
751 | ROUND (7, context->keys, b, b_next); | ||
752 | ROUND (0, context->keys, b, b_next); | ||
753 | ROUND (1, context->keys, b, b_next); | ||
754 | ROUND (2, context->keys, b, b_next); | ||
755 | ROUND (3, context->keys, b, b_next); | ||
756 | ROUND (4, context->keys, b, b_next); | ||
757 | ROUND (5, context->keys, b, b_next); | ||
758 | ROUND (6, context->keys, b, b_next); | ||
759 | |||
760 | ROUND_LAST (7, context->keys, b, b_next); | ||
761 | |||
762 | #ifdef WORDS_BIGENDIAN | ||
763 | output[0] = byte_swap_32 (b_next[0]); | ||
764 | output[1] = byte_swap_32 (b_next[1]); | ||
765 | output[2] = byte_swap_32 (b_next[2]); | ||
766 | output[3] = byte_swap_32 (b_next[3]); | ||
767 | #else | ||
768 | output[0] = b_next[0]; | ||
769 | output[1] = b_next[1]; | ||
770 | output[2] = b_next[2]; | ||
771 | output[3] = b_next[3]; | ||
772 | #endif | ||
773 | } | ||
774 | |||
775 | static void | ||
776 | serpent_decrypt_internal (serpent_context_t *context, | ||
777 | const serpent_block_t input, serpent_block_t output) | ||
778 | { | ||
779 | serpent_block_t b, b_next; | ||
780 | int round = ROUNDS; | ||
781 | |||
782 | #ifdef WORDS_BIGENDIAN | ||
783 | b_next[0] = byte_swap_32 (input[0]); | ||
784 | b_next[1] = byte_swap_32 (input[1]); | ||
785 | b_next[2] = byte_swap_32 (input[2]); | ||
786 | b_next[3] = byte_swap_32 (input[3]); | ||
787 | #else | ||
788 | b_next[0] = input[0]; | ||
789 | b_next[1] = input[1]; | ||
790 | b_next[2] = input[2]; | ||
791 | b_next[3] = input[3]; | ||
792 | #endif | ||
793 | |||
794 | ROUND_FIRST_INVERSE (7, context->keys, b_next, b); | ||
795 | |||
796 | ROUND_INVERSE (6, context->keys, b, b_next); | ||
797 | ROUND_INVERSE (5, context->keys, b, b_next); | ||
798 | ROUND_INVERSE (4, context->keys, b, b_next); | ||
799 | ROUND_INVERSE (3, context->keys, b, b_next); | ||
800 | ROUND_INVERSE (2, context->keys, b, b_next); | ||
801 | ROUND_INVERSE (1, context->keys, b, b_next); | ||
802 | ROUND_INVERSE (0, context->keys, b, b_next); | ||
803 | ROUND_INVERSE (7, context->keys, b, b_next); | ||
804 | ROUND_INVERSE (6, context->keys, b, b_next); | ||
805 | ROUND_INVERSE (5, context->keys, b, b_next); | ||
806 | ROUND_INVERSE (4, context->keys, b, b_next); | ||
807 | ROUND_INVERSE (3, context->keys, b, b_next); | ||
808 | ROUND_INVERSE (2, context->keys, b, b_next); | ||
809 | ROUND_INVERSE (1, context->keys, b, b_next); | ||
810 | ROUND_INVERSE (0, context->keys, b, b_next); | ||
811 | ROUND_INVERSE (7, context->keys, b, b_next); | ||
812 | ROUND_INVERSE (6, context->keys, b, b_next); | ||
813 | ROUND_INVERSE (5, context->keys, b, b_next); | ||
814 | ROUND_INVERSE (4, context->keys, b, b_next); | ||
815 | ROUND_INVERSE (3, context->keys, b, b_next); | ||
816 | ROUND_INVERSE (2, context->keys, b, b_next); | ||
817 | ROUND_INVERSE (1, context->keys, b, b_next); | ||
818 | ROUND_INVERSE (0, context->keys, b, b_next); | ||
819 | ROUND_INVERSE (7, context->keys, b, b_next); | ||
820 | ROUND_INVERSE (6, context->keys, b, b_next); | ||
821 | ROUND_INVERSE (5, context->keys, b, b_next); | ||
822 | ROUND_INVERSE (4, context->keys, b, b_next); | ||
823 | ROUND_INVERSE (3, context->keys, b, b_next); | ||
824 | ROUND_INVERSE (2, context->keys, b, b_next); | ||
825 | ROUND_INVERSE (1, context->keys, b, b_next); | ||
826 | ROUND_INVERSE (0, context->keys, b, b_next); | ||
827 | |||
828 | |||
829 | #ifdef WORDS_BIGENDIAN | ||
830 | output[0] = byte_swap_32 (b_next[0]); | ||
831 | output[1] = byte_swap_32 (b_next[1]); | ||
832 | output[2] = byte_swap_32 (b_next[2]); | ||
833 | output[3] = byte_swap_32 (b_next[3]); | ||
834 | #else | ||
835 | output[0] = b_next[0]; | ||
836 | output[1] = b_next[1]; | ||
837 | output[2] = b_next[2]; | ||
838 | output[3] = b_next[3]; | ||
839 | #endif | ||
840 | } | ||
841 | |||
842 | static void | ||
843 | serpent_encrypt (void *ctx, byte_t *buffer_out, const byte_t *buffer_in) | ||
844 | { | ||
845 | serpent_context_t *context = ctx; | ||
846 | |||
847 | serpent_encrypt_internal (context, | ||
848 | (const u32_t *) buffer_in, (u32_t *) buffer_out); | ||
849 | _gcry_burn_stack (2 * sizeof (serpent_block_t)); | ||
850 | } | ||
851 | |||
852 | static void | ||
853 | serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in) | ||
854 | { | ||
855 | serpent_context_t *context = ctx; | ||
856 | |||
857 | serpent_decrypt_internal (context, | ||
858 | (const u32_t *) buffer_in, | ||
859 | (u32_t *) buffer_out); | ||
860 | _gcry_burn_stack (2 * sizeof (serpent_block_t)); | ||
861 | } | ||
862 | |||
863 | |||
864 | |||
865 | /* Serpent test. */ | ||
866 | |||
867 | static const char * | ||
868 | serpent_test (void) | ||
869 | { | ||
870 | serpent_context_t context; | ||
871 | unsigned char scratch[16]; | ||
872 | unsigned int i; | ||
873 | |||
874 | static struct test | ||
875 | { | ||
876 | int key_length; | ||
877 | unsigned char key[32]; | ||
878 | unsigned char text_plain[16]; | ||
879 | unsigned char text_cipher[16]; | ||
880 | } test_data[] = | ||
881 | { | ||
882 | { | ||
883 | 16, | ||
884 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", | ||
885 | "\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E", | ||
886 | "\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D" | ||
887 | }, | ||
888 | { | ||
889 | 24, | ||
890 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | ||
891 | "\x00\x00\x00\x00\x00\x00\x00\x00", | ||
892 | "\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E", | ||
893 | "\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9" | ||
894 | }, | ||
895 | { | ||
896 | 32, | ||
897 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | ||
898 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", | ||
899 | "\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E", | ||
900 | "\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B" | ||
901 | }, | ||
902 | { | ||
903 | 32, | ||
904 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | ||
905 | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", | ||
906 | "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00", | ||
907 | "\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C" | ||
908 | }, | ||
909 | { | ||
910 | 0 | ||
911 | }, | ||
912 | }; | ||
913 | |||
914 | for (i = 0; test_data[i].key_length; i++) | ||
915 | { | ||
916 | serpent_setkey_internal (&context, test_data[i].key, | ||
917 | test_data[i].key_length); | ||
918 | serpent_encrypt_internal (&context, | ||
919 | (const u32_t *) test_data[i].text_plain, | ||
920 | (u32_t *) scratch); | ||
921 | |||
922 | if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t))) | ||
923 | switch (test_data[i].key_length) | ||
924 | { | ||
925 | case 16: | ||
926 | return "Serpent-128 test encryption failed."; | ||
927 | case 24: | ||
928 | return "Serpent-192 test encryption failed."; | ||
929 | case 32: | ||
930 | return "Serpent-256 test encryption failed."; | ||
931 | } | ||
932 | |||
933 | serpent_decrypt_internal (&context, | ||
934 | (const u32_t *) test_data[i].text_cipher, | ||
935 | (u32_t *) scratch); | ||
936 | if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t))) | ||
937 | switch (test_data[i].key_length) | ||
938 | { | ||
939 | case 16: | ||
940 | return "Serpent-128 test decryption failed."; | ||
941 | case 24: | ||
942 | return "Serpent-192 test decryption failed."; | ||
943 | case 32: | ||
944 | return "Serpent-256 test decryption failed."; | ||
945 | } | ||
946 | } | ||
947 | |||
948 | return NULL; | ||
949 | } | ||
950 | |||
951 | |||
952 | |||
953 | /* "SERPENT" is an alias for "SERPENT128". */ | ||
954 | static const char *cipher_spec_serpent128_aliases[] = | ||
955 | { | ||
956 | "SERPENT", | ||
957 | NULL, | ||
958 | }; | ||
959 | |||
960 | gcry_cipher_spec_t _gcry_cipher_spec_serpent128 = | ||
961 | { | ||
962 | "SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128, | ||
963 | sizeof (serpent_context_t), | ||
964 | serpent_setkey, serpent_encrypt, serpent_decrypt, | ||
965 | }; | ||
966 | |||
967 | gcry_cipher_spec_t _gcry_cipher_spec_serpent192 = | ||
968 | { | ||
969 | "SERPENT192", NULL, NULL, 16, 192, | ||
970 | sizeof (serpent_context_t), | ||
971 | serpent_setkey, serpent_encrypt, serpent_decrypt, | ||
972 | }; | ||
973 | |||
974 | gcry_cipher_spec_t _gcry_cipher_spec_serpent256 = | ||
975 | { | ||
976 | "SERPENT256", NULL, NULL, 16, 256, | ||
977 | sizeof (serpent_context_t), | ||
978 | serpent_setkey, serpent_encrypt, serpent_decrypt, | ||
979 | }; | ||