diff --git a/rsa.c b/rsa.c
index 6ee9fbe65c620bb104d3aeb655be2a1ee3e1d6b8..bfc31348912a4ba8c5880ca29adb06925b8637e5 100644
--- a/rsa.c
+++ b/rsa.c
@@ -59,10 +59,10 @@ rsa_clear_public_key(struct rsa_public_key *key)
  * Returns 0 if the modulo is too small to be useful. */
 
 static unsigned
-rsa_check_size(unsigned bits)
+rsa_check_size(mpz_t n)
 {
   /* Round upwards */
-  unsigned size = (bits + 7) / 8;
+  unsigned size = (mpz_sizeinbase(n, 2) + 7) / 8;
 
   /* For PKCS#1 to make sense, the size of the modulo, in octets, must
    * be at least 11 + the length of the DER-encoded Digest Info.
@@ -86,7 +86,7 @@ rsa_prepare_public_key(struct rsa_public_key *key)
     return 0;
 #endif
   
-  key->size = rsa_check_size(mpz_sizeinbase(key->n, 2));
+  key->size = rsa_check_size(key->n);
   
   return (key->size > 0);
 }
@@ -120,10 +120,19 @@ rsa_prepare_private_key(struct rsa_private_key *key)
 {
   /* FIXME: Add further sanity checks. */
 
-  /* The size of the product is the sum of the sizes of the factors. */
-  key->size = rsa_check_size(mpz_sizeinbase(key->p, 2)
-			     + mpz_sizeinbase(key->p, 2));
+  mpz_t n;
+  
+  /* The size of the product is the sum of the sizes of the factors,
+   * or sometimes one less. It's possible but tricky to compute the
+   * size without computing the full product. */
+
+  mpz_init(n);
+  mpz_mul(n, key->p, key->q);
 
+  key->size = rsa_check_size(n);
+
+  mpz_clear(n);
+  
   return (key->size > 0);
 }