summaryrefslogtreecommitdiffstats
path: root/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
diff options
context:
space:
mode:
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java166
1 files changed, 94 insertions, 72 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
index 928c6a6..7277045 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
@@ -1,5 +1,7 @@
package org.bouncycastle.crypto.generators;
+import java.math.BigInteger;
+
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
import org.bouncycastle.crypto.KeyGenerationParameters;
@@ -8,8 +10,6 @@ import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
import org.bouncycastle.math.ec.WNafUtil;
-import java.math.BigInteger;
-
/**
* an RSA key pair generator.
*/
@@ -27,96 +27,118 @@ public class RSAKeyPairGenerator
public AsymmetricCipherKeyPair generateKeyPair()
{
- BigInteger p, q, n, d, e, pSub1, qSub1, phi;
+ AsymmetricCipherKeyPair result = null;
+ boolean done = false;
- //
- // p and q values should have a length of half the strength in bits
- //
- int strength = param.getStrength();
- int qBitlength = strength >>> 1;
- int pBitlength = strength - qBitlength;
- int mindiffbits = strength / 3;
- int minWeight = strength >>> 2;
+ while (!done)
+ {
+ BigInteger p, q, n, d, e, pSub1, qSub1, phi, lcm, dLowerBound;
- e = param.getPublicExponent();
+ //
+ // p and q values should have a length of half the strength in bits
+ //
+ int strength = param.getStrength();
+ int pbitlength = (strength + 1) / 2;
+ int qbitlength = strength - pbitlength;
+ int mindiffbits = strength / 3;
+ int minWeight = strength >> 2;
- // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
- // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")
+ e = param.getPublicExponent();
- p = chooseRandomPrime(pBitlength, e);
+ // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
+ // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")
- //
- // generate a modulus of the required length
- //
- for (;;)
- {
- q = chooseRandomPrime(qBitlength, e);
-
- // p and q should not be too close together (or equal!)
- BigInteger diff = q.subtract(p).abs();
- if (diff.bitLength() < mindiffbits)
- {
- continue;
- }
+ p = chooseRandomPrime(pbitlength, e);
//
- // calculate the modulus
+ // generate a modulus of the required length
//
- n = p.multiply(q);
-
- if (n.bitLength() != strength)
+ for (;;)
{
+ q = chooseRandomPrime(qbitlength, e);
+
+ // p and q should not be too close together (or equal!)
+ BigInteger diff = q.subtract(p).abs();
+ if (diff.bitLength() < mindiffbits)
+ {
+ continue;
+ }
+
//
- // if we get here our primes aren't big enough, make the largest
- // of the two p and try again
+ // calculate the modulus
//
- p = p.max(q);
- continue;
- }
-
- /*
- * Require a minimum weight of the NAF representation, since low-weight composites may
- * be weak against a version of the number-field-sieve for factoring.
- *
- * See "The number field sieve for integers of low weight", Oliver Schirokauer.
- */
- if (WNafUtil.getNafWeight(n) < minWeight)
+ n = p.multiply(q);
+
+ if (n.bitLength() != strength)
+ {
+ //
+ // if we get here our primes aren't big enough, make the largest
+ // of the two p and try again
+ //
+ p = p.max(q);
+ continue;
+ }
+
+ /*
+ * Require a minimum weight of the NAF representation, since low-weight composites may
+ * be weak against a version of the number-field-sieve for factoring.
+ *
+ * See "The number field sieve for integers of low weight", Oliver Schirokauer.
+ */
+ if (WNafUtil.getNafWeight(n) < minWeight)
+ {
+ p = chooseRandomPrime(pbitlength, e);
+ continue;
+ }
+
+ break;
+ }
+
+ if (p.compareTo(q) < 0)
{
- p = chooseRandomPrime(pBitlength, e);
- continue;
+ phi = p;
+ p = q;
+ q = phi;
}
- break;
- }
+ pSub1 = p.subtract(ONE);
+ qSub1 = q.subtract(ONE);
+ phi = pSub1.multiply(qSub1);
+ lcm = phi.divide(pSub1.gcd(qSub1));
- if (p.compareTo(q) < 0)
- {
- phi = p;
- p = q;
- q = phi;
- }
+ //
+ // calculate the private exponent
+ //
+ d = e.modInverse(lcm);
- pSub1 = p.subtract(ONE);
- qSub1 = q.subtract(ONE);
- phi = pSub1.multiply(qSub1);
+ // if d is less than or equal to dLowerBound, we need to start over
+ // also, for backward compatibility, if d is not the same as
+ // e.modInverse(phi), we need to start over
- //
- // calculate the private exponent
- //
- d = e.modInverse(phi);
+ if (d.bitLength() <= qbitlength || !d.equals(e.modInverse(phi)))
+ {
+ continue;
+ }
+ else
+ {
+ done = true;
+ }
- //
- // calculate the CRT factors
- //
- BigInteger dP, dQ, qInv;
+ //
+ // calculate the CRT factors
+ //
+ BigInteger dP, dQ, qInv;
- dP = d.remainder(pSub1);
- dQ = d.remainder(qSub1);
- qInv = q.modInverse(p);
+ dP = d.remainder(pSub1);
+ dQ = d.remainder(qSub1);
+ qInv = q.modInverse(p);
+
+ result = new AsymmetricCipherKeyPair(
+ new RSAKeyParameters(false, n, e),
+ new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
+ }
- return new AsymmetricCipherKeyPair(
- new RSAKeyParameters(false, n, e),
- new RSAPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
+ return result;
}
/**