3 The serpent block cipher.
5 For more details on this algorithm, see the Serpent website at
6 http://www.cl.cam.ac.uk/~rja14/serpent.html
8 Copyright (C) 2011 Niels Möller
9 Copyright (C) 2010, 2011 Simon Josefsson
10 Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
12 This file is part of GNU Nettle.
14 GNU Nettle is free software: you can redistribute it and/or
15 modify it under the terms of either:
17 * the GNU Lesser General Public License as published by the Free
18 Software Foundation; either version 3 of the License, or (at your
19 option) any later version.
23 * the GNU General Public License as published by the Free
24 Software Foundation; either version 2 of the License, or (at your
25 option) any later version.
27 or both in parallel, as here.
29 GNU Nettle is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32 General Public License for more details.
34 You should have received copies of the GNU General Public License and
35 the GNU Lesser General Public License along with this program. If
36 not, see http://www.gnu.org/licenses/.
39 /* This file is derived from cipher/serpent.c in Libgcrypt v1.4.6.
40 The adaption to Nettle was made by Simon Josefsson on 2010-12-07
41 with final touches on 2011-05-30. Changes include replacing
42 libgcrypt with nettle in the license template, renaming
43 serpent_context to serpent_ctx, renaming u32 to uint32_t, removing
44 libgcrypt stubs and selftests, modifying entry function prototypes,
45 using FOR_BLOCKS to iterate through data in encrypt/decrypt, using
46 LE_READ_UINT32 and LE_WRITE_UINT32 to access data in
47 encrypt/decrypt, and running indent on the code. */
59 #include "serpent-internal.h"
61 /* These are the S-Boxes of Serpent. They are copied from Serpents
62 reference implementation (the optimized one, contained in
63 `floppy2') and are therefore:
65 Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen.
67 To quote the Serpent homepage
68 (http://www.cl.cam.ac.uk/~rja14/serpent.html):
70 "Serpent is now completely in the public domain, and we impose no
71 restrictions on its use. This was announced on the 21st August at
72 the First AES Candidate Conference. The optimised implementations
73 in the submission package are now under the GNU PUBLIC LICENSE
74 (GPL), although some comments in the code still say otherwise. You
75 are welcome to use Serpent for any application." */
77 /* S0: 3 8 15 1 10 6 5 11 14 13 4 2 7 0 9 12 */
78 /* Could easily let y0, y1 overlap with x0, x1, and possibly also x2 and y2 */
79 #define SBOX0(x0, x1, x2, x3, y0, y1, y2, y3) \
101 /* FIXME: Arrange for some overlap between inputs and outputs? */
102 /* S1: 15 12 2 7 9 0 5 10 1 11 14 8 6 13 3 4 */
103 /* Original single-assignment form:
124 #define SBOX1(x0, x1, x2, x3, y0, y1, y2, y3) \
146 /* FIXME: Arrange for some overlap between inputs and outputs? */
147 /* S2: 8 6 7 9 3 12 10 15 13 1 14 4 0 11 5 2 */
148 #define SBOX2(x0, x1, x2, x3, y0, y1, y2, y3) \
168 /* S3: 0 15 11 8 12 9 6 3 13 1 2 4 10 7 5 14 */
169 /* Original single-assignment form:
190 #define SBOX3(x0, x1, x2, x3, y0, y1, y2, y3) \
213 /* S4: 1 15 8 3 12 0 11 6 2 5 4 10 9 14 7 13 */
214 /* Original single-assignment form:
235 #define SBOX4(x0, x1, x2, x3, y0, y1, y2, y3) \
258 /* S5: 15 5 2 11 4 10 9 12 0 3 14 8 13 6 7 1 */
259 /* Original single-assignment form:
278 #define SBOX5(x0, x1, x2, x3, y0, y1, y2, y3) \
299 /* S6: 7 2 12 5 8 4 6 11 14 9 1 15 13 3 10 0 */
300 /* Original single-assignment form:
321 #define SBOX6(x0, x1, x2, x3, y0, y1, y2, y3) \
344 /* S7: 1 13 15 0 14 8 2 11 7 4 12 10 9 3 5 6 */
345 /* Original single-assignment form:
366 /* It appears impossible to do this with only 8 registers. We
367 recompute t02, and t04 (if we have spare registers, hopefully the
368 compiler can recognize them as common subexpressions). */
369 #define SBOX7(x0, x1, x2, x3, y0, y1, y2, y3) \
372 y3 = x1 | y0; /* t04 */ \
374 y1 = ~x3; /* t02 */ \
383 y2 = x1 | y0; /* t04 */ \
389 x3 = ~x3; /* t02 */ \
394 /* In-place linear transformation. */
395 #define LINEAR_TRANSFORMATION(x0,x1,x2,x3) \
397 x0 = ROTL32 (13, x0); \
398 x2 = ROTL32 (3, x2); \
400 x3 = x3 ^ x2 ^ (x0 << 3); \
401 x1 = ROTL32 (1, x1); \
402 x3 = ROTL32 (7, x3); \
404 x2 = x2 ^ x3 ^ (x1 << 7); \
405 x0 = ROTL32 (5, x0); \
406 x2 = ROTL32 (22, x2); \
409 /* Round inputs are x0,x1,x2,x3 (destroyed), and round outputs are
411 #define ROUND(which, subkey, x0,x1,x2,x3, y0,y1,y2,y3) \
413 KEYXOR(x0,x1,x2,x3, subkey); \
414 SBOX##which(x0,x1,x2,x3, y0,y1,y2,y3); \
415 LINEAR_TRANSFORMATION(y0,y1,y2,y3); \
418 #if HAVE_NATIVE_64_BIT
420 #define LINEAR_TRANSFORMATION64(x0,x1,x2,x3) \
422 x0 = DROTL32 (13, x0); \
423 x2 = DROTL32 (3, x2); \
425 x3 = x3 ^ x2 ^ DRSHIFT32(3, x0); \
426 x1 = DROTL32 (1, x1); \
427 x3 = DROTL32 (7, x3); \
429 x2 = x2 ^ x3 ^ DRSHIFT32(7, x1); \
430 x0 = DROTL32 (5, x0); \
431 x2 = DROTL32 (22, x2); \
434 #define ROUND64(which, subkey, x0,x1,x2,x3, y0,y1,y2,y3) \
436 KEYXOR64(x0,x1,x2,x3, subkey); \
437 SBOX##which(x0,x1,x2,x3, y0,y1,y2,y3); \
438 LINEAR_TRANSFORMATION64(y0,y1,y2,y3); \
441 #endif /* HAVE_NATIVE_64_BIT */
444 serpent_encrypt (const struct serpent_ctx *ctx,
445 size_t length, uint8_t * dst, const uint8_t * src)
447 assert( !(length % SERPENT_BLOCK_SIZE));
449 #if HAVE_NATIVE_64_BIT
450 if (length & SERPENT_BLOCK_SIZE)
452 while (length >= SERPENT_BLOCK_SIZE)
455 uint32_t x0,x1,x2,x3, y0,y1,y2,y3;
458 x0 = LE_READ_UINT32 (src);
459 x1 = LE_READ_UINT32 (src + 4);
460 x2 = LE_READ_UINT32 (src + 8);
461 x3 = LE_READ_UINT32 (src + 12);
463 for (k = 0; ; k += 8)
465 ROUND (0, ctx->keys[k+0], x0,x1,x2,x3, y0,y1,y2,y3);
466 ROUND (1, ctx->keys[k+1], y0,y1,y2,y3, x0,x1,x2,x3);
467 ROUND (2, ctx->keys[k+2], x0,x1,x2,x3, y0,y1,y2,y3);
468 ROUND (3, ctx->keys[k+3], y0,y1,y2,y3, x0,x1,x2,x3);
469 ROUND (4, ctx->keys[k+4], x0,x1,x2,x3, y0,y1,y2,y3);
470 ROUND (5, ctx->keys[k+5], y0,y1,y2,y3, x0,x1,x2,x3);
471 ROUND (6, ctx->keys[k+6], x0,x1,x2,x3, y0,y1,y2,y3);
474 ROUND (7, ctx->keys[k+7], y0,y1,y2,y3, x0,x1,x2,x3);
477 /* Special final round, using two subkeys. */
478 KEYXOR (y0,y1,y2,y3, ctx->keys[31]);
479 SBOX7 (y0,y1,y2,y3, x0,x1,x2,x3);
480 KEYXOR (x0,x1,x2,x3, ctx->keys[32]);
482 LE_WRITE_UINT32 (dst, x0);
483 LE_WRITE_UINT32 (dst + 4, x1);
484 LE_WRITE_UINT32 (dst + 8, x2);
485 LE_WRITE_UINT32 (dst + 12, x3);
487 src += SERPENT_BLOCK_SIZE;
488 dst += SERPENT_BLOCK_SIZE;
489 length -= SERPENT_BLOCK_SIZE;
491 #if HAVE_NATIVE_64_BIT
492 FOR_BLOCKS(length, dst, src, 2*SERPENT_BLOCK_SIZE)
494 uint64_t x0,x1,x2,x3, y0,y1,y2,y3;
497 x0 = LE_READ_UINT32 (src);
498 x1 = LE_READ_UINT32 (src + 4);
499 x2 = LE_READ_UINT32 (src + 8);
500 x3 = LE_READ_UINT32 (src + 12);
502 x0 <<= 32; x0 |= LE_READ_UINT32 (src + 16);
503 x1 <<= 32; x1 |= LE_READ_UINT32 (src + 20);
504 x2 <<= 32; x2 |= LE_READ_UINT32 (src + 24);
505 x3 <<= 32; x3 |= LE_READ_UINT32 (src + 28);
507 for (k = 0; ; k += 8)
509 ROUND64 (0, ctx->keys[k+0], x0,x1,x2,x3, y0,y1,y2,y3);
510 ROUND64 (1, ctx->keys[k+1], y0,y1,y2,y3, x0,x1,x2,x3);
511 ROUND64 (2, ctx->keys[k+2], x0,x1,x2,x3, y0,y1,y2,y3);
512 ROUND64 (3, ctx->keys[k+3], y0,y1,y2,y3, x0,x1,x2,x3);
513 ROUND64 (4, ctx->keys[k+4], x0,x1,x2,x3, y0,y1,y2,y3);
514 ROUND64 (5, ctx->keys[k+5], y0,y1,y2,y3, x0,x1,x2,x3);
515 ROUND64 (6, ctx->keys[k+6], x0,x1,x2,x3, y0,y1,y2,y3);
518 ROUND64 (7, ctx->keys[k+7], y0,y1,y2,y3, x0,x1,x2,x3);
521 /* Special final round, using two subkeys. */
522 KEYXOR64 (y0,y1,y2,y3, ctx->keys[31]);
523 SBOX7 (y0,y1,y2,y3, x0,x1,x2,x3);
524 KEYXOR64 (x0,x1,x2,x3, ctx->keys[32]);
526 LE_WRITE_UINT32 (dst + 16, x0);
527 LE_WRITE_UINT32 (dst + 20, x1);
528 LE_WRITE_UINT32 (dst + 24, x2);
529 LE_WRITE_UINT32 (dst + 28, x3);
530 x0 >>= 32; LE_WRITE_UINT32 (dst, x0);
531 x1 >>= 32; LE_WRITE_UINT32 (dst + 4, x1);
532 x2 >>= 32; LE_WRITE_UINT32 (dst + 8, x2);
533 x3 >>= 32; LE_WRITE_UINT32 (dst + 12, x3);
535 #endif /* HAVE_NATIVE_64_BIT */