diff options
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.java | 166 |
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; } /** |