diff --git a/ChangeLog b/ChangeLog
index 194c070252b6ffe2a6b1db118bfa3936de63ca4b..70b58c6b71a6f03db28181da82eb98e94964d69c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-04-09  Niels M�ller  <nisse@lysator.liu.se>
+
+	* Makefile.in (hogweed_SOURCES): Added bignum-random-prime.c.
+
+	* bignum-random-prime.c (nettle_random_prime): New file, new
+	function.
+
 2010-03-31  Niels M�ller  <nisse@lysator.liu.se>
 
 	* examples/nettle-benchmark.c (main): Benchmark sha224.
diff --git a/Makefile.in b/Makefile.in
index d4c8f1b63da5658d929964ba9310bea739bc9936..941954056b87b38040d9aba0dbad157ad09c97d8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -76,7 +76,9 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
 
 hogweed_SOURCES = sexp.c sexp-format.c \
 		  sexp-transport.c sexp-transport-format.c \
-		  bignum.c bignum-next-prime.c bignum-random.c sexp2bignum.c \
+		  bignum.c bignum-next-prime.c \
+		  bignum-random.c bignum-random-prime.c \
+		  sexp2bignum.c \
 		  pkcs1.c pkcs1-rsa-md5.c pkcs1-rsa-sha1.c \
 		  pkcs1-rsa-sha256.c pkcs1-rsa-sha512.c \
 		  rsa.c rsa-sign.c rsa-verify.c \
diff --git a/bignum-random-prime.c b/bignum-random-prime.c
new file mode 100644
index 0000000000000000000000000000000000000000..67a5b1071b49fa902d6c13cdc9efb8c050ad5afd
--- /dev/null
+++ b/bignum-random-prime.c
@@ -0,0 +1,339 @@
+/* bignum-random-prime.c
+ *
+ * Generation of random provable primes.
+ */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2010 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
+
+#ifndef RANDOM_PRIME_VERBOSE
+#define RANDOM_PRIME_VERBOSE 0
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#if RANDOM_PRIME_VERBOSE
+#include <stdio.h>
+#define VERBOSE(x) (fputs((x), stderr))
+#else
+#define VERBOSE(x)
+#endif
+
+#include "bignum.h"
+
+#include "macros.h"
+
+/* Use a table of p_2 = 3 to p_{172} = 1021, multiplied to 32-bit or
+   64-bit size. */
+
+struct sieve_element {
+  /* Product of some small primes. */
+  unsigned long prod;
+  /* Square of the smallest one. */
+  unsigned long p2;
+};
+
+static const struct sieve_element
+sieve_table[] = {
+  {111546435, 9}, /* 3 -- 23 */
+  {58642669, 841}, /* 29 -- 43 */
+  {600662303, 2209}, /* 47 -- 67 */
+  {33984931, 5041}, /* 71 -- 83 */
+  {89809099, 7921}, /* 89 -- 103 */
+  {167375713, 11449}, /* 107 -- 127 */
+  {371700317, 17161}, /* 131 -- 149 */
+  {645328247, 22801}, /* 151 -- 167 */
+  {1070560157, 29929}, /* 173 -- 191 */
+  {1596463769, 37249}, /* 193 -- 211 */
+  {11592209, 49729}, /* 223 -- 229 */
+  {13420567, 54289}, /* 233 -- 241 */
+  {16965341, 63001}, /* 251 -- 263 */
+  {20193023, 72361}, /* 269 -- 277 */
+  {23300239, 78961}, /* 281 -- 293 */
+  {29884301, 94249}, /* 307 -- 313 */
+  {35360399, 100489}, /* 317 -- 337 */
+  {42749359, 120409}, /* 347 -- 353 */
+  {49143869, 128881}, /* 359 -- 373 */
+  {56466073, 143641}, /* 379 -- 389 */
+  {65111573, 157609}, /* 397 -- 409 */
+  {76027969, 175561}, /* 419 -- 431 */
+  {84208541, 187489}, /* 433 -- 443 */
+  {94593973, 201601}, /* 449 -- 461 */
+  {103569859, 214369}, /* 463 -- 479 */
+  {119319383, 237169}, /* 487 -- 499 */
+  {133390067, 253009}, /* 503 -- 521 */
+  {154769821, 273529}, /* 523 -- 547 */
+  {178433279, 310249}, /* 557 -- 569 */
+  {193397129, 326041}, /* 571 -- 587 */
+  {213479407, 351649}, /* 593 -- 601 */
+  {229580147, 368449}, /* 607 -- 617 */
+  {250367549, 383161}, /* 619 -- 641 */
+  {271661713, 413449}, /* 643 -- 653 */
+  {293158127, 434281}, /* 659 -- 673 */
+  {319512181, 458329}, /* 677 -- 691 */
+  {357349471, 491401}, /* 701 -- 719 */
+  {393806449, 528529}, /* 727 -- 739 */
+  {422400701, 552049}, /* 743 -- 757 */
+  {452366557, 579121}, /* 761 -- 773 */
+  {507436351, 619369}, /* 787 -- 809 */
+  {547978913, 657721}, /* 811 -- 823 */
+  {575204137, 683929}, /* 827 -- 839 */
+  {627947039, 727609}, /* 853 -- 859 */
+  {666785731, 744769}, /* 863 -- 881 */
+  {710381447, 779689}, /* 883 -- 907 */
+  {777767161, 829921}, /* 911 -- 929 */
+  {834985999, 877969}, /* 937 -- 947 */
+  {894826021, 908209}, /* 953 -- 971 */
+  {951747481, 954529}, /* 977 -- 991 */
+  {1019050649, 994009}, /* 997 -- 1013 */
+  {1040399, 1038361}, /* 1019 -- 1021 */
+};
+
+#define SIEVE_SIZE (sizeof(sieve_table) / sizeof(sieve_table[0]))
+
+/* Combined Miller-Rabin test to the base a, and checking the
+   conditions from Pocklington's theorem. */
+static int
+miller_rabin_pocklington(mpz_t n, mpz_t nm1, mpz_t nm1dq, mpz_t a)
+{
+  mpz_t r;
+  mpz_t y;
+  int is_prime = 0;
+
+  /* Avoid the mp_bitcnt_t type for compatibility with older GMP
+     versions. */
+  unsigned k;
+  unsigned j;
+
+  VERBOSE(".");
+
+  if (mpz_even_p(n) || mpz_cmp_ui(n, 3) < 0)
+    return 0;
+
+  mpz_init(r);
+  mpz_init(y);
+
+  k = mpz_scan1(nm1, 0);
+  assert(k > 0);
+
+  mpz_fdiv_q_2exp (r, nm1, k);
+
+  mpz_powm(y, a, r, n);
+
+  if (mpz_cmp_ui(y, 1) == 0 || mpz_cmp(y, nm1) == 0)
+    {
+    passed_miller_rabin:
+      /* We know that a^{n-1} = 1 (mod n)
+
+	 Remains to check that gcd(a^{(n-1)/q} - 1, n) == 1 */      
+      VERBOSE("x");
+
+      mpz_powm(y, a, nm1dq, n);
+      mpz_sub_ui(y, y, 1);
+      mpz_gcd(y, y, n);
+      is_prime = mpz_cmp_ui (y, 1) == 0;
+      VERBOSE(is_prime ? "\n" : "");
+    }
+
+  for (j = 1; j < k; j++)
+    {
+      mpz_powm_ui (y, y, 2, n);
+
+      if (mpz_cmp_ui (y, 1) == 0)
+	break;
+      if (mpz_cmp (y, nm1) == 0)
+	goto passed_miller_rabin;
+    }
+
+  mpz_clear(r);
+  mpz_clear(y);
+
+  return is_prime;
+}
+
+#if 0
+/* Single Miller-Rabin test to base 2. */
+static int
+miller_rabin_2(mpz_t n)
+{
+  mpz_t nm1;
+  mpz_t r;
+  mpz_t y;
+
+  /* Avoid the mp_bitcnt_t type for compatibility with older GMP
+     versions. */
+  unsigned k;
+  unsigned j;
+
+  //  gmp_fprintf(stderr, "n = %Zd\n", n);
+
+  if (mpz_even_p(n) || mpz_cmp_ui(n, 3) < 0)
+    return 0;
+
+  mpz_init(nm1);
+  mpz_init(r);
+  mpz_init_set_ui(y, 2);
+
+  mpz_sub_ui(nm1, n, 1);
+  k = mpz_scan1(nm1, 0);
+  assert(k > 0);
+
+  mpz_fdiv_q_2exp (r, nm1, k);
+
+  mpz_powm(y, y, r, n);
+
+  //  gmp_fprintf (stderr, "r = %Zd, y = %Zd\n", r,y);
+
+  if (mpz_cmp_ui(y, 1) == 0 || mpz_cmp(y, nm1) == 0)
+    return 1;
+
+  for (j = 1; j < k; j++)
+    {
+      mpz_powm_ui (y, y, 2, n);
+      //      gmp_fprintf (stderr, "j = %d, y = %Zd\n", j, y);
+
+      if (mpz_cmp_ui (y, 1) == 0)
+	return 0;
+      if (mpz_cmp (y, nm1) == 0)
+	return 1;
+    }
+  return 0;
+}
+#endif
+
+/* Generate random prime of a given size. Maurer's algorithm (Alg.
+   6.42 Handbook of applied cryptography), but with ratio = 1/2 (like
+   the variant in fips186-3). FIXME: Force primes to start with two
+   one bits? */
+void
+nettle_random_prime(mpz_t p, unsigned bits,
+		    void *ctx, nettle_random_func random)
+{
+  assert (bits >= 6);
+  if (bits < 20)
+    {
+      unsigned long highbit;
+      uint8_t buf[3];
+      unsigned long x;
+      unsigned j;
+
+      /* Small cases:
+
+	 3 bits: 5 or 7
+	 4 bits: 11, 13, 15
+	 5 bits: 17, 19, 23, 29, 31
+
+	 With 3 bits, no sieving is done, since candidates are smaller
+	 than 3^2 = 9 (and this is ok; all odd 3-bit numbers are
+	 prime).
+
+	 With 4 bits, sieving with the first value, 3*5*...*23 doesn't
+	 work, since this includes the primes 11 and 13 in the
+	 interval. Of the odd numbers in the interval, 9, 11, 13, 15,
+	 only the factors of three need be discarded.
+
+	 With 5 bits, we still sieve with only the first value, which
+	 includes three of the primes in the interval. Of the odd
+	 numbers in the interval, 17, 19, (21), 23, (25), (27), 29,
+	 31, we need to discard multiples of 3 and 5 only.
+
+	 With 6 bits, we sieve with only the first value (since 63 <
+	 29^2), and there's no problem.
+       */
+      
+      highbit = 1L << (bits - 1);
+
+    again:
+      random (ctx, sizeof(buf), buf);
+      x = READ_UINT24(buf);
+      x &= (highbit - 1);
+      x |= highbit | 1;
+
+      mpz_set_ui (p, x);      
+      for (j = 0; j < SIEVE_SIZE && x >= sieve_table[j].p2; j++)
+	if (mpz_gcd_ui (NULL, p, sieve_table[j].prod) != 1)
+	  goto again;
+    }
+  else
+    {
+      mpz_t q, r, nm1, t, a, i;
+      unsigned j;
+
+      mpz_init (q);
+      mpz_init (r);
+      mpz_init (nm1);
+      mpz_init (t);
+      mpz_init (a);
+      mpz_init (i);
+
+     /* Bit size ceil(k/2) + 1, slightly larger than used in Alg.
+         4.62. */
+      nettle_random_prime (q, (bits+3)/2, ctx, random);
+
+      /* i = floor (2^{bits-2} / q) */
+      mpz_init_set_ui (i, 1);
+      mpz_mul_2exp (i, i, bits-2);
+      mpz_fdiv_q (i, i, q);
+
+      for (;;)
+	{
+	  uint8_t buf[1];
+
+	  /* Generate r in the range i + 1 <= r <= 2*i */
+	  nettle_mpz_random (r, ctx, random, i);
+	  mpz_add (r, r, i);
+	  mpz_add_ui (r, r, 1);
+
+	  /* Set p = 2*r*q + 1 */
+	  mpz_mul_2exp(r, r, 1);
+	  mpz_mul (nm1, r, q);
+	  mpz_add_ui (p, nm1, 1);
+
+	  assert(mpz_sizeinbase(p, 2) == bits);
+
+	  for (j = 0; j < SIEVE_SIZE; j++)
+	    {
+	      if (mpz_gcd_ui (NULL, p, sieve_table[j].prod) != 1)
+		goto composite;
+	    }
+
+	  random(ctx, sizeof(buf), buf);
+	  
+	  mpz_set_ui (a, buf[0] + 2);
+
+	  if (miller_rabin_pocklington(p, nm1, r, a))
+	    break;
+	composite:
+	  ;
+	}
+      mpz_clear (q);
+      mpz_clear (r);
+      mpz_clear (nm1);
+      mpz_clear (t);
+      mpz_clear (a);
+      mpz_clear (i);
+      
+    }
+}
diff --git a/bignum.h b/bignum.h
index 14d0fc62da56da0e43edd5ade907af9414211a39..759e7618765249c7600abc7ef7d3c306f7977d89 100644
--- a/bignum.h
+++ b/bignum.h
@@ -85,6 +85,10 @@ void
 nettle_next_prime(mpz_t p, mpz_t n, unsigned count, unsigned prime_limit,
 		  void *progress_ctx, nettle_progress_func progress);
 
+void
+nettle_random_prime(mpz_t p, unsigned bits,
+		    void *ctx, nettle_random_func random);
+
 /* sexp parsing */
 struct sexp_iterator;