]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
* src/symmetric/twofish.c, src/symmetric/twofish.h
authorNiels Möller <nisse@lysator.liu.se>
Fri, 5 Mar 1999 02:34:24 +0000 (03:34 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Fri, 5 Mar 1999 02:34:24 +0000 (03:34 +0100)
(twofish_selftest): Made non static.
(twofish_setup): Removed memory allocation. Instead, a
TWOFISH_pointer is given as an argument.
(twofish_encrypt, twofish_decrypt): Use correct pointer types. No
void * or casts.

Rev: src/symmetric/include/twofish.h:1.2
Rev: src/symmetric/twofish.c:1.2

include/twofish.h
twofish.c

index 9b3356dc1b140f18a0ffb3ee44b1931847248581..a955ea922d3d2370701f069094f5cbe7ff6ebad3 100644 (file)
@@ -1,3 +1,8 @@
+/* twofish.h
+ *
+ * $Id$
+ */
+
 /*
  * twofish - An implementation of the twofish cipher.
  * Copyright (C) 1999 Ruud de Rooij <ruud@debian.org>
@@ -50,52 +55,53 @@ typedef struct {
     UINT32 s_box[4][256];
 } TWOFISH_context;
 
-/* TWOFISH_context * twofish_setup(size_t keysize, const void * key);
+/* Set up internal tables required for twofish encryption and decryption.
  *
- * Set up internal tables required for twofish encryption and decryption.
- *
- * The key size is specified in bytes.  Key sizes up to 32 bytes are
- * supported.  Larger key sizes are silently truncated.  The function
- * returns a pointer which must be passed as the first argument to
- * twofish_encrypt() and twofish_decrypt().  When no more encryption or
- * decryption with this key is to be performed, the storage for the tables
- * can be reclaimed with the free() function.
- * If no memory is available to store the tables, twofish_setup()
- * returns NULL.
- */
+ * The key size is specified in bytes. Key sizes up to 32 bytes are
+ * supported. Larger key sizes are silently truncated. */
 
-TWOFISH_context * twofish_setup(size_t keysize, const void *key);
+void
+twofish_setup(TWOFISH_context *ctx, size_t keysize, const UINT8 *key);
 
-/* void twofish_encrypt(void * context,
- *                      const void * plaintext,
- *                      void * ciphertext);
+/* void twofish_encrypt(TWOFISH_context *context,
+ *                      const UINT8 *plaintext,
+ *                      UINT8 *ciphertext);
  *
  * Encrypt 16 bytes of data with the twofish algorithm.
  *
  * Before this function can be used, twofish_setup() must be used in order to
  * set up various tables required for the encryption algorithm.
- * The first argument is the handle returned from twofish_setup().
+ * 
  * This function always encrypts 16 bytes of plaintext to 16 bytes of
  * ciphertext.  The memory areas of the plaintext and the ciphertext can
  * overlap.
  */
 
-void twofish_encrypt(void *context, const void *plaintext, void *ciphertext);
+void
+twofish_encrypt(TWOFISH_context *context,
+               const UINT8 *plaintext,
+               UINT8 *ciphertext);
 
-/* void twofish_decrypt(void * context,
- *                      const void * ciphertext,
- *                      void * plaintext);
+/* void twofish_decrypt(TWOFISH_context *context,
+ *                      const UINT8 *ciphertext,
+ *                      UINT8 *plaintext);
  *
  * Decrypt 16 bytes of data with the twofish algorithm.
  *
  * Before this function can be used, twofish_setup() must be used in order to
  * set up various tables required for the decryption algorithm.
- * The first argument is the handle returned from twofish_setup().
+ * 
  * This function always decrypts 16 bytes of ciphertext to 16 bytes of
  * plaintext.  The memory areas of the plaintext and the ciphertext can
  * overlap.
  */
 
-void twofish_decrypt(void *context, const void *ciphertext, void *plaintext);
+void
+twofish_decrypt(TWOFISH_context *context,
+               const UINT8 *ciphertext,
+               UINT8 *plaintext);
+
+int
+twofish_selftest(void);
 
-#endif
+#endif /* TWOFISH_H */
index ea02973067265952a4bdbbc96d547a5cba79bbb5..cc7e606d947149288e6cb5e268e0394a5fcd40c3 100644 (file)
--- a/twofish.c
+++ b/twofish.c
@@ -1,5 +1,9 @@
-/*
- * twofish - An implementation of the twofish cipher.
+/* twofish.c
+ *
+ * $Id$
+ */
+  
+/* twofish - An implementation of the twofish cipher.
  * Copyright (C) 1999 Ruud de Rooij <ruud@debian.org>
  *
  * Modifications for lsh, integrated testing
@@ -72,21 +76,23 @@ typedef UINT32 word;
 static void
 bytes_to_words(word *dest, const byte *src, int n)
 {
-    while (n-- > 0) {
-        *dest++ = src[0] | src[1] << 8 | src[2] << 16 | src[3] << 24;
-        src += 4;
+  while (n-- > 0)
+    {
+      *dest++ = src[0] | src[1] << 8 | src[2] << 16 | src[3] << 24;
+      src += 4;
     }
 }
 
 static void
 words_to_bytes(byte *dest, const word *src, int n)
 {
-    while (n-- > 0) {
-        *dest++ = *src;
-        *dest++ = *src >> 8;
-        *dest++ = *src >> 16;
-        *dest++ = *src >> 24;
-        src++;
+  while (n-- > 0)
+    {
+      *dest++ = *src;
+      *dest++ = *src >> 8;
+      *dest++ = *src >> 16;
+      *dest++ = *src >> 24;
+      src++;
     }
 }
 
@@ -184,15 +190,16 @@ static byte q1[] = { 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
 static byte
 gf_multiply(byte p, byte a, byte b)
 {
-    word shift  = b;
-    byte result = 0;
-    while (a) {
-        if (a & 1) result ^= shift;
-        a = a >> 1;
-        shift = shift << 1;
-        if (shift & 0x100) shift ^= p;
+  word shift  = b;
+  byte result = 0;
+  while (a)
+    {
+      if (a & 1) result ^= shift;
+      a = a >> 1;
+      shift = shift << 1;
+      if (shift & 0x100) shift ^= p;
     }
-    return result;
+  return result;
 }
 
 /* ------------------------------------------------------------------------- */
@@ -218,18 +225,18 @@ static byte rs_matrix[4][8] = {
 static word
 compute_s(word m1, word m2)
 {
-    word s = 0;
-    int i;
-    for (i = 0; i < 4; i++)
-        s |=  ((  gf_multiply(0x4D, m1,       rs_matrix[i][0])
-                ^ gf_multiply(0x4D, m1 >> 8,  rs_matrix[i][1])
-                ^ gf_multiply(0x4D, m1 >> 16, rs_matrix[i][2])
-                ^ gf_multiply(0x4D, m1 >> 24, rs_matrix[i][3])
-                ^ gf_multiply(0x4D, m2,       rs_matrix[i][4])
-                ^ gf_multiply(0x4D, m2 >> 8,  rs_matrix[i][5])
-                ^ gf_multiply(0x4D, m2 >> 16, rs_matrix[i][6])
-                ^ gf_multiply(0x4D, m2 >> 24, rs_matrix[i][7])) << (i*8));
-    return s;
+  word s = 0;
+  int i;
+  for (i = 0; i < 4; i++)
+    s |=  ((  gf_multiply(0x4D, m1,       rs_matrix[i][0])
+           ^ gf_multiply(0x4D, m1 >> 8,  rs_matrix[i][1])
+           ^ gf_multiply(0x4D, m1 >> 16, rs_matrix[i][2])
+           ^ gf_multiply(0x4D, m1 >> 24, rs_matrix[i][3])
+           ^ gf_multiply(0x4D, m2,       rs_matrix[i][4])
+           ^ gf_multiply(0x4D, m2 >> 8,  rs_matrix[i][5])
+           ^ gf_multiply(0x4D, m2 >> 16, rs_matrix[i][6])
+           ^ gf_multiply(0x4D, m2 >> 24, rs_matrix[i][7])) << (i*8));
+  return s;
 }
 
 /* ------------------------------------------------------------------------- */
@@ -246,9 +253,9 @@ static byte * q_table[4][5] = { { q1, q1, q0, q0, q1 },
 /* The matrix MDS as specified in section 4.3.2 of the twofish paper. */
 
 static byte mds_matrix[4][4] = { { 0x01, 0xEF, 0x5B, 0x5B },
-                                { 0x5B, 0xEF, 0xEF, 0x01 },
-                                { 0xEF, 0x5B, 0x01, 0xEF },
-                                { 0xEF, 0x01, 0xEF, 0x5B } };
+                                { 0x5B, 0xEF, 0xEF, 0x01 },
+                                { 0xEF, 0x5B, 0x01, 0xEF },
+                                { 0xEF, 0x01, 0xEF, 0x5B } };
 
 /* word h_byte(int k, int i, byte x, byte l0, byte l1, byte l2, byte l3);
  *
@@ -266,15 +273,15 @@ static byte mds_matrix[4][4] = { { 0x01, 0xEF, 0x5B, 0x5B },
 static word
 h_byte(int k, int i, byte x, byte l0, byte l1, byte l2, byte l3)
 {
-    byte y = q_table[i][4][l0 ^
-                 q_table[i][3][l1 ^
-                     q_table[i][2][k == 2 ? x : l2 ^
-                         q_table[i][1][k == 3 ? x : l3 ^ q_table[i][0][x]]]]];
-
-    return ((word)gf_multiply(0x69, mds_matrix[0][i], y))       |
-           ((word)gf_multiply(0x69, mds_matrix[1][i], y) << 8)  |
-           ((word)gf_multiply(0x69, mds_matrix[2][i], y) << 16) |
-           ((word)gf_multiply(0x69, mds_matrix[3][i], y) << 24);
+  byte y = q_table[i][4][l0 ^
+            q_table[i][3][l1 ^
+              q_table[i][2][k == 2 ? x : l2 ^
+                q_table[i][1][k == 3 ? x : l3 ^ q_table[i][0][x]]]]];
+
+  return ( ((word)gf_multiply(0x69, mds_matrix[0][i], y))
+          | ((word)gf_multiply(0x69, mds_matrix[1][i], y) << 8)
+          | ((word)gf_multiply(0x69, mds_matrix[2][i], y) << 16)
+          | ((word)gf_multiply(0x69, mds_matrix[3][i], y) << 24) );
 }
 
 /* word h(int k, byte x, word l0, word l1, word l2, word l3);
@@ -285,75 +292,76 @@ h_byte(int k, int i, byte x, byte l0, byte l1, byte l2, byte l3)
 static word
 h(int k, byte x, word l0, word l1, word l2, word l3)
 {
-    return   h_byte(k, 0, x, l0,       l1,       l2,       l3)
-           ^ h_byte(k, 1, x, l0 >> 8,  l1 >> 8,  l2 >> 8,  l3 >> 8)
-           ^ h_byte(k, 2, x, l0 >> 16, l1 >> 16, l2 >> 16, l3 >> 16)
-           ^ h_byte(k, 3, x, l0 >> 24, l1 >> 24, l2 >> 24, l3 >> 24);
+  return (  h_byte(k, 0, x, l0,       l1,       l2,       l3)
+         ^ h_byte(k, 1, x, l0 >> 8,  l1 >> 8,  l2 >> 8,  l3 >> 8)
+         ^ h_byte(k, 2, x, l0 >> 16, l1 >> 16, l2 >> 16, l3 >> 16)
+         ^ h_byte(k, 3, x, l0 >> 24, l1 >> 24, l2 >> 24, l3 >> 24) );
 }
 
 
 /*
  * Sanity check using the test vectors from appendix 2 of the Twofish paper.
  */
-static int
-twofish_selftest(void) {
+int
+twofish_selftest(void)
+{
   byte testkey128[16] =
-       { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
   byte ciphertext128[16] =
-       {
-        0x5D, 0x9D, 0x4E, 0xEF, 0xFA, 0x91, 0x51, 0x57,
-        0x55, 0x24, 0xF1, 0x15, 0x81, 0x5A, 0x12, 0xE0 };
+  {
+    0x5D, 0x9D, 0x4E, 0xEF, 0xFA, 0x91, 0x51, 0x57,
+    0x55, 0x24, 0xF1, 0x15, 0x81, 0x5A, 0x12, 0xE0 };
 
   byte testkey192[24] =
-       { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
-         0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
+  { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
   byte ciphertext192[16] =
-       { 0xE7, 0x54, 0x49, 0x21, 0x2B, 0xEE, 0xF9, 0xF4,
-        0xA3, 0x90, 0xBD, 0x86, 0x0A, 0x64, 0x09, 0x41 };
+  { 0xE7, 0x54, 0x49, 0x21, 0x2B, 0xEE, 0xF9, 0xF4,
+    0xA3, 0x90, 0xBD, 0x86, 0x0A, 0x64, 0x09, 0x41 };
 
   byte testkey256[32] =
-       { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
-         0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
-         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-         0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
+  { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+    0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
   byte ciphertext256[16] =
-       { 0x37, 0xFE, 0x26, 0xFF, 0x1C, 0xF6, 0x61, 0x75,
-        0xF5, 0xDD, 0xF4, 0xC3, 0x3B, 0x97, 0xA2, 0x05 };
+  { 0x37, 0xFE, 0x26, 0xFF, 0x1C, 0xF6, 0x61, 0x75,
+    0xF5, 0xDD, 0xF4, 0xC3, 0x3B, 0x97, 0xA2, 0x05 };
 
-  TWOFISH_context context;
+  TWOFISH_context context;
   int i;
   byte plaintext[16], ciphertext[16];
 
-  context = twofish_setup(16, testkey128);
-  bzero(plaintext, 16);
+  twofish_setup(&context, 16, testkey128);
+  memset(plaintext, 0, 16);
 
   for (i = 0 ; i < 50; i++) {
-     twofish_encrypt(context, plaintext, ciphertext);
-     memcpy(plaintext, ciphertext, 16);
+    twofish_encrypt(&context, plaintext, ciphertext);
+    memcpy(plaintext, ciphertext, 16);
   }
   if (!memcmp(ciphertext, ciphertext128, 16)) {
     return 0;
   }
 
-  context = twofish_setup(24, testkey192);
-  bzero(plaintext, 16);
+  twofish_setup(&context, 24, testkey192);
+  memset(plaintext, 0, 16);
 
   for (i = 0 ; i < 50; i++) {
-     twofish_encrypt(context, plaintext, ciphertext);
-     memcpy(plaintext, ciphertext, 16);
+    twofish_encrypt(&context, plaintext, ciphertext);
+    memcpy(plaintext, ciphertext, 16);
   }
   if (!memcmp(ciphertext, ciphertext192, 16)) {
     return 0;
   }
 
-  context = twofish_setup(32, testkey256);
-  bzero(plaintext, 16);
+  twofish_setup(&context, 32, testkey256);
+  memset(plaintext, 0, 16);
 
   for (i = 0 ; i < 50; i++) {
-     twofish_encrypt(context, plaintext, ciphertext);
-     memcpy(plaintext, ciphertext, 16);
+    twofish_encrypt(&context, plaintext, ciphertext);
+    memcpy(plaintext, ciphertext, 16);
   }
   if (!memcmp(ciphertext, ciphertext256, 16)) {
     return 0;
@@ -371,204 +379,203 @@ twofish_selftest(void) {
  */
 
 
-/* TWOFISH_context * twofish_setup(size_t keysize, const void * key);
+/* void twofish_setup(TWOFISH_context *ctx, size_t keysize, const UINT8 * key);
  *
  * Set up internal tables required for twofish encryption and decryption.
  *
  * The key size is specified in bytes.  Key sizes up to 32 bytes are
- * supported.  Larger key sizes are silently truncated.  The function
- * returns a pointer which must be passed as the first argument to
- * twofish_encrypt() and twofish_decrypt().  When no more encryption or
- * decryption with this key is to be performed, the storage for the tables
- * can be reclaimed with the free() function.
- * If no memory is available to store the tables, twofish_setup()
- * returns NULL.
+ * supported.  Larger key sizes are silently truncated.  
  */
 
-TWOFISH_context *
-twofish_setup(size_t keysize, const void *key)
+void
+twofish_setup(TWOFISH_context * context, size_t keysize, const UINT8 *key)
 {
-    TWOFISH_context * context = malloc(sizeof (TWOFISH_context));
-    byte key_copy[32];
-    word m[8], s[4], t;
-    int i, j, k;
+  byte key_copy[32];
+  word m[8], s[4], t;
+  int i, j, k;
 
 #ifndef NDEBUG
-    static int initialized = 0;
+  static int initialized = 0;
 
-    if (!initialized) {
-         initialized = 1;
-         assert(twofish_selftest());
+  if (!initialized)
+    {
+      initialized = 1;
+      assert(twofish_selftest());
     }
 #endif
 
-    if (!context)
-        return NULL;
-
-    /* Extend or truncate key as necessary */
-
-    memset(key_copy, 0, 32);
-    if (keysize > 32) keysize =32;
-    memcpy(key_copy, key, keysize);
-
-    bytes_to_words(m, key_copy, keysize/4);
-
-    if (keysize <= 16)
-        k = 2;
-    else if (keysize <= 24)
-        k = 3;
-    else
-        k = 4;
-
-    /* Compute sub-keys */
-
-    for (i = 0; i < 20; i++) {
-        t = h(k, 2*i+1, m[1], m[3], m[5], m[7]);
-        t = rol8(t);
-        t += (context->keys[2*i] =
-                   t + h(k, 2*i, m[0], m[2], m[4], m[6]));
-        t = rol9(t);
-        context->keys[2*i+1] = t;
+  /* Extend or truncate key as necessary */
+
+  memset(key_copy, 0, 32);
+  if (keysize > 32)
+    keysize = 32;
+  memcpy(key_copy, key, keysize);
+
+  /* FIXME: This truncates the key if it is not a multiple of 4 octets.
+   * Is this really indended? */
+  bytes_to_words(m, key_copy, keysize/4);
+
+  if (keysize <= 16)
+    k = 2;
+  else if (keysize <= 24)
+    k = 3;
+  else
+    k = 4;
+
+  /* Compute sub-keys */
+
+  for (i = 0; i < 20; i++)
+    {
+      t = h(k, 2*i+1, m[1], m[3], m[5], m[7]);
+      t = rol8(t);
+      t += (context->keys[2*i] =
+           t + h(k, 2*i, m[0], m[2], m[4], m[6]));
+      t = rol9(t);
+      context->keys[2*i+1] = t;
     }
 
-    /* Compute key-dependent S-boxes */
+  /* Compute key-dependent S-boxes */
 
-    for (i = 0; i < k; i++)
-        s[k-1-i] = compute_s(m[2*i], m[2*i+1]);
+  for (i = 0; i < k; i++)
+    s[k-1-i] = compute_s(m[2*i], m[2*i+1]);
 
-    for (i = 0; i < 4; i++)
-        for (j = 0; j < 256; j++)
-            context->s_box[i][j] = h_byte(k, i, j, s[0] >> (i*8),
-                                                   s[1] >> (i*8),
-                                                   s[2] >> (i*8),
-                                                   s[3] >> (i*8));
-    return context;
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 256; j++)
+      context->s_box[i][j] = h_byte(k, i, j,
+                                   s[0] >> (i*8),
+                                   s[1] >> (i*8),
+                                   s[2] >> (i*8),
+                                   s[3] >> (i*8));
 }
 
-/* void twofish_encrypt(void * context,
- *                      const void * plaintext,
- *                      void * ciphertext);
+/* void twofish_encrypt(TWOFISH_context *context,
+ *                      const UINT8 *plaintext,
+ *                      UINT8 *ciphertext);
  *
  * Encrypt 16 bytes of data with the twofish algorithm.
  *
  * Before this function can be used, twofish_setup() must be used in order to
  * set up various tables required for the encryption algorithm.
- * The first argument is the handle returned from twofish_setup().
+ * 
  * This function always encrypts 16 bytes of plaintext to 16 bytes of
  * ciphertext.  The memory areas of the plaintext and the ciphertext can
  * overlap.
  */
 
 void
-twofish_encrypt(void *context, const void *plaintext, void *ciphertext)
+twofish_encrypt(TWOFISH_context *context,
+               const UINT8 *plaintext,
+               UINT8 *ciphertext)
 {
-    word words[4];
-    word r0, r1, r2, r3, t0, t1;
-    int i;
-    word * keys        = ((TWOFISH_context *)context)->keys;
-    word (*s_box)[256] = ((TWOFISH_context *)context)->s_box;
-
-    bytes_to_words(words, plaintext, 4);
-
-    r0 = words[0] ^ keys[0];
-    r1 = words[1] ^ keys[1];
-    r2 = words[2] ^ keys[2];
-    r3 = words[3] ^ keys[3];
-
-    for (i = 0; i < 8; i++) {
-        t1 =   s_box[1][r1 & 0xFF]
-             ^ s_box[2][(r1 >> 8) & 0xFF]
-             ^ s_box[3][(r1 >> 16) & 0xFF]
-             ^ s_box[0][(r1 >> 24) & 0xFF];
-        t0 = (  s_box[0][r0 & 0xFF]
-              ^ s_box[1][(r0 >> 8) & 0xFF]
-              ^ s_box[2][(r0 >> 16) & 0xFF]
-              ^ s_box[3][(r0 >> 24) & 0xFF]) + t1;
-        r3 = (t1 + t0 + keys[4*i+9]) ^ rol1(r3);
-        r2 = (t0 + keys[4*i+8]) ^ r2;
-        r2 = ror1(r2);
-
-        t1 =   s_box[1][r3 & 0xFF]
-             ^ s_box[2][(r3 >> 8) & 0xFF]
-             ^ s_box[3][(r3 >> 16) & 0xFF]
-             ^ s_box[0][(r3 >> 24) & 0xFF];
-        t0 = (  s_box[0][r2 & 0xFF]
-              ^ s_box[1][(r2 >> 8) & 0xFF]
-              ^ s_box[2][(r2 >> 16) & 0xFF]
-              ^ s_box[3][(r2 >> 24) & 0xFF]) + t1;
-        r1 = (t1 + t0 + keys[4*i+11]) ^ rol1(r1);
-        r0 = (t0 + keys[4*i+10]) ^ r0;
-        r0 = ror1(r0);
-    }
+  word words[4];
+  word r0, r1, r2, r3, t0, t1;
+  int i;
+  word * keys        = context->keys;
+  word (*s_box)[256] = context->s_box;
+
+  bytes_to_words(words, plaintext, 4);
+
+  r0 = words[0] ^ keys[0];
+  r1 = words[1] ^ keys[1];
+  r2 = words[2] ^ keys[2];
+  r3 = words[3] ^ keys[3];
+
+  for (i = 0; i < 8; i++) {
+    t1 = (  s_box[1][r1 & 0xFF]
+         ^ s_box[2][(r1 >> 8) & 0xFF]
+         ^ s_box[3][(r1 >> 16) & 0xFF]
+         ^ s_box[0][(r1 >> 24) & 0xFF]);
+    t0 = (  s_box[0][r0 & 0xFF]
+         ^ s_box[1][(r0 >> 8) & 0xFF]
+         ^ s_box[2][(r0 >> 16) & 0xFF]
+         ^ s_box[3][(r0 >> 24) & 0xFF]) + t1;
+    r3 = (t1 + t0 + keys[4*i+9]) ^ rol1(r3);
+    r2 = (t0 + keys[4*i+8]) ^ r2;
+    r2 = ror1(r2);
+
+    t1 = (  s_box[1][r3 & 0xFF]
+         ^ s_box[2][(r3 >> 8) & 0xFF]
+         ^ s_box[3][(r3 >> 16) & 0xFF]
+         ^ s_box[0][(r3 >> 24) & 0xFF]);
+    t0 = (  s_box[0][r2 & 0xFF]
+         ^ s_box[1][(r2 >> 8) & 0xFF]
+         ^ s_box[2][(r2 >> 16) & 0xFF]
+         ^ s_box[3][(r2 >> 24) & 0xFF]) + t1;
+    r1 = (t1 + t0 + keys[4*i+11]) ^ rol1(r1);
+    r0 = (t0 + keys[4*i+10]) ^ r0;
+    r0 = ror1(r0);
+  }
 
-    words[0] = r2 ^ keys[4];
-    words[1] = r3 ^ keys[5];
-    words[2] = r0 ^ keys[6];
-    words[3] = r1 ^ keys[7];
+  words[0] = r2 ^ keys[4];
+  words[1] = r3 ^ keys[5];
+  words[2] = r0 ^ keys[6];
+  words[3] = r1 ^ keys[7];
 
-    words_to_bytes(ciphertext, words, 4);
+  words_to_bytes(ciphertext, words, 4);
 }
 
-/* void twofish_decrypt(void * context,
- *                      const void * ciphertext,
- *                      void * plaintext);
+/* void twofish_decrypt(TWOFISH_context *context,
+ *                      const UINT8 *ciphertext,
+ *                      UINT8 *plaintext);
  *
  * Decrypt 16 bytes of data with the twofish algorithm.
  *
  * Before this function can be used, twofish_setup() must be used in order to
  * set up various tables required for the decryption algorithm.
- * The first argument is the handle returned from twofish_setup().
+ * 
  * This function always decrypts 16 bytes of ciphertext to 16 bytes of
  * plaintext.  The memory areas of the plaintext and the ciphertext can
  * overlap.
  */
 
 void
-twofish_decrypt(void *context, const void *ciphertext, void *plaintext)
+twofish_decrypt(TWOFISH_context *context,
+               const UINT8 *ciphertext,
+               UINT8 *plaintext)
 {
-    word words[4];
-    word r0, r1, r2, r3, t0, t1;
-    int i;
-    word * keys  = ((TWOFISH_context *)context)->keys;
-    word (*s_box)[256] = ((TWOFISH_context *)context)->s_box;
-
-    bytes_to_words(words, ciphertext, 4);
-
-    r0 = words[2] ^ keys[6];
-    r1 = words[3] ^ keys[7];
-    r2 = words[0] ^ keys[4];
-    r3 = words[1] ^ keys[5];
-
-    for (i = 0; i < 8; i++) {
-        t1 =   s_box[1][r3 & 0xFF]
-             ^ s_box[2][(r3 >> 8) & 0xFF]
-             ^ s_box[3][(r3 >> 16) & 0xFF]
-             ^ s_box[0][(r3 >> 24) & 0xFF];
-        t0 = (  s_box[0][r2 & 0xFF]
-              ^ s_box[1][(r2 >> 8) & 0xFF]
-              ^ s_box[2][(r2 >> 16) & 0xFF]
-              ^ s_box[3][(r2 >> 24) & 0xFF]) + t1;
-        r1 = (t1 + t0 + keys[39-4*i]) ^ r1;
-        r1 = ror1(r1);
-        r0 = (t0 + keys[38-4*i]) ^ rol1(r0);
-
-        t1 =   s_box[1][r1 & 0xFF]
-             ^ s_box[2][(r1 >> 8) & 0xFF]
-             ^ s_box[3][(r1 >> 16) & 0xFF]
-             ^ s_box[0][(r1 >> 24) & 0xFF];
-        t0 = (  s_box[0][r0 & 0xFF]
-              ^ s_box[1][(r0 >> 8) & 0xFF]
-              ^ s_box[2][(r0 >> 16) & 0xFF]
-              ^ s_box[3][(r0 >> 24) & 0xFF]) + t1;
-        r3 = (t1 + t0 + keys[37-4*i]) ^ r3;
-        r3 = ror1(r3);
-        r2 = (t0 + keys[36-4*i]) ^ rol1(r2);
-    }
+  word words[4];
+  word r0, r1, r2, r3, t0, t1;
+  int i;
+  word *keys  = context->keys;
+  word (*s_box)[256] = context->s_box;
+
+  bytes_to_words(words, ciphertext, 4);
+
+  r0 = words[2] ^ keys[6];
+  r1 = words[3] ^ keys[7];
+  r2 = words[0] ^ keys[4];
+  r3 = words[1] ^ keys[5];
+
+  for (i = 0; i < 8; i++) {
+    t1 = (  s_box[1][r3 & 0xFF]
+         ^ s_box[2][(r3 >> 8) & 0xFF]
+         ^ s_box[3][(r3 >> 16) & 0xFF]
+         ^ s_box[0][(r3 >> 24) & 0xFF]);
+    t0 = (  s_box[0][r2 & 0xFF]
+         ^ s_box[1][(r2 >> 8) & 0xFF]
+         ^ s_box[2][(r2 >> 16) & 0xFF]
+         ^ s_box[3][(r2 >> 24) & 0xFF]) + t1;
+    r1 = (t1 + t0 + keys[39-4*i]) ^ r1;
+    r1 = ror1(r1);
+    r0 = (t0 + keys[38-4*i]) ^ rol1(r0);
+
+    t1 = (  s_box[1][r1 & 0xFF]
+         ^ s_box[2][(r1 >> 8) & 0xFF]
+         ^ s_box[3][(r1 >> 16) & 0xFF]
+         ^ s_box[0][(r1 >> 24) & 0xFF]);
+    t0 = (  s_box[0][r0 & 0xFF]
+         ^ s_box[1][(r0 >> 8) & 0xFF]
+         ^ s_box[2][(r0 >> 16) & 0xFF]
+         ^ s_box[3][(r0 >> 24) & 0xFF]) + t1;
+    r3 = (t1 + t0 + keys[37-4*i]) ^ r3;
+    r3 = ror1(r3);
+    r2 = (t0 + keys[36-4*i]) ^ rol1(r2);
+  }
 
-    words[0] = r0 ^ keys[0];
-    words[1] = r1 ^ keys[1];
-    words[2] = r2 ^ keys[2];
-    words[3] = r3 ^ keys[3];
+  words[0] = r0 ^ keys[0];
+  words[1] = r1 ^ keys[1];
+  words[2] = r2 ^ keys[2];
+  words[3] = r3 ^ keys[3];
 
-    words_to_bytes(plaintext, words, 4);
+  words_to_bytes(plaintext, words, 4);
 }