diff --git a/examples/eratosthenes.c b/examples/eratosthenes.c
new file mode 100644
index 0000000000000000000000000000000000000000..8293137287fd7f0f99a1bb44f9dc868049971847
--- /dev/null
+++ b/examples/eratosthenes.c
@@ -0,0 +1,492 @@
+/* eratosthenes.c
+ *
+ * An implementation of the sieve of Eratosthenes, to generate a list of primes.
+ *
+ */
+ 
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2007 Niels M�ller
+ *  
+ * 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.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "getopt.h"
+
+#ifdef SIZEOF_LONG
+# define BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG)
+# if BITS_PER_LONG > 32
+#  define NEED_HANDLE_LARGE_LONG 1
+# else
+#  define NEED_HANDLE_LARGE_LONG 0
+# endif
+#else
+# define BITS_PER_LONG (CHAR_BIT * sizeof(unsigned long))
+# define NEED_HANDLE_LARGE_LONG 1
+#endif
+
+
+static void
+usage(void)
+{
+  fprintf(stderr, "Usage: erathostenes [OPTIONS] [LIMIT]\n\n"
+	  "Options:\n"
+	  "      --help         Display this message.\n"
+	  "      --odd-only     Omit the prime 2.\n"
+	  "      --primes-only  Suppress output of differences.\n"
+	  "      --diff-only    Supress output of primes.\n"
+	  "      --tabular      Tabular output (default is one prime per line).\n"
+	  "      --binary       Binary output.\n"
+	  "      --quiet        No summary line.\n");
+}
+
+static unsigned
+isqrt(unsigned n)
+{
+  unsigned x;
+
+  /* FIXME: Better initialization. */
+  if (n < UINT_MAX)
+    x = n;
+  else
+    /* Must avoid overflow in the first step. */
+    x = n-1;  
+
+  for (;;)
+    {
+      unsigned y = (x + n/x) / 2;
+      if (y >= x)
+	return x;
+
+      x = y;
+    }
+}
+
+/* Size is in bits */
+static unsigned long *
+vector_alloc(unsigned size)
+{
+  unsigned end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG;
+  unsigned i;
+  unsigned long *vector = malloc (end * sizeof(long));
+  
+  if (!vector)
+    return NULL;
+
+  for (i = 0; i < end; i++)
+    vector[i] = ~0;
+
+  return vector;
+}
+
+static void
+vector_clear_bits (unsigned long *vector, unsigned step, unsigned start, unsigned size)
+{
+#if 0
+  if (step <= BITS_PER_LONG/2)
+    {
+      unsigned long buf[BITS_PER_LONG - 1];      
+
+      unsigned end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG;
+
+      unsigned i = start / BITS_PER_LONG;
+      unsigned bit = start % BITS_PER_LONG;
+      unsigned long mask;
+      unsigned j;
+
+      if (bit >= step)
+	{
+	  /* Must handle first word specially */
+	  for (mask = 0; bit < BITS_PER_LONG; bit += step)
+	    mask |= 1L << (bit % BITS_PER_LONG);
+
+	  vector[i++] &= ~mask;
+	  bit -= BITS_PER_LONG;
+	}
+
+      /* Fill buf with bit pattern */
+      for (j = 0; j < step; j++)
+	{
+	  for (mask = 0; bit < BITS_PER_LONG; bit += step)
+	    mask |= 1L << (bit % BITS_PER_LONG);
+
+	  buf[j] = ~mask;
+	  bit -= BITS_PER_LONG;
+	}
+
+      /* Apply bit pattern */
+      while (i + step < end)
+	for (j = 0; j < step; )
+	  vector[i++] &= buf[j++];
+
+      for (j = 0; i < end; )
+	vector[i++] &= buf[j++];
+    }
+  else
+#endif
+    {
+      unsigned bit;
+
+      for (bit = start; bit < size; bit += step)
+	{
+	  unsigned i = bit / BITS_PER_LONG;
+	  unsigned long mask = 1L << (bit % BITS_PER_LONG);
+
+	  vector[i] &= ~mask;
+	}
+    }
+}
+
+static unsigned
+find_first_one (unsigned long x)
+{
+  unsigned table[0x10] =
+    {
+      /* 0, 1,  2,  3,  4,  5,  6,  7 */
+        -1, 0,  1,  0,  2,  0,  1 , 0,
+      /* 8, 9, 10, 11, 12, 13, 14, 15 */
+	 3, 0,  1,  0,  2,  0,  1,  0
+    };
+
+  /* Isolate least significant bit */
+  x &= -x;
+  
+  unsigned i = 0;
+#if NEED_HANDLE_LARGE_LONG
+#ifndef SIZEOF_LONG
+  /* Can't not be tested by the preprocessor. May generate warnings
+     when long is 32 bits. */
+  if (BITS_PER_LONG > 32)
+#endif
+    while (x >= 0x100000000L)
+      {
+	x >>= 32;
+	i += 32;
+      }
+#endif /* NEED_HANDLE_LARGE_LONG */
+
+  if (x >= 0x10000)
+    {
+      x >>= 16;
+      i =+ 16;
+    }
+  if (x >= 0x100)
+    {
+      x >>= 8;
+      i += 8;
+    }
+  if (x >= 0x10)
+    {
+      x >>= 4;
+      i += 4;
+    }
+  return i + table[x & 0xf];
+}
+
+/* Returns size if there's no more bits set */
+static unsigned
+vector_find_next (const unsigned long *vector, unsigned bit, unsigned size)
+{
+  unsigned end = (size + BITS_PER_LONG - 1) / BITS_PER_LONG;
+  unsigned i = bit / BITS_PER_LONG;
+  unsigned long mask = 1L << (bit % BITS_PER_LONG);
+  unsigned long word;
+
+  if (i >= end)
+    return size;
+
+  for (word = vector[i] & ~(mask - 1); !word; word = vector[i])
+    if (++i >= end)
+      return size;
+
+  /* Next bit is the least significant bit of word */
+  return i * BITS_PER_LONG + find_first_one(word);
+}
+
+struct output_info
+{
+  int output_2;
+  enum {
+    FORMAT_PRIMES = 1, FORMAT_DIFF = 2, FORMAT_TABULAR = 4, FORMAT_BINARY = 8
+  } format;
+
+  unsigned long last;
+  unsigned column;
+
+  /* For the binary output */
+  unsigned size;
+};
+
+static void
+output_init(struct output_info *info)
+{
+  info->output_2 = 1;
+  info->format = FORMAT_PRIMES | FORMAT_DIFF;
+  info->last = 0;
+  info->size = 1;
+}
+
+static void
+output(struct output_info *info, unsigned long p)
+{
+  if (info->format & FORMAT_BINARY)
+    {
+      /* Overrides the other formats. */
+      unsigned char buf[4];
+      unsigned diff = (p - info->last) / 2;
+      switch (info->size)
+	{
+	case 1:
+	  if (diff < 0x100)
+	    {
+	      putchar(diff);
+	      break;
+	    }
+	  else
+	    {
+	      info->size++;
+	      putchar(0);
+	      /* Fall through */
+	    }
+	case 2:
+	  if (diff < 0x10000)
+	    {
+	      buf[0] = diff >> 8;
+	      buf[1] = diff & 0xff;
+	      putchar(buf[0]);
+	      putchar(buf[1]);
+	      break;
+	    }
+	  else
+	    {
+	      info->size++;
+	      putchar(0);
+	      putchar(0);
+	      /* Fall through */
+	    }
+	case 3:
+	  if (diff < 0x1000000)
+	    {
+	      buf[0] = diff >> 16;
+	      buf[1] = (diff >> 8) & 0xff;
+	      buf[2] = diff & 0xff;
+	      putchar(buf[0]);
+	      putchar(buf[1]);
+	      putchar(buf[2]);
+	      break;
+	    }
+	  else
+	    {
+	      info->size++;
+	      putchar(0);
+	      putchar(0);
+	      putchar(0);
+	      /* Fall through */
+	    }
+	case 4:
+	  buf[0] = diff >> 24;
+	  buf[1] = (diff >> 16) & 0xff;
+	  buf[2] = (diff >> 8) & 0xff;
+	  buf[3] = diff & 0xff;
+	  putchar(buf[0]);
+	  putchar(buf[1]);
+	  putchar(buf[2]);
+	  putchar(buf[3]);
+	  break;
+	}
+    }
+  else if (info->format & (FORMAT_PRIMES | FORMAT_DIFF))
+    {
+      if (info->format & FORMAT_PRIMES)
+	printf("%ld", p);
+      if (info->format & FORMAT_DIFF)
+	printf(" %ld", p - info->last);
+
+      if (info->format & FORMAT_TABULAR)
+	{
+	  printf(",");
+	  info->column++;
+	  if (info->column == 16)
+	    {
+	      printf("\n");
+	      info->column = 0;
+	    }
+	  else
+	    printf(" ");
+	}
+      else
+	printf("\n");
+    }
+  info->last = p;
+}
+
+static void
+output_first(struct output_info *info)
+{
+  if (info->format & FORMAT_BINARY)
+    {
+      /* Omit 2, and start with 1, so that differences are odd. */
+      info->last = 1;
+    }
+  else
+    {
+      info->column = 0;
+      if (info->output_2)
+	output(info, 2);
+
+      info->last = 2;
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+  unsigned long *vector;
+  /* Generate all primes p <= limit */
+  unsigned limit;
+  unsigned size;
+  unsigned bit;
+  unsigned prime_count;
+  unsigned sieve_limit;
+
+  struct output_info info;
+  int quiet;
+  int c;
+  
+  enum { FLAG_ODD = -100, FLAG_PRIME, FLAG_DIFF, FLAG_TABULAR, FLAG_BINARY, FLAG_QUIET };
+  
+  static const struct option options[] =
+    {
+      /* Name, args, flag, val */
+      { "help", no_argument, NULL, '?' },
+      { "odd-only", no_argument, NULL, FLAG_ODD },
+      { "prime-only", no_argument, NULL, FLAG_PRIME },
+      { "diff-only", no_argument, NULL, FLAG_DIFF },
+      { "tabular", no_argument, NULL, FLAG_TABULAR },
+      { "binary", no_argument, NULL, FLAG_BINARY },
+      { "quiet" , no_argument, NULL, FLAG_QUIET },
+      { NULL, 0, NULL, 0}
+    };
+
+  output_init(&info);
+
+  while ( (c = getopt_long(argc, argv, "?", options, NULL)) != -1)
+    switch (c)
+      {
+      case '?':
+	usage();
+	return EXIT_FAILURE;
+      case FLAG_ODD:
+	info.output_2 = 0;
+	break;
+      case FLAG_PRIME:
+	info.format &= ~FORMAT_DIFF;
+	break;
+      case FLAG_DIFF:
+	info.format &= ~FORMAT_PRIMES;
+	break;
+      case FLAG_TABULAR:
+	info.format |= FORMAT_TABULAR;
+	break;
+      case FLAG_BINARY:
+	info.format |= FORMAT_BINARY;
+	break;
+      case FLAG_QUIET:
+	quiet = 1;
+	break;
+      default:
+	abort();
+      }
+
+  argc -= optind;
+  argv += optind;
+
+  if (argc == 0)
+    limit = 1000;
+  else if (argc == 1)
+    {
+      limit = atoi(argv[0]);
+      if (limit < 2)
+	return EXIT_SUCCESS;
+    }
+  else
+    {
+      usage();
+      return EXIT_FAILURE;
+    }
+
+  size = (limit - 1) / 2;
+
+  vector = vector_alloc (size);
+  if (!vector)
+    {
+      fprintf(stderr, "Insufficient memory.\n");
+      return EXIT_FAILURE;
+    }
+
+  output_first(&info);
+  prime_count = 1;
+
+  bit = 0;
+
+  if (limit == 2)
+    return EXIT_SUCCESS;
+
+  sieve_limit = (isqrt(limit) - 1) / 2;
+  
+  while (bit < sieve_limit)
+    {
+      unsigned n = 3 + 2 * bit;
+      
+      output(&info, n);
+      prime_count++;
+
+      /* First bit to clear corresponds to n^2, which is bit
+
+	 (n^2 - 3) / 2 = n * bit + 3 (bit + 1)
+      */
+      vector_clear_bits (vector, n, n*bit + 3*(bit + 1), size);
+
+      bit = vector_find_next (vector, bit + 1, size);
+    }
+
+  /* No more marking, just output the remaining primes. */
+  while (bit < size)
+    {
+      unsigned n = 3 + 2 * bit;
+
+      output(&info, n);
+      prime_count++;
+
+      bit = vector_find_next (vector, bit + 1, size);
+    }
+
+  if (!quiet)
+    {
+      printf("\n");
+      fprintf(stderr, "Prime #%d = %ld\n", prime_count, info.last);
+    }
+
+  return EXIT_SUCCESS;
+}