]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Serpent rewrite.
authorSimon Josefsson <simon@josefsson.org>
Tue, 31 May 2011 20:56:10 +0000 (22:56 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Tue, 31 May 2011 20:56:10 +0000 (22:56 +0200)
Rev: nettle/ChangeLog:1.170
Rev: nettle/Makefile.in:1.33
Rev: nettle/serpent.c:1.4
Rev: nettle/serpent_sboxes.h:1.2(DEAD)

ChangeLog
Makefile.in
serpent.c
serpent_sboxes.h [deleted file]

index a8338e4c0244d856d54b730dacd6df81dcda3f64..96a910f2a7a59974201efd20f385057eaadac092 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-05-30  Simon Josefsson  <simon@josefsson.org>
+
+       * serpent.c: Rewrite, based on libgcrypt code.  License changed
+       from GPL to LGPL.
+       * serpent_sboxes.h: Removed.
+       * Makefile.in: Drop serpent_sboxes.h.
+
 2011-05-31  Niels Möller  <nisse@lysator.liu.se>
 
        * testsuite/serpent-test.c (test_main): Added some tests for
index d71a712734458a2f00d4457abf3be6d8662061fc..6b4948b5276897a36a17cc6bc2f56af39c6b200b 100644 (file)
@@ -128,7 +128,7 @@ DISTFILES = $(SOURCES) $(HEADERS) .bootstrap aclocal.m4 configure.ac \
        README AUTHORS COPYING COPYING.LIB INSTALL NEWS TODO ChangeLog \
        memxor.c $(des_headers) descore.README \
        aes-internal.h camellia-internal.h cast128_sboxes.h desinfo.h desCode.h \
-       serpent_sboxes.h nettle-internal.h nettle-write.h prime-list.h \
+       nettle-internal.h nettle-write.h prime-list.h \
        asm.m4 \
        nettle.texinfo nettle.info nettle.html nettle.pdf sha-example.c
 
index c88192d2dc4d7a88aae8d2b4f684e2a01f284a9c..1667d65f5191df0d474972ab4e5b71a8d0dfa3e3 100644 (file)
--- a/serpent.c
+++ b/serpent.c
@@ -1,4 +1,4 @@
-/* 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]);
+  }
 }
diff --git a/serpent_sboxes.h b/serpent_sboxes.h
deleted file mode 100644 (file)
index 0dc0787..0000000
+++ /dev/null
@@ -1,511 +0,0 @@
-/* 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 */