* gpgkeys_ldap.c (get_key): Fix typo in deduping code.
[gnupg.git] / cipher / twofish.c
index d93c145..a6a571f 100644 (file)
@@ -1,5 +1,10 @@
 /* Twofish for GPG
  * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ *
+ * The original author has disclaimed all copyright interest in this
+ * code and thus putting it in the public domain.
  *
  * This code is a "clean room" implementation, written from the paper
  * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
@@ -11,7 +16,7 @@
  * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
  * Third Edition.
  *
- * Only the 128-bit block size is supported at present.  This code is intended
+ * Only the 128- and 256-bit key sizes are supported.  This code is intended
  * for GNU C on a 32-bit system, but it should work almost anywhere.  Loops
  * are unrolled, precomputation tables are used, etc., for maximum speed at
  * some cost in memory consumption. */
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h> /* for assert() */
 #include <string.h> /* for memcmp() */
 
 #include "types.h"  /* for byte and u32 typedefs */
-#include "util.h"   /* for log_fatal() */
+#include "util.h"
+#include "errors.h"
+#include "algorithms.h"
 
 /* Prototype for the self-test function. */
-static void selftest(void);
-
-/* Macros used by the info function. */
-#define FNCCAST_SETKEY(f)  ((int(*)(void*, byte*, unsigned))(f))
-#define FNCCAST_CRYPT(f)   ((void(*)(void*, byte*, byte*))(f))
+static const char *selftest(void);
 
 /* Structure for an expanded Twofish key.  s contains the key-dependent
  * S-boxes composed with the MDS matrix; w contains the eight "whitening"
@@ -386,6 +388,75 @@ static const byte exp_to_poly[492] = {
    0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
 };
 \f
+
+/* The table constants are indices of
+ * S-box entries, preprocessed through q0 and q1. */
+static byte calc_sb_tbl[512] = {
+    0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
+    0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
+    0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
+    0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
+    0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
+    0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
+    0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
+    0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
+    0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
+    0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
+    0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
+    0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
+    0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
+    0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
+    0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
+    0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
+    0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
+    0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
+    0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
+    0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
+    0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
+    0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
+    0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
+    0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
+    0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
+    0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
+    0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
+    0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
+    0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
+    0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
+    0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
+    0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
+    0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
+    0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
+    0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
+    0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
+    0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
+    0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
+    0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
+    0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
+    0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
+    0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
+    0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
+    0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
+    0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
+    0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
+    0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
+    0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
+    0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
+    0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
+    0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
+    0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
+    0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
+    0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
+    0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
+    0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
+    0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
+    0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
+    0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
+    0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
+    0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
+    0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
+    0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
+    0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
+};
 /* Macro to perform one column of the RS matrix multiplication.  The
  * parameters a, b, c, and d are the four bytes of output; i is the index
  * of the key bytes, and w, x, y, and z, are the column of constants from
@@ -400,13 +471,13 @@ static const byte exp_to_poly[492] = {
       (d) ^= exp_to_poly[tmp + (z)]; \
    }
 
-/* Macros to calculate the key-dependent S-boxes using the S vector from
- * CALC_S.  CALC_SB_2 computes a single entry in all four S-boxes, where i
- * is the index of the entry to compute, and a and b are the index numbers
- * preprocessed through the q0 and q1 tables respectively.  CALC_SB is
- * simply a convenience to make the code shorter; it calls CALC_SB_2 four
- * times with consecutive indices from i to i+3, using the remaining
- * parameters two by two. */
+/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
+ * the S vector from CALC_S.  CALC_SB_2 computes a single entry in all
+ * four S-boxes, where i is the index of the entry to compute, and a and b
+ * are the index numbers preprocessed through the q0 and q1 tables
+ * respectively.  CALC_SB is simply a convenience to make the code shorter;
+ * it calls CALC_SB_2 four times with consecutive indices from i to i+3,
+ * using the remaining parameters two by two. */
 
 #define CALC_SB_2(i, a, b) \
    ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
@@ -418,168 +489,231 @@ static const byte exp_to_poly[492] = {
    CALC_SB_2 (i, a, b); CALC_SB_2 ((i)+1, c, d); \
    CALC_SB_2 ((i)+2, e, f); CALC_SB_2 ((i)+3, g, h)
 
+/* Macros exactly like CALC_SB and CALC_SB_2, but for 256-bit keys. */
+
+#define CALC_SB256_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
+   ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
+   ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
+   ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
+
+#define CALC_SB256(i, a, b, c, d, e, f, g, h) \
+   CALC_SB256_2 (i, a, b); CALC_SB256_2 ((i)+1, c, d); \
+   CALC_SB256_2 ((i)+2, e, f); CALC_SB256_2 ((i)+3, g, h)
+
 /* Macros to calculate the whitening and round subkeys.  CALC_K_2 computes the
- * h() function for a given index (either 2i or 2i+1). a and b are the index
- * preprocessed through q0 and q1 respectively; j is the index of the first
- * key byte to use.  CALC_K computes a pair of subkeys by calling CALC_K_2
+ * last two stages of the h() function for a given index (either 2i or 2i+1).
+ * a, b, c, and d are the four bytes going into the last two stages.  For
+ * 128-bit keys, this is the entire h() function and a and c are the index
+ * preprocessed through q0 and q1 respectively; for longer keys they are the
+ * output of previous stages.  j is the index of the first key byte to use.
+ * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
  * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
  * rotations.  Its parameters are: a, the array to write the results into,
  * j, the index of the first output entry, k and l, the preprocessed indices
- * for index 2i, and m and n, the preprocessed indices for index 2i+1. */
+ * for index 2i, and m and n, the preprocessed indices for index 2i+1.
+ * CALC_K256_2 expands CALC_K_2 to handle 256-bit keys, by doing two
+ * additional lookup-and-XOR stages.  The parameters a and b are the index
+ * preprocessed through q0 and q1 respectively; j is the index of the first
+ * key byte to use.  CALC_K256 is identical to CALC_K but for using the
+ * CALC_K256_2 macro instead of CALC_K_2. */
 
-#define CALC_K_2(a, b, j) \
+#define CALC_K_2(a, b, c, d, j) \
      mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
    ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
-   ^ mds[2][q1[a ^ key[(j) + 10]] ^ key[(j) + 2]] \
-   ^ mds[3][q1[b ^ key[(j) + 11]] ^ key[(j) + 3]]
+   ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
+   ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
 
 #define CALC_K(a, j, k, l, m, n) \
-   x = CALC_K_2 (k, l, 0); \
-   y = CALC_K_2 (m, n, 4); \
+   x = CALC_K_2 (k, l, k, l, 0); \
+   y = CALC_K_2 (m, n, m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K256_2(a, b, j) \
+   CALC_K_2 (q0[q1[b ^ key[(j) + 24]] ^ key[(j) + 16]], \
+            q1[q1[a ^ key[(j) + 25]] ^ key[(j) + 17]], \
+            q0[q0[a ^ key[(j) + 26]] ^ key[(j) + 18]], \
+            q1[q0[b ^ key[(j) + 27]] ^ key[(j) + 19]], j)
+
+#define CALC_K256(a, j, k, l, m, n) \
+   x = CALC_K256_2 (k, l, 0); \
+   y = CALC_K256_2 (m, n, 4); \
    y = (y << 8) + (y >> 24); \
    x += y; y += x; ctx->a[j] = x; \
-   ctx->a[(j) + 1] = (y << 9) + ( y >> 23)
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
 \f
-/* Perform the key setup.  Note that this works *only* with 128-bit keys,
- * despite the API that makes it look like it might support other sizes. */
 
-static int
-twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
+static void
+burn_stack (int bytes)
 {
-   /* Temporaries for CALC_K. */
-   u32 x, y;
+    char buf[64];
+    
+    wipememory(buf,sizeof buf);
+    bytes -= sizeof buf;
+    if (bytes > 0)
+        burn_stack (bytes);
+}
 
-   /* The S vector used to key the S-boxes, split up into individual
-    * bytes. */
-   byte sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
 
-   /* Temporary for CALC_S. */
-   byte tmp;
 
-   /* Flag for self-test. */
-   static int initialized = 0;
+/* Perform the key setup.  Note that this works only with 128- and 256-bit
+ * keys, despite the API that looks like it might support other sizes. */
 
-   /* Check key length. */
-   assert (keylen == 16);
+#ifdef __riscos__
+/* need to switch off CSE optimisation for Norcroft C (Acorn/Pace) */
+#pragma no_optimise_cse
+#endif /* __riscos__ */
 
-   /* Do self-test if necessary. */
-   if (!initialized) {
-      initialized = 1;
-      selftest ();
-   }
+static int
+do_twofish_setkey (TWOFISH_context *ctx, const byte *key, unsigned int keylen)
+{
+    int i, j, k;
+
+    /* Temporaries for CALC_K. */
+    u32 x, y;
+
+    /* The S vector used to key the S-boxes, split up into individual bytes.
+     * 128-bit keys use only sa through sh; 256-bit use all of them. */
+    byte sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
+    byte si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
+
+    /* Temporary for CALC_S. */
+    byte tmp;
+
+    /* Flags for self-test. */
+    static int initialized = 0;
+    static const char *selftest_failed=0;
+
+    /* Check key length. */
+    if( ( ( keylen - 16 ) | 16 ) != 16 )
+       return G10ERR_WRONG_KEYLEN;
+
+    /* Do self-test if necessary. */
+    if (!initialized) {
+       initialized = 1;
+       selftest_failed = selftest ();
+       if( selftest_failed )
+        fprintf(stderr, "%s\n", selftest_failed );
+    }
+    if( selftest_failed )
+       return G10ERR_SELFTEST_FAILED;
+
+    /* Compute the first two words of the S vector.  The magic numbers are
+     * the entries of the RS matrix, preprocessed through poly_to_exp. The
+     * numbers in the comments are the original (polynomial form) matrix
+     * entries. */
+    CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+    CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+    CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+    CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+    CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+    CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+    CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+    CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+    CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+    CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+    CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+    CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+    CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+    CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+    CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+    CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+    if (keylen == 32) { /* 256-bit key */
+       /* Calculate the remaining two words of the S vector */
+       CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+       CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+       CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+       CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+       CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+       CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+       CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+       CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+       CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+       CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+       CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+       CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+       CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+       CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+       CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+       CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+       /* Compute the S-boxes. */
+       for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 ) {
+           CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+       }
 
-   /* Compute the S vector.  The magic numbers are the entries of the RS
-    * matrix, preprocessed through poly_to_exp.  The numbers in the comments
-    * are the original (polynomial form) matrix entries. */
-   CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
-   CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
-   CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
-   CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
-   CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
-   CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
-   CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
-   CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
-   CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
-   CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
-   CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
-   CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
-   CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
-   CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
-   CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
-   CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
-
-   /* Compute the S-boxes.  The constants are indices of
-    * S-box entries, preprocessed through q0 and q1. */
-   CALC_SB (0, 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4);
-   CALC_SB (4, 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8);
-   CALC_SB (8, 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B);
-   CALC_SB (12, 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B);
-   CALC_SB (16, 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD);
-   CALC_SB (20, 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1);
-   CALC_SB (24, 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B);
-   CALC_SB (28, 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F);
-   CALC_SB (32, 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B);
-   CALC_SB (36, 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D);
-   CALC_SB (40, 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E);
-   CALC_SB (44, 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5);
-   CALC_SB (48, 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14);
-   CALC_SB (52, 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3);
-   CALC_SB (56, 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54);
-   CALC_SB (60, 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51);
-   CALC_SB (64, 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A);
-   CALC_SB (68, 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96);
-   CALC_SB (72, 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10);
-   CALC_SB (76, 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C);
-   CALC_SB (80, 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7);
-   CALC_SB (84, 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70);
-   CALC_SB (88, 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB);
-   CALC_SB (92, 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8);
-   CALC_SB (96, 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF);
-   CALC_SB (100, 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC);
-   CALC_SB (104, 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF);
-   CALC_SB (108, 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2);
-   CALC_SB (112, 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82);
-   CALC_SB (116, 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9);
-   CALC_SB (120, 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97);
-   CALC_SB (124, 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17);
-   CALC_SB (128, 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D);
-   CALC_SB (132, 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3);
-   CALC_SB (136, 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C);
-   CALC_SB (140, 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E);
-   CALC_SB (144, 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F);
-   CALC_SB (148, 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49);
-   CALC_SB (152, 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21);
-   CALC_SB (156, 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9);
-   CALC_SB (160, 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD);
-   CALC_SB (164, 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01);
-   CALC_SB (168, 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F);
-   CALC_SB (172, 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48);
-   CALC_SB (176, 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E);
-   CALC_SB (180, 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19);
-   CALC_SB (184, 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57);
-   CALC_SB (188, 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64);
-   CALC_SB (192, 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE);
-   CALC_SB (196, 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5);
-   CALC_SB (200, 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44);
-   CALC_SB (204, 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69);
-   CALC_SB (208, 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15);
-   CALC_SB (212, 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E);
-   CALC_SB (216, 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34);
-   CALC_SB (220, 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC);
-   CALC_SB (224, 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B);
-   CALC_SB (228, 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB);
-   CALC_SB (232, 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52);
-   CALC_SB (236, 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9);
-   CALC_SB (240, 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4);
-   CALC_SB (244, 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2);
-   CALC_SB (248, 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56);
-   CALC_SB (252, 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91);
-
-   /* Calculate whitening and round subkeys.  The constants are
-    * indices of subkeys, preprocessed through q0 and q1. */
-   CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
-   CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
-   CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
-   CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
-   CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
-   CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
-   CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
-   CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
-   CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
-   CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
-   CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
-   CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
-   CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
-   CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
-   CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
-   CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
-   CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
-   CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
-   CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
-   CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+       /* Calculate whitening and round subkeys.  The constants are
+        * indices of subkeys, preprocessed through q0 and q1. */
+       CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+       CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+       CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+       CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+       CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+       CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+       CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+       CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+       CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+       CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+       CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+       CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+       CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+       CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+       CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+       CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+       CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+       CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+       CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+       CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+    }
+    else {
+       /* Compute the S-boxes. */
+       for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 ) {
+           CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+       }
 
-   return 0;
+       /* Calculate whitening and round subkeys.  The constants are
+        * indices of subkeys, preprocessed through q0 and q1. */
+       CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+       CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+       CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+       CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+       CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+       CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+       CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+       CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+       CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+       CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+       CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
+       CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+       CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
+       CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+       CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+       CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
+       CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+       CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+       CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
+       CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+    }
+
+    return 0;
 }
+
+#ifdef __riscos__
+#pragma optimise_cse
+#endif /* __riscos__ */
+
+static int
+twofish_setkey (TWOFISH_context *ctx, const byte *key, unsigned int keylen)
+{
+    int rc = do_twofish_setkey (ctx, key, keylen);
+    burn_stack (23+6*sizeof(void*));
+    return rc;
+}
+        
+
 \f
 /* Macros to compute the g() function in the encryption and decryption
  * rounds.  G1 is the straight g() function; G2 includes the 8-bit
@@ -641,8 +775,13 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
 \f
 /* Encrypt one block.  in and out may be the same. */
 
+#ifdef __riscos__
+/* need to switch off CSE optimisation for Norcroft C (Acorn/Pace) */
+#pragma no_optimise_cse
+#endif /* __riscos__ */
+
 static void
-twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
 {
    /* The four 32-bit chunks of the text. */
    u32 a, b, c, d;
@@ -672,11 +811,27 @@ twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
    OUTUNPACK (2, a, 6);
    OUTUNPACK (3, b, 7);
 }
+
+#ifdef __riscos__
+#pragma optimise_cse
+#endif /* __riscos__ */
+
+static void
+twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+{
+    do_twofish_encrypt (ctx, out, in);
+    burn_stack (24+3*sizeof (void*));
+}
 \f
 /* Decrypt one block.  in and out may be the same. */
 
+#ifdef __riscos__
+/* need to switch off CSE optimisation for Norcroft C (Acorn/Pace) - bug */
+#pragma no_optimise_cse
+#endif /* __riscos__ */
+
 static void
-twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
 {
    /* The four 32-bit chunks of the text. */
    u32 a, b, c, d;
@@ -706,20 +861,31 @@ twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
    OUTUNPACK (2, c, 2);
    OUTUNPACK (3, d, 3);
 }
-\f
-/* Test a single encryption and decryption, as a sanity check. */
+
+#ifdef __riscos__
+#pragma optimise_cse
+#endif /* __riscos__ */
 
 static void
+twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+{
+    do_twofish_decrypt (ctx, out, in);
+    burn_stack (24+3*sizeof (void*));
+}
+\f
+/* Test a single encryption and decryption with each key size. */
+
+static const char*
 selftest (void)
 {
    TWOFISH_context ctx; /* Expanded key. */
    byte scratch[16];   /* Encryption/decryption result buffer. */
 
-   /* Test vector for single encryption/decryption.  Note that I am using
-    * the vector from the Twofish paper's "known answer test", I=3, instead
-    * of the all-0 vector from the "intermediate value test", because an
-    * all-0 key would trigger all the special cases in the RS matrix multiply,
-    * leaving the actual math untested. */
+   /* Test vectors for single encryption/decryption.  Note that I am using
+    * the vectors from the Twofish paper's "known answer test", I=3 for
+    * 128-bit and I=4 for 256-bit, instead of the all-0 vectors from the
+    * "intermediate value test", because an all-0 key would trigger all the
+    * special cases in the RS matrix multiply, leaving the math untested. */
    static const byte plaintext[16] = {
       0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
       0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19
@@ -732,22 +898,46 @@ selftest (void)
       0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
       0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3
    };
+   static const byte plaintext_256[16] = {
+      0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
+      0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6
+   };
+   static const byte key_256[32] = {
+      0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
+      0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
+      0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
+      0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F
+   };
+   static const byte ciphertext_256[16] = {
+      0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
+      0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA
+   };
 
    twofish_setkey (&ctx, key, sizeof(key));
    twofish_encrypt (&ctx, scratch, plaintext);
    if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
-     log_fatal ("Twofish test encryption failed\n");
+     return "Twofish-128 test encryption failed.";
    twofish_decrypt (&ctx, scratch, scratch);
    if (memcmp (scratch, plaintext, sizeof (plaintext)))
-     log_fatal ("Twofish test decryption failed\n");
+     return "Twofish-128 test decryption failed.";
+
+   twofish_setkey (&ctx, key_256, sizeof(key_256));
+   twofish_encrypt (&ctx, scratch, plaintext_256);
+   if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
+     return "Twofish-256 test encryption failed.";
+   twofish_decrypt (&ctx, scratch, scratch);
+   if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
+     return "Twofish-256 test decryption failed.";
+
+   return NULL;
 }
 \f
-/* More complete test program. This does a thousand encryptions and
- * decryptions with each of five hundred keys using a feedback scheme similar
- * to a Feistel cipher, so as to be sure of testing all the table entries
- * pretty thoroughly.  We keep changing the keys so as to get a more
- * meaningful performance number, since the key setup is non-trivial for
- * Twofish. */
+/* More complete test program. This does 1000 encryptions and decryptions
+ * with each of 250 128-bit keys and 2000 encryptions and decryptions with
+ * each of 125 256-bit keys, using a feedback scheme similar to a Feistel
+ * cipher, so as to be sure of testing all the table entries pretty
+ * thoroughly. We keep changing the keys so as to get a more meaningful
+ * performance number, since the key setup is non-trivial for Twofish. */
 
 #ifdef TEST
 
@@ -760,56 +950,79 @@ main()
 {
    TWOFISH_context ctx;     /* Expanded key. */
    int i, j;               /* Loop counters. */
+
    const char *encrypt_msg; /* Message to print regarding encryption test;
                             * the printf is done outside the loop to avoid
                             * stuffing up the timing. */
    clock_t timer; /* For computing elapsed time. */
 
    /* Test buffer. */
-   byte buffer[2][16] = {
+   byte buffer[4][16] = {
       {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
       {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78,
-       0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0}
+       0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0},
+      {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10},
+      {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10,
+       0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98}
    };
 
    /* Expected outputs for the million-operation test */
-   static const byte test_encrypt[2][16] = {
-      {0xD6, 0xD9, 0x74, 0x06, 0x93, 0x9C, 0x9A, 0x5E,
-       0xAA, 0x34, 0x18, 0x5B, 0xD3, 0x92, 0x5B, 0xC5},
-      {0x9C, 0xCD, 0x01, 0x30, 0xF9, 0x96, 0x00, 0x60,
-       0x49, 0x91, 0x73, 0x28, 0x9D, 0x8E, 0x8F, 0xC4}
+   static const byte test_encrypt[4][16] = {
+      {0xC8, 0x23, 0xB8, 0xB7, 0x6B, 0xFE, 0x91, 0x13,
+       0x2F, 0xA7, 0x5E, 0xE6, 0x94, 0x77, 0x6F, 0x6B},
+      {0x90, 0x36, 0xD8, 0x29, 0xD5, 0x96, 0xC2, 0x8E,
+       0xE4, 0xFF, 0x76, 0xBC, 0xE5, 0x77, 0x88, 0x27},
+      {0xB8, 0x78, 0x69, 0xAF, 0x42, 0x8B, 0x48, 0x64,
+       0xF7, 0xE9, 0xF3, 0x9C, 0x42, 0x18, 0x7B, 0x73},
+      {0x7A, 0x88, 0xFB, 0xEB, 0x90, 0xA4, 0xB4, 0xA8,
+       0x43, 0xA3, 0x1D, 0xF1, 0x26, 0xC4, 0x53, 0x57}
    };
-   static const byte test_decrypt[2][16] = {
+   static const byte test_decrypt[4][16] = {
       {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
       {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78,
-       0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0}
+       0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0},
+      {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10},
+      {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10,
+       0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98}
    };
 
    /* Start the timer ticking. */
    timer = clock ();
 
    /* Encryption test. */
-   for (i = 0; i < 250; i++) {
+   for (i = 0; i < 125; i++) {
       twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
       for (j = 0; j < 1000; j++)
-       twofish_encrypt (&ctx, buffer[1], buffer[1]);
+       twofish_encrypt (&ctx, buffer[2], buffer[2]);
       twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]));
       for (j = 0; j < 1000; j++)
+       twofish_encrypt (&ctx, buffer[3], buffer[3]);
+      twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
+      for (j = 0; j < 1000; j++) {
        twofish_encrypt (&ctx, buffer[0], buffer[0]);
+       twofish_encrypt (&ctx, buffer[1], buffer[1]);
+      }
    }
    encrypt_msg = memcmp (buffer, test_encrypt, sizeof (test_encrypt)) ?
                 "encryption failure!\n" : "encryption OK!\n";
 
    /* Decryption test. */
-   for (i = 0; i < 250; i++) {
+   for (i = 0; i < 125; i++) {
+      twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
+      for (j = 0; j < 1000; j++) {
+       twofish_decrypt (&ctx, buffer[0], buffer[0]);
+       twofish_decrypt (&ctx, buffer[1], buffer[1]);
+      }
       twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]));
       for (j = 0; j < 1000; j++)
-       twofish_decrypt (&ctx, buffer[0], buffer[0]);
+       twofish_decrypt (&ctx, buffer[3], buffer[3]);
       twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
       for (j = 0; j < 1000; j++)
-       twofish_decrypt (&ctx, buffer[1], buffer[1]);
+       twofish_decrypt (&ctx, buffer[2], buffer[2]);
    }
 
    /* Stop the timer, and print results. */
@@ -824,7 +1037,10 @@ main()
 
 #endif /* TEST */
 \f
-static const char *
+#ifdef IS_MODULE
+static
+#endif
+       const char *
 twofish_get_info (int algo, size_t *keylen,
                  size_t *blocksize, size_t *contextsize,
                  int  (**r_setkey) (void *c, byte *key, unsigned keylen),
@@ -832,20 +1048,28 @@ twofish_get_info (int algo, size_t *keylen,
                  void (**r_decrypt) (void *c, byte *outbuf, byte *inbuf)
                 )
 {
-    *keylen = 128;
+    *keylen = algo==10? 256 : 128;
     *blocksize = 16;
     *contextsize = sizeof (TWOFISH_context);
-    *r_setkey = FNCCAST_SETKEY (twofish_setkey);
-    *r_encrypt= FNCCAST_CRYPT (twofish_encrypt);
-    *r_decrypt= FNCCAST_CRYPT (twofish_decrypt);
 
-   if (algo == 102) /* This algorithm number is assigned for
-                    * experiments, so we can use it */
-     return "TWOFISH";
-   return NULL;
+    *(int  (**)(TWOFISH_context*, const byte*, const unsigned))r_setkey
+                                                       = twofish_setkey;
+    *(void (**)(const TWOFISH_context*, byte*, const byte*))r_encrypt
+                                                       = twofish_encrypt;
+    *(void (**)(const TWOFISH_context*, byte*, const byte*))r_decrypt
+                                                       = twofish_decrypt;
+
+    if( algo == 10 )
+       return "TWOFISH";
+    if (algo == 102) /* This algorithm number is assigned for
+                     * experiments, so we can use it */
+       return "TWOFISH128";
+    return NULL;
 }
 
 
+#ifdef IS_MODULE
+static
 const char * const gnupgext_version = "TWOFISH ($Revision$)";
 
 static struct {
@@ -855,13 +1079,14 @@ static struct {
     void (*func)(void);
 } func_table[] = {
     { 20, 1, 0, (void(*)(void))twofish_get_info },
+    { 21, 1, 10  },
     { 21, 1, 102 },
 };
 
 
 
 /****************
- * Enumerate the names of the functions together with informations about
+ * Enumerate the names of the functions together with information about
  * this function. Set sequence to an integer with a initial value of 0 and
  * do not change it.
  * If what is 0 all kind of functions are returned.
@@ -875,7 +1100,7 @@ static struct {
  *               version = interface version of the function/pointer
  *                         (currently this is 1 for all functions)
  */
-void *
+static void *
 gnupgext_enum_func ( int what, int *sequence, int *class, int *vers )
 {
     void *ret;
@@ -894,7 +1119,11 @@ gnupgext_enum_func ( int what, int *sequence, int *class, int *vers )
            ret = &func_table[i].value;
            break;
          default:
+#ifndef __riscos__
            ret = func_table[i].func;
+#else /* __riscos__ */
+           ret = (void *) func_table[i].func;
+#endif /* __riscos__ */
            break;
        }
        i++;
@@ -903,4 +1132,4 @@ gnupgext_enum_func ( int what, int *sequence, int *class, int *vers )
     *sequence = i;
     return ret;
 }
-
+#endif