diff --git a/examples/nettle-benchmark.c b/examples/nettle-benchmark.c
index 846d12759fffb5759501a72351c47fa0f3d93ef4..42dfa468a5f09666b96609d905efe5e7d38cba56 100644
--- a/examples/nettle-benchmark.c
+++ b/examples/nettle-benchmark.c
@@ -25,8 +25,16 @@
  */
 
 #include "aes.h"
+#include "arcfour.h"
+#include "blowfish.h"
+#include "cast128.h"
+#include "des.h"
+#include "serpent.h"
+#include "twofish.h"
+
 #include "cbc.h"
 
+#include <assert.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -34,12 +42,18 @@
 
 #include <time.h>
 
-/* Encrypt 1MB, 1K at a time. */
-#define BENCH_SIZE 1024
+/* Encrypt 100MB, 1K at a time. */
+#define BENCH_BLOCK 1024
+#define BENCH_COUNT 10240
 
 typedef void (*crypt_func)(void *ctx,
 			   unsigned length, uint8_t *dst,
 			   const uint8_t *src);
+
+typedef void (*setkey_func)(void *ctx,
+                            unsigned length,
+                            const uint8_t *key);
+
 static double
 time_function(void (*f)(void *arg), void *arg)
 {
@@ -68,8 +82,8 @@ bench_cipher(void *arg)
   struct bench_cipher_info *info = arg;
   unsigned i;
   
-  for (i = 0; i<BENCH_SIZE; i++)
-    info->crypt(info->ctx, BENCH_SIZE, info->data, info->data);
+  for (i = 0; i<BENCH_COUNT; i++)
+    info->crypt(info->ctx, BENCH_BLOCK, info->data, info->data);
 }
 
 struct bench_cbc_info
@@ -89,10 +103,10 @@ bench_cbc_encrypt(void *arg)
   struct bench_cbc_info *info = arg;
   unsigned i;
 
-  for (i = 0; i<BENCH_SIZE; i++)
+  for (i = 0; i<BENCH_COUNT; i++)
     cbc_encrypt(info->ctx, info->crypt,
 		info->block_size, info->iv,
-		BENCH_SIZE, info->data, info->data);
+		BENCH_BLOCK, info->data, info->data);
 }
 
 static void
@@ -101,10 +115,10 @@ bench_cbc_decrypt(void *arg)
   struct bench_cbc_info *info = arg;
   unsigned i;
 
-  for (i = 0; i<BENCH_SIZE; i++)
+  for (i = 0; i<BENCH_COUNT; i++)
     cbc_decrypt(info->ctx, info->crypt,
 		info->block_size, info->iv,
-		BENCH_SIZE, info->data, info->data);
+		BENCH_BLOCK, info->data, info->data);
 }
 
 /* Set data[i] = floor(sqrt(i)) */
@@ -112,7 +126,7 @@ static void
 init_data(uint8_t *data)
 {
   unsigned i,j;
-  for (i = j = 0; i<BENCH_SIZE;  i++)
+  for (i = j = 0; i<BENCH_BLOCK;  i++)
     {
       if (j*j < i)
 	j++;
@@ -121,73 +135,205 @@ init_data(uint8_t *data)
 }
 
 static void
-bench(const char *name, void (*f)(void *), void *arg)
+init_key(unsigned length,
+         uint8_t *key)
 {
-  printf("%15s: %f\n", name, time_function(f, arg));
+  unsigned i;
+  for (i = 0; i<length; i++)
+    key[i] = i;
 }
 
-int
-main(int argc, char **argv)
+struct cipher
 {
-  /* Time block ciphers */
-  uint8_t iv[AES_BLOCK_SIZE];
-  uint8_t key[AES_MAX_KEY_SIZE];
+  const char *name;
+  unsigned context_size;
   
-  uint8_t data[BENCH_SIZE];
+  unsigned block_size;
+  unsigned key_size;
+
+  setkey_func setkey;
+  crypt_func encrypt;
+  crypt_func decrypt;
+};
+  
+
+static void
+time_cipher(struct cipher *cipher)
+{
+  void *ctx = alloca(cipher->context_size);
+  uint8_t *key = alloca(cipher->key_size);
+
+  uint8_t data[BENCH_BLOCK];
+
+  printf("\n");
+  
+  init_data(data);
 
   {
-    struct aes_ctx ctx;
     struct bench_cipher_info info
-      = { &ctx, (crypt_func) aes_encrypt, data };
+      = { ctx, cipher->encrypt, data };
     
-    memset(key, 0, sizeof(key));
-
-    aes_set_key(&ctx, sizeof(key), key);
-    init_data(data);
-
-    bench("AES (ECB encrypt)", bench_cipher, &info);
+    init_key(cipher->key_size, key);
+    cipher->setkey(ctx, cipher->key_size, key);
+    
+    printf("%13s (ECB encrypt): %f\n", cipher->name,
+           time_function(bench_cipher, &info));
   }
-
+  
   {
-    struct aes_ctx ctx;
     struct bench_cipher_info info
-      = { &ctx, (crypt_func) aes_decrypt, data };
+      = { ctx, cipher->decrypt, data };
     
-    memset(key, 0, sizeof(key));
-
-    aes_set_key(&ctx, sizeof(key), key);
-    init_data(data);
-
-    bench("AES (ECB decrypt)", bench_cipher, &info);
+    init_key(cipher->key_size, key);
+    cipher->setkey(ctx, cipher->key_size, key);
+    
+    printf("%13s (ECB decrypt): %f\n", cipher->name,
+           time_function(bench_cipher, &info));
   }
 
-  {
-    struct aes_ctx ctx;
-    struct bench_cbc_info info
-      = { &ctx, (crypt_func) aes_encrypt, data, AES_BLOCK_SIZE, iv };
+  if (cipher->block_size)
+    {
+      uint8_t *iv = alloca(cipher->block_size);
+      
+      /* Do CBC mode */
+      {
+        struct bench_cbc_info info
+          = { ctx, cipher->encrypt, data, cipher->block_size, iv };
     
-    memset(key, 0, sizeof(key));
-    memset(iv, 0, sizeof(iv));
+        memset(iv, 0, sizeof(iv));
     
-    aes_set_key(&ctx, sizeof(key), key);
-    init_data(data);
+        cipher->setkey(ctx, cipher->key_size, key);
 
-    bench("AES (CBC encrypt)", bench_cbc_encrypt, &info);
-  }
+        printf("%13s (CBC encrypt): %f\n", cipher->name,
+               time_function(bench_cbc_encrypt,
+                             &info));
+      }
 
-  {
-    struct aes_ctx ctx;
-    struct bench_cbc_info info
-      = { &ctx, (crypt_func) aes_decrypt, data, AES_BLOCK_SIZE, iv };
+      {
+        struct bench_cbc_info info
+          = { ctx, cipher->decrypt, data, cipher->block_size, iv };
     
-    memset(key, 0, sizeof(key));
-    memset(iv, 0, sizeof(iv));
+        memset(iv, 0, sizeof(iv));
 
-    aes_set_key(&ctx, sizeof(key), key);
-    init_data(data);
+        cipher->setkey(ctx, cipher->key_size, key);
 
-    bench("AES (CBC decrypt)", bench_cbc_decrypt, &info);
-  }
+        printf("%13s (CBC decrypt): %f\n", cipher->name,
+               time_function(bench_cbc_decrypt,
+                             &info));
+      }
+    }
+}
+
+/* DES uses a different signature for the key set function.
+ * And we have to adjust parity. */
+static void
+des_set_key_hack(void *c, unsigned length, const uint8_t *key)
+{
+  struct des_ctx *ctx = c;
+  uint8_t pkey[DES_KEY_SIZE];
+  
+  assert(length == DES_KEY_SIZE);
+  des_fix_parity(DES_KEY_SIZE, pkey, key);
+  if (!des_set_key(ctx, pkey))
+    abort();
+}
+
+static void
+des3_set_key_hack(void *c, unsigned length, const uint8_t *key)
+{
+  struct des3_ctx *ctx = c;
+  uint8_t pkey[DES3_KEY_SIZE];
+  
+  assert(length == DES3_KEY_SIZE);
+  des_fix_parity(DES3_KEY_SIZE, pkey, key);
+  if (!des3_set_key(ctx, pkey))
+    abort();
+}
+
+#define NCIPHERS 12
+
+int
+main(int argc, char **argv)
+{
+  unsigned i;
+  struct cipher ciphers[NCIPHERS] =
+    {
+      { "AES-128", sizeof(struct aes_ctx),
+        AES_BLOCK_SIZE, 16,
+        (setkey_func) aes_set_key,
+        (crypt_func) aes_encrypt,
+        (crypt_func) aes_decrypt
+      },
+      { "AES-192", sizeof(struct aes_ctx),
+        AES_BLOCK_SIZE, 24,
+        (setkey_func) aes_set_key,
+        (crypt_func) aes_encrypt,
+        (crypt_func) aes_decrypt
+      },
+      { "AES-256", sizeof(struct aes_ctx),
+        AES_BLOCK_SIZE, 32,
+        (setkey_func) aes_set_key,
+        (crypt_func) aes_encrypt,
+        (crypt_func) aes_decrypt
+      },
+      { "ARCFOUR-128", sizeof(struct arcfour_ctx),
+        0, ARCFOUR_KEY_SIZE,
+        (setkey_func) arcfour_set_key,
+        (crypt_func) arcfour_crypt,
+        (crypt_func) arcfour_crypt
+      },
+      { "BLOWFISH-128", sizeof(struct blowfish_ctx),
+        BLOWFISH_BLOCK_SIZE, BLOWFISH_KEY_SIZE,
+        (setkey_func) blowfish_set_key,
+        (crypt_func) blowfish_encrypt,
+        (crypt_func) blowfish_decrypt
+      },
+      { "CAST-128", sizeof(struct cast128_ctx),
+        CAST128_BLOCK_SIZE, CAST128_KEY_SIZE,
+        (setkey_func) cast128_set_key,
+        (crypt_func) cast128_encrypt,
+        (crypt_func) cast128_decrypt
+      },
+      { "DES", sizeof(struct des_ctx),
+        DES_BLOCK_SIZE, DES_KEY_SIZE,
+        des_set_key_hack,
+        (crypt_func) des_encrypt,
+        (crypt_func) des_decrypt
+      },
+      { "DES3", sizeof(struct des3_ctx),
+        DES3_BLOCK_SIZE, DES3_KEY_SIZE,
+        des3_set_key_hack,
+        (crypt_func) des3_encrypt,
+        (crypt_func) des3_decrypt
+      },
+      { "SERPENT-256", sizeof(struct serpent_ctx),
+        SERPENT_BLOCK_SIZE, SERPENT_KEY_SIZE,
+        (setkey_func) serpent_set_key,
+        (crypt_func) serpent_encrypt,
+        (crypt_func) serpent_decrypt
+      },
+      { "TWOFISH-128", sizeof(struct twofish_ctx),
+        TWOFISH_BLOCK_SIZE, 16,
+        (setkey_func) twofish_set_key,
+        (crypt_func) twofish_encrypt,
+        (crypt_func) twofish_decrypt
+      },
+      { "TWOFISH-192", sizeof(struct twofish_ctx),
+        TWOFISH_BLOCK_SIZE, 24,
+        (setkey_func) twofish_set_key,
+        (crypt_func) twofish_encrypt,
+        (crypt_func) twofish_decrypt
+      },
+      { "TWOFISH-256", sizeof(struct twofish_ctx),
+        TWOFISH_BLOCK_SIZE, 32,
+        (setkey_func) twofish_set_key,
+        (crypt_func) twofish_encrypt,
+        (crypt_func) twofish_decrypt
+      },
+    };
 
+  for (i = 0; i<NCIPHERS; i++)
+    time_cipher(ciphers + i);
+  
   return 0;
 }