diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-07-24 08:12:48 +0400 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-07-24 08:12:48 +0400 |
commit | e91c9e11bff64d5101e87e5ad3d4b44f4afac27a (patch) | |
tree | ec25bd07ed622ce42a7c6ddf2582e9e96ecf76c6 | |
parent | d215105264e3f52cb845926ff85b12be1c65eac4 (diff) |
Apply low-hamming-weight NAF check for more generators
3 files changed, 57 insertions, 15 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/DHKeyGeneratorHelper.java b/core/src/main/java/org/bouncycastle/crypto/generators/DHKeyGeneratorHelper.java index d395d5d3..6795ec96 100644 --- a/core/src/main/java/org/bouncycastle/crypto/generators/DHKeyGeneratorHelper.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/DHKeyGeneratorHelper.java @@ -4,6 +4,7 @@ import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.params.DHParameters; +import org.bouncycastle.math.ec.WNafUtil; import org.bouncycastle.util.BigIntegers; class DHKeyGeneratorHelper @@ -23,7 +24,15 @@ class DHKeyGeneratorHelper if (limit != 0) { - return new BigInteger(limit, random).setBit(limit - 1); + int minWeight = limit >>> 2; + for (;;) + { + BigInteger x = new BigInteger(limit, random).setBit(limit - 1); + if (WNafUtil.getNafWeight(x) >= minWeight) + { + return x; + } + } } BigInteger min = TWO; @@ -40,7 +49,15 @@ class DHKeyGeneratorHelper } BigInteger max = q.subtract(TWO); - return BigIntegers.createRandomInRange(min, max, random); + int minWeight = max.bitLength() >>> 2; + for (;;) + { + BigInteger x = BigIntegers.createRandomInRange(min, max, random); + if (WNafUtil.getNafWeight(x) >= minWeight) + { + return x; + } + } } BigInteger calculatePublic(DHParameters dhParams, BigInteger x) diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java index 93f49cfa..ff3df358 100644 --- a/core/src/main/java/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/DSAKeyPairGenerator.java @@ -1,5 +1,8 @@ package org.bouncycastle.crypto.generators; +import java.math.BigInteger; +import java.security.SecureRandom; + import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; @@ -7,11 +10,9 @@ import org.bouncycastle.crypto.params.DSAKeyGenerationParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; +import org.bouncycastle.math.ec.WNafUtil; import org.bouncycastle.util.BigIntegers; -import java.math.BigInteger; -import java.security.SecureRandom; - /** * a DSA key pair generator. * @@ -45,13 +46,20 @@ public class DSAKeyPairGenerator private static BigInteger generatePrivateKey(BigInteger q, SecureRandom random) { - // TODO Prefer this method? (change test cases that used fixed random) - // B.1.1 Key Pair Generation Using Extra Random Bits -// BigInteger c = new BigInteger(q.bitLength() + 64, random); -// return c.mod(q.subtract(ONE)).add(ONE); - // B.1.2 Key Pair Generation by Testing Candidates - return BigIntegers.createRandomInRange(ONE, q.subtract(ONE), random); + int minWeight = q.bitLength() >>> 2; + for (;;) + { + // TODO Prefer this method? (change test cases that used fixed random) + // B.1.1 Key Pair Generation Using Extra Random Bits +// BigInteger x = new BigInteger(q.bitLength() + 64, random).mod(q.subtract(ONE)).add(ONE); + + BigInteger x = BigIntegers.createRandomInRange(ONE, q.subtract(ONE), random); + if (WNafUtil.getNafWeight(x) >= minWeight) + { + return x; + } + } } private static BigInteger calculatePublicKey(BigInteger p, BigInteger g, BigInteger x) diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/GOST3410KeyPairGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/GOST3410KeyPairGenerator.java index 3e13c212..8948f931 100644 --- a/core/src/main/java/org/bouncycastle/crypto/generators/GOST3410KeyPairGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/GOST3410KeyPairGenerator.java @@ -7,6 +7,7 @@ import org.bouncycastle.crypto.params.GOST3410KeyGenerationParameters; import org.bouncycastle.crypto.params.GOST3410Parameters; import org.bouncycastle.crypto.params.GOST3410PrivateKeyParameters; import org.bouncycastle.crypto.params.GOST3410PublicKeyParameters; +import org.bouncycastle.math.ec.WNafUtil; import java.math.BigInteger; import java.security.SecureRandom; @@ -19,8 +20,6 @@ import java.security.SecureRandom; public class GOST3410KeyPairGenerator implements AsymmetricCipherKeyPairGenerator { - private static final BigInteger ZERO = BigInteger.valueOf(0); - private GOST3410KeyGenerationParameters param; public void init( @@ -39,11 +38,29 @@ public class GOST3410KeyPairGenerator p = GOST3410Params.getP(); a = GOST3410Params.getA(); - do + int minWeight = 64; + for (;;) { x = new BigInteger(256, random); + + if (x.signum() < 1 || x.compareTo(q) >= 0) + { + continue; + } + + /* + * Require a minimum weight of the NAF representation, since low-weight primes may be + * weak against a version of the number-field-sieve for the discrete-logarithm-problem. + * + * See "The number field sieve for integers of low weight", Oliver Schirokauer. + */ + if (WNafUtil.getNafWeight(x) < minWeight) + { + continue; + } + + break; } - while (x.equals(ZERO) || x.compareTo(q) >= 0); // // calculate the public key. |