-/* serpent.h
+/* serpent.c
*
* The serpent block cipher.
*
/* nettle, low-level cryptographics library
*
- * Copyright (C) 1998, 2000, 2001, 2011,
- * Ross Anderson, Eli Biham, Lars Knudsen, Rafael R. Sevilla, Niels Möller
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* I've modified this code a bit so that it interoperates with lsh
- * properly. 2000-9-5, Rafael R. Sevilla <dido@pacific.net.ph>
+ * Copyright (C) 2010, 2011 Simon Josefsson
+ * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ *
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The nettle library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
*/
-/* NOTE: The copyright notice for the original version of this code
- * said "All rights reserved. This code is freely distributed for AES
- * selection process. No other use is allowed." However, the authors
- * later decided to GPL the code. /nisse */
+/* This file is derived from cipher/serpent.c in Libgcrypt v1.4.6.
+ The adaption to Nettle was made by Simon Josefsson on 2010-12-07
+ with final touches on 2011-05-30. Changes include replacing
+ libgcrypt with nettle in the license template, renaming
+ serpent_context to serpent_ctx, renaming u32 to uint32_t, removing
+ libgcrypt stubs and selftests, modifying entry function prototypes,
+ using FOR_BLOCKS to iterate through data in encrypt/decrypt, using
+ LE_READ_UINT32 and LE_WRITE_UINT32 to access data in
+ encrypt/decrypt, and running indent on the code. */
#if HAVE_CONFIG_H
-# include "config.h"
+#include "config.h"
#endif
#include <assert.h>
#include "serpent.h"
-#include "serpent_sboxes.h"
#include "macros.h"
-void
-serpent_set_key(struct serpent_ctx *ctx,
- unsigned key_size, const uint8_t *key)
-{
- unsigned i, j;
- uint32_t w[132], k[132];
+/* Number of rounds per Serpent encrypt/decrypt operation. */
+#define ROUNDS 32
+
+/* Magic number, used during generating of the subkeys. */
+#define PHI 0x9E3779B9
+
+/* Serpent works on 128 bit blocks. */
+typedef uint32_t serpent_block_t[4];
+
+/* Serpent key, provided by the user. If the original key is shorter
+ than 256 bits, it is padded. */
+typedef uint32_t serpent_key_t[8];
+
+#define byte_swap_32(x) \
+ (0 \
+ | (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \
+ | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+
+#define rol(x,n) ((((uint32_t)(x))<<(n))| \
+ (((uint32_t)(x))>>(32-(n))))
+#define ror(x,n) ((((uint32_t)(x))<<(32-(n)))| \
+ (((uint32_t)(x))>>(n)))
+
+/* These are the S-Boxes of Serpent. They are copied from Serpents
+ reference implementation (the optimized one, contained in
+ `floppy2') and are therefore:
+
+ Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen.
+
+ To quote the Serpent homepage
+ (http://www.cl.cam.ac.uk/~rja14/serpent.html):
+
+ "Serpent is now completely in the public domain, and we impose no
+ restrictions on its use. This was announced on the 21st August at
+ the First AES Candidate Conference. The optimised implementations
+ in the submission package are now under the GNU PUBLIC LICENSE
+ (GPL), although some comments in the code still say otherwise. You
+ are welcome to use Serpent for any application." */
+
+#define SBOX0(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t05, t06, t07, t08, t09; \
+ uint32_t t11, t12, t13, t14, t15, t17, t01; \
+ t01 = b ^ c ; \
+ t02 = a | d ; \
+ t03 = a ^ b ; \
+ z = t02 ^ t01; \
+ t05 = c | z ; \
+ t06 = a ^ d ; \
+ t07 = b | c ; \
+ t08 = d & t05; \
+ t09 = t03 & t07; \
+ y = t09 ^ t08; \
+ t11 = t09 & y ; \
+ t12 = c ^ d ; \
+ t13 = t07 ^ t11; \
+ t14 = b & t06; \
+ t15 = t06 ^ t13; \
+ w = ~ t15; \
+ t17 = w ^ t14; \
+ x = t12 ^ t17; \
+ }
+
+#define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t06, t08, t09, t10; \
+ uint32_t t12, t13, t14, t15, t17, t18, t01; \
+ t01 = c ^ d ; \
+ t02 = a | b ; \
+ t03 = b | c ; \
+ t04 = c & t01; \
+ t05 = t02 ^ t01; \
+ t06 = a | t04; \
+ y = ~ t05; \
+ t08 = b ^ d ; \
+ t09 = t03 & t08; \
+ t10 = d | y ; \
+ x = t09 ^ t06; \
+ t12 = a | t05; \
+ t13 = x ^ t12; \
+ t14 = t03 ^ t10; \
+ t15 = a ^ c ; \
+ z = t14 ^ t13; \
+ t17 = t05 & t13; \
+ t18 = t14 | t17; \
+ w = t15 ^ t18; \
+ }
+
+#define SBOX1(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t06, t07, t08; \
+ uint32_t t10, t11, t12, t13, t16, t17, t01; \
+ t01 = a | d ; \
+ t02 = c ^ d ; \
+ t03 = ~ b ; \
+ t04 = a ^ c ; \
+ t05 = a | t03; \
+ t06 = d & t04; \
+ t07 = t01 & t02; \
+ t08 = b | t06; \
+ y = t02 ^ t05; \
+ t10 = t07 ^ t08; \
+ t11 = t01 ^ t10; \
+ t12 = y ^ t11; \
+ t13 = b & d ; \
+ z = ~ t10; \
+ x = t13 ^ t12; \
+ t16 = t10 | x ; \
+ t17 = t05 & t16; \
+ w = c ^ t17; \
+ }
+
+#define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t06, t07, t08; \
+ uint32_t t09, t10, t11, t14, t15, t17, t01; \
+ t01 = a ^ b ; \
+ t02 = b | d ; \
+ t03 = a & c ; \
+ t04 = c ^ t02; \
+ t05 = a | t04; \
+ t06 = t01 & t05; \
+ t07 = d | t03; \
+ t08 = b ^ t06; \
+ t09 = t07 ^ t06; \
+ t10 = t04 | t03; \
+ t11 = d & t08; \
+ y = ~ t09; \
+ x = t10 ^ t11; \
+ t14 = a | y ; \
+ t15 = t06 ^ x ; \
+ z = t01 ^ t04; \
+ t17 = c ^ t15; \
+ w = t14 ^ t17; \
+ }
+
+#define SBOX2(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t05, t06, t07, t08; \
+ uint32_t t09, t10, t12, t13, t14, t01; \
+ t01 = a | c ; \
+ t02 = a ^ b ; \
+ t03 = d ^ t01; \
+ w = t02 ^ t03; \
+ t05 = c ^ w ; \
+ t06 = b ^ t05; \
+ t07 = b | t05; \
+ t08 = t01 & t06; \
+ t09 = t03 ^ t07; \
+ t10 = t02 | t09; \
+ x = t10 ^ t08; \
+ t12 = a | d ; \
+ t13 = t09 ^ x ; \
+ t14 = b ^ t13; \
+ z = ~ t09; \
+ y = t12 ^ t14; \
+ }
+
+#define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t06, t07, t08, t09; \
+ uint32_t t10, t11, t12, t15, t16, t17, t01; \
+ t01 = a ^ d ; \
+ t02 = c ^ d ; \
+ t03 = a & c ; \
+ t04 = b | t02; \
+ w = t01 ^ t04; \
+ t06 = a | c ; \
+ t07 = d | w ; \
+ t08 = ~ d ; \
+ t09 = b & t06; \
+ t10 = t08 | t03; \
+ t11 = b & t07; \
+ t12 = t06 & t02; \
+ z = t09 ^ t10; \
+ x = t12 ^ t11; \
+ t15 = c & z ; \
+ t16 = w ^ x ; \
+ t17 = t10 ^ t15; \
+ y = t16 ^ t17; \
+ }
+
+#define SBOX3(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t06, t07, t08; \
+ uint32_t t09, t10, t11, t13, t14, t15, t01; \
+ t01 = a ^ c ; \
+ t02 = a | d ; \
+ t03 = a & d ; \
+ t04 = t01 & t02; \
+ t05 = b | t03; \
+ t06 = a & b ; \
+ t07 = d ^ t04; \
+ t08 = c | t06; \
+ t09 = b ^ t07; \
+ t10 = d & t05; \
+ t11 = t02 ^ t10; \
+ z = t08 ^ t09; \
+ t13 = d | z ; \
+ t14 = a | t07; \
+ t15 = b & t13; \
+ y = t08 ^ t11; \
+ w = t14 ^ t15; \
+ x = t05 ^ t04; \
+ }
+
+#define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t06, t07, t09; \
+ uint32_t t11, t12, t13, t14, t16, t01; \
+ t01 = c | d ; \
+ t02 = a | d ; \
+ t03 = c ^ t02; \
+ t04 = b ^ t02; \
+ t05 = a ^ d ; \
+ t06 = t04 & t03; \
+ t07 = b & t01; \
+ y = t05 ^ t06; \
+ t09 = a ^ t03; \
+ w = t07 ^ t03; \
+ t11 = w | t05; \
+ t12 = t09 & t11; \
+ t13 = a & y ; \
+ t14 = t01 ^ t05; \
+ x = b ^ t12; \
+ t16 = b | t13; \
+ z = t14 ^ t16; \
+ }
+
+#define SBOX4(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t06, t08, t09; \
+ uint32_t t10, t11, t12, t13, t14, t15, t16, t01; \
+ t01 = a | b ; \
+ t02 = b | c ; \
+ t03 = a ^ t02; \
+ t04 = b ^ d ; \
+ t05 = d | t03; \
+ t06 = d & t01; \
+ z = t03 ^ t06; \
+ t08 = z & t04; \
+ t09 = t04 & t05; \
+ t10 = c ^ t06; \
+ t11 = b & c ; \
+ t12 = t04 ^ t08; \
+ t13 = t11 | t03; \
+ t14 = t10 ^ t09; \
+ t15 = a & t05; \
+ t16 = t11 | t12; \
+ y = t13 ^ t08; \
+ x = t15 ^ t16; \
+ w = ~ t14; \
+ }
+
+#define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t06, t07, t09; \
+ uint32_t t10, t11, t12, t13, t15, t01; \
+ t01 = b | d ; \
+ t02 = c | d ; \
+ t03 = a & t01; \
+ t04 = b ^ t02; \
+ t05 = c ^ d ; \
+ t06 = ~ t03; \
+ t07 = a & t04; \
+ x = t05 ^ t07; \
+ t09 = x | t06; \
+ t10 = a ^ t07; \
+ t11 = t01 ^ t09; \
+ t12 = d ^ t04; \
+ t13 = c | t10; \
+ z = t03 ^ t12; \
+ t15 = a ^ t04; \
+ y = t11 ^ t13; \
+ w = t15 ^ t09; \
+ }
+
+#define SBOX5(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t07, t08, t09; \
+ uint32_t t10, t11, t12, t13, t14, t01; \
+ t01 = b ^ d ; \
+ t02 = b | d ; \
+ t03 = a & t01; \
+ t04 = c ^ t02; \
+ t05 = t03 ^ t04; \
+ w = ~ t05; \
+ t07 = a ^ t01; \
+ t08 = d | w ; \
+ t09 = b | t05; \
+ t10 = d ^ t08; \
+ t11 = b | t07; \
+ t12 = t03 | w ; \
+ t13 = t07 | t10; \
+ t14 = t01 ^ t11; \
+ y = t09 ^ t13; \
+ x = t07 ^ t08; \
+ z = t12 ^ t14; \
+ }
+
+#define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t07, t08, t09; \
+ uint32_t t10, t12, t13, t15, t16, t01; \
+ t01 = a & d ; \
+ t02 = c ^ t01; \
+ t03 = a ^ d ; \
+ t04 = b & t02; \
+ t05 = a & c ; \
+ w = t03 ^ t04; \
+ t07 = a & w ; \
+ t08 = t01 ^ w ; \
+ t09 = b | t05; \
+ t10 = ~ b ; \
+ x = t08 ^ t09; \
+ t12 = t10 | t07; \
+ t13 = w | x ; \
+ z = t02 ^ t12; \
+ t15 = t02 ^ t13; \
+ t16 = b ^ d ; \
+ y = t16 ^ t15; \
+ }
+
+#define SBOX6(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t07, t08, t09, t10; \
+ uint32_t t11, t12, t13, t15, t17, t18, t01; \
+ t01 = a & d ; \
+ t02 = b ^ c ; \
+ t03 = a ^ d ; \
+ t04 = t01 ^ t02; \
+ t05 = b | c ; \
+ x = ~ t04; \
+ t07 = t03 & t05; \
+ t08 = b & x ; \
+ t09 = a | c ; \
+ t10 = t07 ^ t08; \
+ t11 = b | d ; \
+ t12 = c ^ t11; \
+ t13 = t09 ^ t10; \
+ y = ~ t13; \
+ t15 = x & t03; \
+ z = t12 ^ t07; \
+ t17 = a ^ b ; \
+ t18 = y ^ t15; \
+ w = t17 ^ t18; \
+ }
+
+#define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t06, t07, t08, t09; \
+ uint32_t t12, t13, t14, t15, t16, t17, t01; \
+ t01 = a ^ c ; \
+ t02 = ~ c ; \
+ t03 = b & t01; \
+ t04 = b | t02; \
+ t05 = d | t03; \
+ t06 = b ^ d ; \
+ t07 = a & t04; \
+ t08 = a | t02; \
+ t09 = t07 ^ t05; \
+ x = t06 ^ t08; \
+ w = ~ t09; \
+ t12 = b & w ; \
+ t13 = t01 & t05; \
+ t14 = t01 ^ t12; \
+ t15 = t07 ^ t13; \
+ t16 = d | t02; \
+ t17 = a ^ x ; \
+ z = t17 ^ t15; \
+ y = t16 ^ t14; \
+ }
+
+#define SBOX7(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t05, t06, t08, t09, t10; \
+ uint32_t t11, t13, t14, t15, t16, t17, t01; \
+ t01 = a & c ; \
+ t02 = ~ d ; \
+ t03 = a & t02; \
+ t04 = b | t01; \
+ t05 = a & b ; \
+ t06 = c ^ t04; \
+ z = t03 ^ t06; \
+ t08 = c | z ; \
+ t09 = d | t05; \
+ t10 = a ^ t08; \
+ t11 = t04 & z ; \
+ x = t09 ^ t10; \
+ t13 = b ^ x ; \
+ t14 = t01 ^ x ; \
+ t15 = c ^ t05; \
+ t16 = t11 | t13; \
+ t17 = t02 | t14; \
+ w = t15 ^ t17; \
+ y = a ^ t16; \
+ }
+
+#define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ uint32_t t02, t03, t04, t06, t07, t08, t09; \
+ uint32_t t10, t11, t13, t14, t15, t16, t01; \
+ t01 = a & b ; \
+ t02 = a | b ; \
+ t03 = c | t01; \
+ t04 = d & t02; \
+ z = t03 ^ t04; \
+ t06 = b ^ t04; \
+ t07 = d ^ z ; \
+ t08 = ~ t07; \
+ t09 = t06 | t08; \
+ t10 = b ^ d ; \
+ t11 = a | d ; \
+ x = a ^ t09; \
+ t13 = c ^ t06; \
+ t14 = c & t11; \
+ t15 = d | x ; \
+ t16 = t01 | t10; \
+ w = t13 ^ t15; \
+ y = t14 ^ t16; \
+ }
+
+/* XOR BLOCK1 into BLOCK0. */
+#define BLOCK_XOR(block0, block1) \
+ { \
+ block0[0] ^= block1[0]; \
+ block0[1] ^= block1[1]; \
+ block0[2] ^= block1[2]; \
+ block0[3] ^= block1[3]; \
+ }
- assert(key_size >= SERPENT_MIN_KEY_SIZE);
- assert(key_size <= SERPENT_MAX_KEY_SIZE);
+/* Copy BLOCK_SRC to BLOCK_DST. */
+#define BLOCK_COPY(block_dst, block_src) \
+ { \
+ block_dst[0] = block_src[0]; \
+ block_dst[1] = block_src[1]; \
+ block_dst[2] = block_src[2]; \
+ block_dst[3] = block_src[3]; \
+ }
- for (i = 0; key_size >= 4; key_size -= 4, key += 4, i++)
+/* Apply SBOX number WHICH to to the block found in ARRAY0 at index
+ INDEX, writing the output to the block found in ARRAY1 at index
+ INDEX. */
+#define SBOX(which, array0, array1, index) \
+ SBOX##which (array0[index + 0], array0[index + 1], \
+ array0[index + 2], array0[index + 3], \
+ array1[index + 0], array1[index + 1], \
+ array1[index + 2], array1[index + 3]);
+
+/* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at
+ index INDEX, writing the output to the block found in ARRAY1 at
+ index INDEX. */
+#define SBOX_INVERSE(which, array0, array1, index) \
+ SBOX##which##_INVERSE (array0[index + 0], array0[index + 1], \
+ array0[index + 2], array0[index + 3], \
+ array1[index + 0], array1[index + 1], \
+ array1[index + 2], array1[index + 3]);
+
+/* Apply the linear transformation to BLOCK. */
+#define LINEAR_TRANSFORMATION(block) \
+ { \
+ block[0] = rol (block[0], 13); \
+ block[2] = rol (block[2], 3); \
+ block[1] = block[1] ^ block[0] ^ block[2]; \
+ block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
+ block[1] = rol (block[1], 1); \
+ block[3] = rol (block[3], 7); \
+ block[0] = block[0] ^ block[1] ^ block[3]; \
+ block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
+ block[0] = rol (block[0], 5); \
+ block[2] = rol (block[2], 22); \
+ }
+
+/* Apply the inverse linear transformation to BLOCK. */
+#define LINEAR_TRANSFORMATION_INVERSE(block) \
+ { \
+ block[2] = ror (block[2], 22); \
+ block[0] = ror (block[0] , 5); \
+ block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
+ block[0] = block[0] ^ block[1] ^ block[3]; \
+ block[3] = ror (block[3], 7); \
+ block[1] = ror (block[1], 1); \
+ block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
+ block[1] = block[1] ^ block[0] ^ block[2]; \
+ block[2] = ror (block[2], 3); \
+ block[0] = ror (block[0], 13); \
+ }
+
+/* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the
+ subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage.
+ This macro increments `round'. */
+#define ROUND(which, subkeys, block, block_tmp) \
+ { \
+ BLOCK_XOR (block, subkeys[round]); \
+ round++; \
+ SBOX (which, block, block_tmp, 0); \
+ LINEAR_TRANSFORMATION (block_tmp); \
+ BLOCK_COPY (block, block_tmp); \
+ }
+
+/* Apply the last Serpent round to BLOCK, using the SBOX number WHICH
+ and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
+ storage. The result will be stored in BLOCK_TMP. This macro
+ increments `round'. */
+#define ROUND_LAST(which, subkeys, block, block_tmp) \
+ { \
+ BLOCK_XOR (block, subkeys[round]); \
+ round++; \
+ SBOX (which, block, block_tmp, 0); \
+ BLOCK_XOR (block_tmp, subkeys[round]); \
+ round++; \
+ }
+
+/* Apply an inverse Serpent round to BLOCK, using the SBOX number
+ WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as
+ temporary storage. This macro increments `round'. */
+#define ROUND_INVERSE(which, subkey, block, block_tmp) \
+ { \
+ LINEAR_TRANSFORMATION_INVERSE (block); \
+ SBOX_INVERSE (which, block, block_tmp, 0); \
+ BLOCK_XOR (block_tmp, subkey[round]); \
+ round--; \
+ BLOCK_COPY (block, block_tmp); \
+ }
+
+/* Apply the first Serpent round to BLOCK, using the SBOX number WHICH
+ and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
+ storage. The result will be stored in BLOCK_TMP. This macro
+ increments `round'. */
+#define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \
+ { \
+ BLOCK_XOR (block, subkeys[round]); \
+ round--; \
+ SBOX_INVERSE (which, block, block_tmp, 0); \
+ BLOCK_XOR (block_tmp, subkeys[round]); \
+ round--; \
+ }
+
+/* Convert the user provided key KEY of KEY_LENGTH bytes into the
+ internally used format. */
+static void
+serpent_key_prepare (const uint8_t * key, unsigned int key_length,
+ serpent_key_t key_prepared)
+{
+ unsigned int i;
+
+ /* Copy key. */
+ for (i = 0; i < key_length / 4; i++)
{
- assert(i < 8);
- w[i] = LE_READ_UINT32 (key);
+#ifdef WORDS_BIGENDIAN
+ key_prepared[i] = byte_swap_32 (((uint32_t *) key)[i]);
+#else
+ key_prepared[i] = ((uint32_t *) key)[i];
+#endif
}
if (i < 8)
{
- /* Pad key, "aabbcc" -> "aabbcc0100...00" -> 0x01ccbbaa*/
- uint32_t partial = 0x01;
- while (key_size > 0)
- partial = (partial << 8 ) | key[--key_size];
-
- w[i++] = partial;
- while (i < 8)
- w[i++] = 0;
+ /* Key must be padded according to the Serpent
+ specification. */
+ key_prepared[i] = 0x00000001;
+
+ for (i++; i < 8; i++)
+ key_prepared[i] = 0;
}
+}
+
+/* Derive the 33 subkeys from KEY and store them in SUBKEYS. */
+static void
+serpent_subkeys_generate (serpent_key_t key, struct serpent_ctx *ctx)
+{
+ uint32_t w_real[140]; /* The `prekey'. */
+ uint32_t k[132];
+ uint32_t *w = &w_real[8];
+ int i, j;
+
+ /* Initialize with key values. */
+ for (i = 0; i < 8; i++)
+ w[i - 8] = key[i];
+
+ /* Expand to intermediate key using the affine recurrence. */
+ for (i = 0; i < 132; i++)
+ w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
- for(i=8; i<16; i++)
- w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^(i-8),11);
- for(i=0; i<8; i++)
- w[i]=w[i+8];
- for(i=8; i<132; i++)
- w[i]=ROL(w[i-8]^w[i-5]^w[i-3]^w[i-1]^PHI^i,11);
-
- RND03(w[ 0], w[ 1], w[ 2], w[ 3], k[ 0], k[ 1], k[ 2], k[ 3]);
- RND02(w[ 4], w[ 5], w[ 6], w[ 7], k[ 4], k[ 5], k[ 6], k[ 7]);
- RND01(w[ 8], w[ 9], w[ 10], w[ 11], k[ 8], k[ 9], k[ 10], k[ 11]);
- RND00(w[ 12], w[ 13], w[ 14], w[ 15], k[ 12], k[ 13], k[ 14], k[ 15]);
- RND31(w[ 16], w[ 17], w[ 18], w[ 19], k[ 16], k[ 17], k[ 18], k[ 19]);
- RND30(w[ 20], w[ 21], w[ 22], w[ 23], k[ 20], k[ 21], k[ 22], k[ 23]);
- RND29(w[ 24], w[ 25], w[ 26], w[ 27], k[ 24], k[ 25], k[ 26], k[ 27]);
- RND28(w[ 28], w[ 29], w[ 30], w[ 31], k[ 28], k[ 29], k[ 30], k[ 31]);
- RND27(w[ 32], w[ 33], w[ 34], w[ 35], k[ 32], k[ 33], k[ 34], k[ 35]);
- RND26(w[ 36], w[ 37], w[ 38], w[ 39], k[ 36], k[ 37], k[ 38], k[ 39]);
- RND25(w[ 40], w[ 41], w[ 42], w[ 43], k[ 40], k[ 41], k[ 42], k[ 43]);
- RND24(w[ 44], w[ 45], w[ 46], w[ 47], k[ 44], k[ 45], k[ 46], k[ 47]);
- RND23(w[ 48], w[ 49], w[ 50], w[ 51], k[ 48], k[ 49], k[ 50], k[ 51]);
- RND22(w[ 52], w[ 53], w[ 54], w[ 55], k[ 52], k[ 53], k[ 54], k[ 55]);
- RND21(w[ 56], w[ 57], w[ 58], w[ 59], k[ 56], k[ 57], k[ 58], k[ 59]);
- RND20(w[ 60], w[ 61], w[ 62], w[ 63], k[ 60], k[ 61], k[ 62], k[ 63]);
- RND19(w[ 64], w[ 65], w[ 66], w[ 67], k[ 64], k[ 65], k[ 66], k[ 67]);
- RND18(w[ 68], w[ 69], w[ 70], w[ 71], k[ 68], k[ 69], k[ 70], k[ 71]);
- RND17(w[ 72], w[ 73], w[ 74], w[ 75], k[ 72], k[ 73], k[ 74], k[ 75]);
- RND16(w[ 76], w[ 77], w[ 78], w[ 79], k[ 76], k[ 77], k[ 78], k[ 79]);
- RND15(w[ 80], w[ 81], w[ 82], w[ 83], k[ 80], k[ 81], k[ 82], k[ 83]);
- RND14(w[ 84], w[ 85], w[ 86], w[ 87], k[ 84], k[ 85], k[ 86], k[ 87]);
- RND13(w[ 88], w[ 89], w[ 90], w[ 91], k[ 88], k[ 89], k[ 90], k[ 91]);
- RND12(w[ 92], w[ 93], w[ 94], w[ 95], k[ 92], k[ 93], k[ 94], k[ 95]);
- RND11(w[ 96], w[ 97], w[ 98], w[ 99], k[ 96], k[ 97], k[ 98], k[ 99]);
- RND10(w[100], w[101], w[102], w[103], k[100], k[101], k[102], k[103]);
- RND09(w[104], w[105], w[106], w[107], k[104], k[105], k[106], k[107]);
- RND08(w[108], w[109], w[110], w[111], k[108], k[109], k[110], k[111]);
- RND07(w[112], w[113], w[114], w[115], k[112], k[113], k[114], k[115]);
- RND06(w[116], w[117], w[118], w[119], k[116], k[117], k[118], k[119]);
- RND05(w[120], w[121], w[122], w[123], k[120], k[121], k[122], k[123]);
- RND04(w[124], w[125], w[126], w[127], k[124], k[125], k[126], k[127]);
- RND03(w[128], w[129], w[130], w[131], k[128], k[129], k[130], k[131]);
-
- for(i=0; i<=32; i++)
- for(j=0; j<4; j++)
- ctx->keys[i][j] = k[4*i+j];
+ /* Calculate subkeys via S-Boxes, in bitslice mode. */
+ SBOX (3, w, k, 0);
+ SBOX (2, w, k, 4);
+ SBOX (1, w, k, 8);
+ SBOX (0, w, k, 12);
+ SBOX (7, w, k, 16);
+ SBOX (6, w, k, 20);
+ SBOX (5, w, k, 24);
+ SBOX (4, w, k, 28);
+ SBOX (3, w, k, 32);
+ SBOX (2, w, k, 36);
+ SBOX (1, w, k, 40);
+ SBOX (0, w, k, 44);
+ SBOX (7, w, k, 48);
+ SBOX (6, w, k, 52);
+ SBOX (5, w, k, 56);
+ SBOX (4, w, k, 60);
+ SBOX (3, w, k, 64);
+ SBOX (2, w, k, 68);
+ SBOX (1, w, k, 72);
+ SBOX (0, w, k, 76);
+ SBOX (7, w, k, 80);
+ SBOX (6, w, k, 84);
+ SBOX (5, w, k, 88);
+ SBOX (4, w, k, 92);
+ SBOX (3, w, k, 96);
+ SBOX (2, w, k, 100);
+ SBOX (1, w, k, 104);
+ SBOX (0, w, k, 108);
+ SBOX (7, w, k, 112);
+ SBOX (6, w, k, 116);
+ SBOX (5, w, k, 120);
+ SBOX (4, w, k, 124);
+ SBOX (3, w, k, 128);
+
+ /* Renumber subkeys. */
+ for (i = 0; i < ROUNDS + 1; i++)
+ for (j = 0; j < 4; j++)
+ ctx->keys[i][j] = k[4 * i + j];
}
+/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits. */
void
-serpent_encrypt(const struct serpent_ctx *ctx,
- unsigned length, uint8_t *dst,
- const uint8_t *plain)
+serpent_set_key (struct serpent_ctx *ctx,
+ unsigned length, const uint8_t * key)
{
- register uint32_t x0, x1, x2, x3;
- register uint32_t y0, y1, y2, y3;
+ serpent_key_t key_prepared;
- FOR_BLOCKS(length, dst, plain, SERPENT_BLOCK_SIZE)
- {
- x0 = LE_READ_UINT32(plain);
- x1 = LE_READ_UINT32(plain + 4);
- x2 = LE_READ_UINT32(plain + 8);
- x3 = LE_READ_UINT32(plain + 12);
-
- /* Start to encrypt the plaintext x */
- keying(x0, x1, x2, x3, ctx->keys[ 0]);
- RND00(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[ 1]);
- RND01(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[ 2]);
- RND02(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[ 3]);
- RND03(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[ 4]);
- RND04(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[ 5]);
- RND05(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[ 6]);
- RND06(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[ 7]);
- RND07(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[ 8]);
- RND08(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[ 9]);
- RND09(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[10]);
- RND10(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[11]);
- RND11(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[12]);
- RND12(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[13]);
- RND13(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[14]);
- RND14(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[15]);
- RND15(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[16]);
- RND16(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[17]);
- RND17(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[18]);
- RND18(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[19]);
- RND19(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[20]);
- RND20(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[21]);
- RND21(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[22]);
- RND22(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[23]);
- RND23(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[24]);
- RND24(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[25]);
- RND25(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[26]);
- RND26(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[27]);
- RND27(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[28]);
- RND28(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[29]);
- RND29(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[30]);
- RND30(x0, x1, x2, x3, y0, y1, y2, y3);
- transform(y0, y1, y2, y3, x0, x1, x2, x3);
- keying(x0, x1, x2, x3, ctx->keys[31]);
- RND31(x0, x1, x2, x3, y0, y1, y2, y3);
- x0 = y0; x1 = y1; x2 = y2; x3 = y3;
- keying(x0, x1, x2, x3, ctx->keys[32]);
-
- /* The ciphertext is now in x */
- LE_WRITE_UINT32(dst, x0);
- LE_WRITE_UINT32(dst+4, x1);
- LE_WRITE_UINT32(dst+8, x2);
- LE_WRITE_UINT32(dst+12, x3);
- }
+ serpent_key_prepare (key, length, key_prepared);
+ serpent_subkeys_generate (key_prepared, ctx);
}
void
-serpent_decrypt(const struct serpent_ctx *ctx,
- unsigned length, uint8_t *dst,
- const uint8_t *cipher)
+serpent_encrypt (const struct serpent_ctx *ctx,
+ unsigned length, uint8_t * dst, const uint8_t * src)
{
- register uint32_t x0, x1, x2, x3;
- register uint32_t y0, y1, y2, y3;
+ FOR_BLOCKS (length, dst, src, SERPENT_BLOCK_SIZE)
+ {
+ serpent_block_t b, b_next;
+ int round = 0;
- FOR_BLOCKS(length, dst, cipher, SERPENT_BLOCK_SIZE)
- {
- x0 = LE_READ_UINT32(cipher);
- x1 = LE_READ_UINT32(cipher + 4);
- x2 = LE_READ_UINT32(cipher + 8);
- x3 = LE_READ_UINT32(cipher + 12);
-
- /* Start to decrypt the ciphertext x */
- keying(x0, x1, x2, x3, ctx->keys[32]);
- InvRND31(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[31]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND30(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[30]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND29(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[29]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND28(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[28]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND27(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[27]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND26(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[26]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND25(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[25]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND24(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[24]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND23(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[23]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND22(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[22]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND21(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[21]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND20(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[20]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND19(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[19]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND18(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[18]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND17(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[17]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND16(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[16]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND15(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[15]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND14(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[14]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND13(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[13]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND12(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[12]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND11(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[11]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND10(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[10]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND09(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[ 9]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND08(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[ 8]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND07(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[ 7]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND06(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[ 6]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND05(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[ 5]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND04(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[ 4]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND03(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[ 3]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND02(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[ 2]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND01(x0, x1, x2, x3, y0, y1, y2, y3);
- keying(y0, y1, y2, y3, ctx->keys[ 1]);
- inv_transform(y0, y1, y2, y3, x0, x1, x2, x3);
- InvRND00(x0, x1, x2, x3, y0, y1, y2, y3);
- x0 = y0; x1 = y1; x2 = y2; x3 = y3;
- keying(x0, x1, x2, x3, ctx->keys[ 0]);
-
- /* The plaintext is now in x */
- LE_WRITE_UINT32(dst, x0);
- LE_WRITE_UINT32(dst+4, x1);
- LE_WRITE_UINT32(dst+8, x2);
- LE_WRITE_UINT32(dst+12, x3);
- }
+ b[0] = LE_READ_UINT32 (src);
+ b[1] = LE_READ_UINT32 (src + 4);
+ b[2] = LE_READ_UINT32 (src + 8);
+ b[3] = LE_READ_UINT32 (src + 12);
+
+ ROUND (0, ctx->keys, b, b_next);
+ ROUND (1, ctx->keys, b, b_next);
+ ROUND (2, ctx->keys, b, b_next);
+ ROUND (3, ctx->keys, b, b_next);
+ ROUND (4, ctx->keys, b, b_next);
+ ROUND (5, ctx->keys, b, b_next);
+ ROUND (6, ctx->keys, b, b_next);
+ ROUND (7, ctx->keys, b, b_next);
+ ROUND (0, ctx->keys, b, b_next);
+ ROUND (1, ctx->keys, b, b_next);
+ ROUND (2, ctx->keys, b, b_next);
+ ROUND (3, ctx->keys, b, b_next);
+ ROUND (4, ctx->keys, b, b_next);
+ ROUND (5, ctx->keys, b, b_next);
+ ROUND (6, ctx->keys, b, b_next);
+ ROUND (7, ctx->keys, b, b_next);
+ ROUND (0, ctx->keys, b, b_next);
+ ROUND (1, ctx->keys, b, b_next);
+ ROUND (2, ctx->keys, b, b_next);
+ ROUND (3, ctx->keys, b, b_next);
+ ROUND (4, ctx->keys, b, b_next);
+ ROUND (5, ctx->keys, b, b_next);
+ ROUND (6, ctx->keys, b, b_next);
+ ROUND (7, ctx->keys, b, b_next);
+ ROUND (0, ctx->keys, b, b_next);
+ ROUND (1, ctx->keys, b, b_next);
+ ROUND (2, ctx->keys, b, b_next);
+ ROUND (3, ctx->keys, b, b_next);
+ ROUND (4, ctx->keys, b, b_next);
+ ROUND (5, ctx->keys, b, b_next);
+ ROUND (6, ctx->keys, b, b_next);
+
+ ROUND_LAST (7, ctx->keys, b, b_next);
+
+ LE_WRITE_UINT32 (dst, b_next[0]);
+ LE_WRITE_UINT32 (dst + 4, b_next[1]);
+ LE_WRITE_UINT32 (dst + 8, b_next[2]);
+ LE_WRITE_UINT32 (dst + 12, b_next[3]);
+ }
+}
+
+void
+serpent_decrypt (const struct serpent_ctx *ctx,
+ unsigned length, uint8_t * dst, const uint8_t * src)
+{
+ FOR_BLOCKS (length, dst, src, SERPENT_BLOCK_SIZE)
+ {
+ serpent_block_t b, b_next;
+ int round = ROUNDS;
+
+ b_next[0] = LE_READ_UINT32 (src);
+ b_next[1] = LE_READ_UINT32 (src + 4);
+ b_next[2] = LE_READ_UINT32 (src + 8);
+ b_next[3] = LE_READ_UINT32 (src + 12);
+
+ ROUND_FIRST_INVERSE (7, ctx->keys, b_next, b);
+
+ ROUND_INVERSE (6, ctx->keys, b, b_next);
+ ROUND_INVERSE (5, ctx->keys, b, b_next);
+ ROUND_INVERSE (4, ctx->keys, b, b_next);
+ ROUND_INVERSE (3, ctx->keys, b, b_next);
+ ROUND_INVERSE (2, ctx->keys, b, b_next);
+ ROUND_INVERSE (1, ctx->keys, b, b_next);
+ ROUND_INVERSE (0, ctx->keys, b, b_next);
+ ROUND_INVERSE (7, ctx->keys, b, b_next);
+ ROUND_INVERSE (6, ctx->keys, b, b_next);
+ ROUND_INVERSE (5, ctx->keys, b, b_next);
+ ROUND_INVERSE (4, ctx->keys, b, b_next);
+ ROUND_INVERSE (3, ctx->keys, b, b_next);
+ ROUND_INVERSE (2, ctx->keys, b, b_next);
+ ROUND_INVERSE (1, ctx->keys, b, b_next);
+ ROUND_INVERSE (0, ctx->keys, b, b_next);
+ ROUND_INVERSE (7, ctx->keys, b, b_next);
+ ROUND_INVERSE (6, ctx->keys, b, b_next);
+ ROUND_INVERSE (5, ctx->keys, b, b_next);
+ ROUND_INVERSE (4, ctx->keys, b, b_next);
+ ROUND_INVERSE (3, ctx->keys, b, b_next);
+ ROUND_INVERSE (2, ctx->keys, b, b_next);
+ ROUND_INVERSE (1, ctx->keys, b, b_next);
+ ROUND_INVERSE (0, ctx->keys, b, b_next);
+ ROUND_INVERSE (7, ctx->keys, b, b_next);
+ ROUND_INVERSE (6, ctx->keys, b, b_next);
+ ROUND_INVERSE (5, ctx->keys, b, b_next);
+ ROUND_INVERSE (4, ctx->keys, b, b_next);
+ ROUND_INVERSE (3, ctx->keys, b, b_next);
+ ROUND_INVERSE (2, ctx->keys, b, b_next);
+ ROUND_INVERSE (1, ctx->keys, b, b_next);
+ ROUND_INVERSE (0, ctx->keys, b, b_next);
+
+ LE_WRITE_UINT32 (dst, b_next[0]);
+ LE_WRITE_UINT32 (dst + 4, b_next[1]);
+ LE_WRITE_UINT32 (dst + 8, b_next[2]);
+ LE_WRITE_UINT32 (dst + 12, b_next[3]);
+ }
}
+++ /dev/null
-/* serpentsboxes.h
- *
- * $Id$
- *
- * For more details on this algorithm, see the Serpent website at
- * http://www.cl.cam.ac.uk/~rja14/serpent.html
- */
-
-/* Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* I've modified this code a bit so that it interoperates with lsh
- * properly. 2000-9-5, Rafael R. Sevilla <dido@pacific.net.ph>
- */
-
-/* NOTE: The copyright notice for the original version of this code
- * said "All rights reserved. This code is freely distributed for AES
- * selection process. No other use is allowed." However, the authors
- * later decided to GPL the code. /nisse */
-
-#ifndef SERPENT_SBOXES_H_INCLUDED
-#define SERPENT_SBOXES_H_INCLUDED
-
-#include "serpent.h"
-
-/* S0: 3 8 15 1 10 6 5 11 14 13 4 2 7 0 9 12 */
-
-/* depth = 5,7,4,2, Total gates=18 */
-#define RND00(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t05, t06, t07, t08, t09, t11, t12, t13, t14, t15, t17, t01;\
- t01 = b ^ c ; \
- t02 = a | d ; \
- t03 = a ^ b ; \
- z = t02 ^ t01; \
- t05 = c | z ; \
- t06 = a ^ d ; \
- t07 = b | c ; \
- t08 = d & t05; \
- t09 = t03 & t07; \
- y = t09 ^ t08; \
- t11 = t09 & y ; \
- t12 = c ^ d ; \
- t13 = t07 ^ t11; \
- t14 = b & t06; \
- t15 = t06 ^ t13; \
- w = ~ t15; \
- t17 = w ^ t14; \
- x = t12 ^ t17; }
-
-/* InvS0: 13 3 11 0 10 6 5 12 1 14 4 7 15 9 8 2 */
-
-/* depth = 8,4,3,6, Total gates=19 */
-#define InvRND00(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t06, t08, t09, t10, t12, t13, t14, t15, t17, t18, t01;\
- t01 = c ^ d ; \
- t02 = a | b ; \
- t03 = b | c ; \
- t04 = c & t01; \
- t05 = t02 ^ t01; \
- t06 = a | t04; \
- y = ~ t05; \
- t08 = b ^ d ; \
- t09 = t03 & t08; \
- t10 = d | y ; \
- x = t09 ^ t06; \
- t12 = a | t05; \
- t13 = x ^ t12; \
- t14 = t03 ^ t10; \
- t15 = a ^ c ; \
- z = t14 ^ t13; \
- t17 = t05 & t13; \
- t18 = t14 | t17; \
- w = t15 ^ t18; }
-
-/* S1: 15 12 2 7 9 0 5 10 1 11 14 8 6 13 3 4 */
-
-/* depth = 10,7,3,5, Total gates=18 */
-#define RND01(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t06, t07, t08, t10, t11, t12, t13, t16, t17, t01;\
- t01 = a | d ; \
- t02 = c ^ d ; \
- t03 = ~ b ; \
- t04 = a ^ c ; \
- t05 = a | t03; \
- t06 = d & t04; \
- t07 = t01 & t02; \
- t08 = b | t06; \
- y = t02 ^ t05; \
- t10 = t07 ^ t08; \
- t11 = t01 ^ t10; \
- t12 = y ^ t11; \
- t13 = b & d ; \
- z = ~ t10; \
- x = t13 ^ t12; \
- t16 = t10 | x ; \
- t17 = t05 & t16; \
- w = c ^ t17; }
-
-/* InvS1: 5 8 2 14 15 6 12 3 11 4 7 9 1 13 10 0 */
-
-/* depth = 7,4,5,3, Total gates=18 */
-#define InvRND01(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t14, t15, t17, t01;\
- t01 = a ^ b ; \
- t02 = b | d ; \
- t03 = a & c ; \
- t04 = c ^ t02; \
- t05 = a | t04; \
- t06 = t01 & t05; \
- t07 = d | t03; \
- t08 = b ^ t06; \
- t09 = t07 ^ t06; \
- t10 = t04 | t03; \
- t11 = d & t08; \
- y = ~ t09; \
- x = t10 ^ t11; \
- t14 = a | y ; \
- t15 = t06 ^ x ; \
- z = t01 ^ t04; \
- t17 = c ^ t15; \
- w = t14 ^ t17; }
-
-/* S2: 8 6 7 9 3 12 10 15 13 1 14 4 0 11 5 2 */
-
-/* depth = 3,8,11,7, Total gates=16 */
-#define RND02(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t05, t06, t07, t08, t09, t10, t12, t13, t14, t01;\
- t01 = a | c ; \
- t02 = a ^ b ; \
- t03 = d ^ t01; \
- w = t02 ^ t03; \
- t05 = c ^ w ; \
- t06 = b ^ t05; \
- t07 = b | t05; \
- t08 = t01 & t06; \
- t09 = t03 ^ t07; \
- t10 = t02 | t09; \
- x = t10 ^ t08; \
- t12 = a | d ; \
- t13 = t09 ^ x ; \
- t14 = b ^ t13; \
- z = ~ t09; \
- y = t12 ^ t14; }
-
-/* InvS2: 12 9 15 4 11 14 1 2 0 3 6 13 5 8 10 7 */
-
-/* depth = 3,6,8,3, Total gates=18 */
-#define InvRND02(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t12, t15, t16, t17, t01;\
- t01 = a ^ d ; \
- t02 = c ^ d ; \
- t03 = a & c ; \
- t04 = b | t02; \
- w = t01 ^ t04; \
- t06 = a | c ; \
- t07 = d | w ; \
- t08 = ~ d ; \
- t09 = b & t06; \
- t10 = t08 | t03; \
- t11 = b & t07; \
- t12 = t06 & t02; \
- z = t09 ^ t10; \
- x = t12 ^ t11; \
- t15 = c & z ; \
- t16 = w ^ x ; \
- t17 = t10 ^ t15; \
- y = t16 ^ t17; }
-
-/* S3: 0 15 11 8 12 9 6 3 13 1 2 4 10 7 5 14 */
-
-/* depth = 8,3,5,5, Total gates=18 */
-#define RND03(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t13, t14, t15, t01;\
- t01 = a ^ c ; \
- t02 = a | d ; \
- t03 = a & d ; \
- t04 = t01 & t02; \
- t05 = b | t03; \
- t06 = a & b ; \
- t07 = d ^ t04; \
- t08 = c | t06; \
- t09 = b ^ t07; \
- t10 = d & t05; \
- t11 = t02 ^ t10; \
- z = t08 ^ t09; \
- t13 = d | z ; \
- t14 = a | t07; \
- t15 = b & t13; \
- y = t08 ^ t11; \
- w = t14 ^ t15; \
- x = t05 ^ t04; }
-
-/* InvS3: 0 9 10 7 11 14 6 13 3 5 12 2 4 8 15 1 */
-
-/* depth = 3,6,4,4, Total gates=17 */
-#define InvRND03(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t06, t07, t09, t11, t12, t13, t14, t16, t01;\
- t01 = c | d ; \
- t02 = a | d ; \
- t03 = c ^ t02; \
- t04 = b ^ t02; \
- t05 = a ^ d ; \
- t06 = t04 & t03; \
- t07 = b & t01; \
- y = t05 ^ t06; \
- t09 = a ^ t03; \
- w = t07 ^ t03; \
- t11 = w | t05; \
- t12 = t09 & t11; \
- t13 = a & y ; \
- t14 = t01 ^ t05; \
- x = b ^ t12; \
- t16 = b | t13; \
- z = t14 ^ t16; }
-
-/* S4: 1 15 8 3 12 0 11 6 2 5 4 10 9 14 7 13 */
-
-/* depth = 6,7,5,3, Total gates=19 */
-#define RND04(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t06, t08, t09, t10, t11, t12, t13, t14, t15, t16, t01;\
- t01 = a | b ; \
- t02 = b | c ; \
- t03 = a ^ t02; \
- t04 = b ^ d ; \
- t05 = d | t03; \
- t06 = d & t01; \
- z = t03 ^ t06; \
- t08 = z & t04; \
- t09 = t04 & t05; \
- t10 = c ^ t06; \
- t11 = b & c ; \
- t12 = t04 ^ t08; \
- t13 = t11 | t03; \
- t14 = t10 ^ t09; \
- t15 = a & t05; \
- t16 = t11 | t12; \
- y = t13 ^ t08; \
- x = t15 ^ t16; \
- w = ~ t14; }
-
-/* InvS4: 5 0 8 3 10 9 7 14 2 12 11 6 4 15 13 1 */
-
-/* depth = 6,4,7,3, Total gates=17 */
-#define InvRND04(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t06, t07, t09, t10, t11, t12, t13, t15, t01;\
- t01 = b | d ; \
- t02 = c | d ; \
- t03 = a & t01; \
- t04 = b ^ t02; \
- t05 = c ^ d ; \
- t06 = ~ t03; \
- t07 = a & t04; \
- x = t05 ^ t07; \
- t09 = x | t06; \
- t10 = a ^ t07; \
- t11 = t01 ^ t09; \
- t12 = d ^ t04; \
- t13 = c | t10; \
- z = t03 ^ t12; \
- t15 = a ^ t04; \
- y = t11 ^ t13; \
- w = t15 ^ t09; }
-
-/* S5: 15 5 2 11 4 10 9 12 0 3 14 8 13 6 7 1 */
-
-/* depth = 4,6,8,6, Total gates=17 */
-#define RND05(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t07, t08, t09, t10, t11, t12, t13, t14, t01;\
- t01 = b ^ d ; \
- t02 = b | d ; \
- t03 = a & t01; \
- t04 = c ^ t02; \
- t05 = t03 ^ t04; \
- w = ~ t05; \
- t07 = a ^ t01; \
- t08 = d | w ; \
- t09 = b | t05; \
- t10 = d ^ t08; \
- t11 = b | t07; \
- t12 = t03 | w ; \
- t13 = t07 | t10; \
- t14 = t01 ^ t11; \
- y = t09 ^ t13; \
- x = t07 ^ t08; \
- z = t12 ^ t14; }
-
-/* InvS5: 8 15 2 9 4 1 13 14 11 6 5 3 7 12 10 0 */
-
-/* depth = 4,6,9,7, Total gates=17 */
-#define InvRND05(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t07, t08, t09, t10, t12, t13, t15, t16, t01;\
- t01 = a & d ; \
- t02 = c ^ t01; \
- t03 = a ^ d ; \
- t04 = b & t02; \
- t05 = a & c ; \
- w = t03 ^ t04; \
- t07 = a & w ; \
- t08 = t01 ^ w ; \
- t09 = b | t05; \
- t10 = ~ b ; \
- x = t08 ^ t09; \
- t12 = t10 | t07; \
- t13 = w | x ; \
- z = t02 ^ t12; \
- t15 = t02 ^ t13; \
- t16 = b ^ d ; \
- y = t16 ^ t15; }
-
-/* S6: 7 2 12 5 8 4 6 11 14 9 1 15 13 3 10 0 */
-
-/* depth = 8,3,6,3, Total gates=19 */
-#define RND06(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t07, t08, t09, t10, t11, t12, t13, t15, t17, t18, t01;\
- t01 = a & d ; \
- t02 = b ^ c ; \
- t03 = a ^ d ; \
- t04 = t01 ^ t02; \
- t05 = b | c ; \
- x = ~ t04; \
- t07 = t03 & t05; \
- t08 = b & x ; \
- t09 = a | c ; \
- t10 = t07 ^ t08; \
- t11 = b | d ; \
- t12 = c ^ t11; \
- t13 = t09 ^ t10; \
- y = ~ t13; \
- t15 = x & t03; \
- z = t12 ^ t07; \
- t17 = a ^ b ; \
- t18 = y ^ t15; \
- w = t17 ^ t18; }
-
-/* InvS6: 15 10 1 13 5 3 6 0 4 9 14 7 2 12 8 11 */
-
-/* depth = 5,3,8,6, Total gates=19 */
-#define InvRND06(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t06, t07, t08, t09, t12, t13, t14, t15, t16, t17, t01;\
- t01 = a ^ c ; \
- t02 = ~ c ; \
- t03 = b & t01; \
- t04 = b | t02; \
- t05 = d | t03; \
- t06 = b ^ d ; \
- t07 = a & t04; \
- t08 = a | t02; \
- t09 = t07 ^ t05; \
- x = t06 ^ t08; \
- w = ~ t09; \
- t12 = b & w ; \
- t13 = t01 & t05; \
- t14 = t01 ^ t12; \
- t15 = t07 ^ t13; \
- t16 = d | t02; \
- t17 = a ^ x ; \
- z = t17 ^ t15; \
- y = t16 ^ t14; }
-
-/* S7: 1 13 15 0 14 8 2 11 7 4 12 10 9 3 5 6 */
-
-/* depth = 10,7,10,4, Total gates=19 */
-#define RND07(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t05, t06, t08, t09, t10, t11, t13, t14, t15, t16, t17, t01;\
- t01 = a & c ; \
- t02 = ~ d ; \
- t03 = a & t02; \
- t04 = b | t01; \
- t05 = a & b ; \
- t06 = c ^ t04; \
- z = t03 ^ t06; \
- t08 = c | z ; \
- t09 = d | t05; \
- t10 = a ^ t08; \
- t11 = t04 & z ; \
- x = t09 ^ t10; \
- t13 = b ^ x ; \
- t14 = t01 ^ x ; \
- t15 = c ^ t05; \
- t16 = t11 | t13; \
- t17 = t02 | t14; \
- w = t15 ^ t17; \
- y = a ^ t16; }
-
-/* InvS7: 3 0 6 13 9 14 15 8 5 12 11 7 10 1 4 2 */
-
-/* depth = 9,7,3,3, Total gates=18 */
-#define InvRND07(a,b,c,d,w,x,y,z) \
- { register uint32_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t13, t14, t15, t16, t01;\
- t01 = a & b ; \
- t02 = a | b ; \
- t03 = c | t01; \
- t04 = d & t02; \
- z = t03 ^ t04; \
- t06 = b ^ t04; \
- t07 = d ^ z ; \
- t08 = ~ t07; \
- t09 = t06 | t08; \
- t10 = b ^ d ; \
- t11 = a | d ; \
- x = a ^ t09; \
- t13 = c ^ t06; \
- t14 = c & t11; \
- t15 = d | x ; \
- t16 = t01 | t10; \
- w = t13 ^ t15; \
- y = t14 ^ t16; }
-
-#define RND08(a,b,c,d,e,f,g,h) RND00(a,b,c,d,e,f,g,h)
-#define RND09(a,b,c,d,e,f,g,h) RND01(a,b,c,d,e,f,g,h)
-#define RND10(a,b,c,d,e,f,g,h) RND02(a,b,c,d,e,f,g,h)
-#define RND11(a,b,c,d,e,f,g,h) RND03(a,b,c,d,e,f,g,h)
-#define RND12(a,b,c,d,e,f,g,h) RND04(a,b,c,d,e,f,g,h)
-#define RND13(a,b,c,d,e,f,g,h) RND05(a,b,c,d,e,f,g,h)
-#define RND14(a,b,c,d,e,f,g,h) RND06(a,b,c,d,e,f,g,h)
-#define RND15(a,b,c,d,e,f,g,h) RND07(a,b,c,d,e,f,g,h)
-#define RND16(a,b,c,d,e,f,g,h) RND00(a,b,c,d,e,f,g,h)
-#define RND17(a,b,c,d,e,f,g,h) RND01(a,b,c,d,e,f,g,h)
-#define RND18(a,b,c,d,e,f,g,h) RND02(a,b,c,d,e,f,g,h)
-#define RND19(a,b,c,d,e,f,g,h) RND03(a,b,c,d,e,f,g,h)
-#define RND20(a,b,c,d,e,f,g,h) RND04(a,b,c,d,e,f,g,h)
-#define RND21(a,b,c,d,e,f,g,h) RND05(a,b,c,d,e,f,g,h)
-#define RND22(a,b,c,d,e,f,g,h) RND06(a,b,c,d,e,f,g,h)
-#define RND23(a,b,c,d,e,f,g,h) RND07(a,b,c,d,e,f,g,h)
-#define RND24(a,b,c,d,e,f,g,h) RND00(a,b,c,d,e,f,g,h)
-#define RND25(a,b,c,d,e,f,g,h) RND01(a,b,c,d,e,f,g,h)
-#define RND26(a,b,c,d,e,f,g,h) RND02(a,b,c,d,e,f,g,h)
-#define RND27(a,b,c,d,e,f,g,h) RND03(a,b,c,d,e,f,g,h)
-#define RND28(a,b,c,d,e,f,g,h) RND04(a,b,c,d,e,f,g,h)
-#define RND29(a,b,c,d,e,f,g,h) RND05(a,b,c,d,e,f,g,h)
-#define RND30(a,b,c,d,e,f,g,h) RND06(a,b,c,d,e,f,g,h)
-#define RND31(a,b,c,d,e,f,g,h) RND07(a,b,c,d,e,f,g,h)
-
-#define InvRND08(a,b,c,d,e,f,g,h) InvRND00(a,b,c,d,e,f,g,h)
-#define InvRND09(a,b,c,d,e,f,g,h) InvRND01(a,b,c,d,e,f,g,h)
-#define InvRND10(a,b,c,d,e,f,g,h) InvRND02(a,b,c,d,e,f,g,h)
-#define InvRND11(a,b,c,d,e,f,g,h) InvRND03(a,b,c,d,e,f,g,h)
-#define InvRND12(a,b,c,d,e,f,g,h) InvRND04(a,b,c,d,e,f,g,h)
-#define InvRND13(a,b,c,d,e,f,g,h) InvRND05(a,b,c,d,e,f,g,h)
-#define InvRND14(a,b,c,d,e,f,g,h) InvRND06(a,b,c,d,e,f,g,h)
-#define InvRND15(a,b,c,d,e,f,g,h) InvRND07(a,b,c,d,e,f,g,h)
-#define InvRND16(a,b,c,d,e,f,g,h) InvRND00(a,b,c,d,e,f,g,h)
-#define InvRND17(a,b,c,d,e,f,g,h) InvRND01(a,b,c,d,e,f,g,h)
-#define InvRND18(a,b,c,d,e,f,g,h) InvRND02(a,b,c,d,e,f,g,h)
-#define InvRND19(a,b,c,d,e,f,g,h) InvRND03(a,b,c,d,e,f,g,h)
-#define InvRND20(a,b,c,d,e,f,g,h) InvRND04(a,b,c,d,e,f,g,h)
-#define InvRND21(a,b,c,d,e,f,g,h) InvRND05(a,b,c,d,e,f,g,h)
-#define InvRND22(a,b,c,d,e,f,g,h) InvRND06(a,b,c,d,e,f,g,h)
-#define InvRND23(a,b,c,d,e,f,g,h) InvRND07(a,b,c,d,e,f,g,h)
-#define InvRND24(a,b,c,d,e,f,g,h) InvRND00(a,b,c,d,e,f,g,h)
-#define InvRND25(a,b,c,d,e,f,g,h) InvRND01(a,b,c,d,e,f,g,h)
-#define InvRND26(a,b,c,d,e,f,g,h) InvRND02(a,b,c,d,e,f,g,h)
-#define InvRND27(a,b,c,d,e,f,g,h) InvRND03(a,b,c,d,e,f,g,h)
-#define InvRND28(a,b,c,d,e,f,g,h) InvRND04(a,b,c,d,e,f,g,h)
-#define InvRND29(a,b,c,d,e,f,g,h) InvRND05(a,b,c,d,e,f,g,h)
-#define InvRND30(a,b,c,d,e,f,g,h) InvRND06(a,b,c,d,e,f,g,h)
-#define InvRND31(a,b,c,d,e,f,g,h) InvRND07(a,b,c,d,e,f,g,h)
-
-/* Linear transformations and key mixing: */
-
-#define ROL(x,n) ((((uint32_t)(x))<<(n))| \
- (((uint32_t)(x))>>(32-(n))))
-#define ROR(x,n) ((((uint32_t)(x))<<(32-(n)))| \
- (((uint32_t)(x))>>(n)))
-
-#define transform(x0, x1, x2, x3, y0, y1, y2, y3) \
- y0 = ROL(x0, 13); \
- y2 = ROL(x2, 3); \
- y1 = x1 ^ y0 ^ y2; \
- y3 = x3 ^ y2 ^ ((uint32_t)y0)<<3; \
- y1 = ROL(y1, 1); \
- y3 = ROL(y3, 7); \
- y0 = y0 ^ y1 ^ y3; \
- y2 = y2 ^ y3 ^ ((uint32_t)y1<<7); \
- y0 = ROL(y0, 5); \
- y2 = ROL(y2, 22)
-
-#define inv_transform(x0, x1, x2, x3, y0, y1, y2, y3) \
- y2 = ROR(x2, 22);\
- y0 = ROR(x0, 5); \
- y2 = y2 ^ x3 ^ ((uint32_t)x1<<7); \
- y0 = y0 ^ x1 ^ x3; \
- y3 = ROR(x3, 7); \
- y1 = ROR(x1, 1); \
- y3 = y3 ^ y2 ^ ((uint32_t)y0)<<3; \
- y1 = y1 ^ y0 ^ y2; \
- y2 = ROR(y2, 3); \
- y0 = ROR(y0, 13)
-
-#define keying(x0, x1, x2, x3, subkey) \
- x0^=subkey[0];x1^=subkey[1]; \
- x2^=subkey[2];x3^=subkey[3]
-
-/* PHI: Constant used in the key schedule */
-#define PHI 0x9e3779b9L
-
-#endif /* SERPENT_SBOXES_H_INCLUDED */