diff options
Diffstat (limited to 'core/src/main/java/org/spongycastle/crypto/generators/ECKeyPairGenerator.java')
-rw-r--r-- | core/src/main/java/org/spongycastle/crypto/generators/ECKeyPairGenerator.java | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/crypto/generators/ECKeyPairGenerator.java b/core/src/main/java/org/spongycastle/crypto/generators/ECKeyPairGenerator.java new file mode 100644 index 00000000..62b12b9a --- /dev/null +++ b/core/src/main/java/org/spongycastle/crypto/generators/ECKeyPairGenerator.java @@ -0,0 +1,84 @@ +package org.spongycastle.crypto.generators; + +import java.math.BigInteger; +import java.security.SecureRandom; + +import org.spongycastle.crypto.AsymmetricCipherKeyPair; +import org.spongycastle.crypto.AsymmetricCipherKeyPairGenerator; +import org.spongycastle.crypto.KeyGenerationParameters; +import org.spongycastle.crypto.params.ECDomainParameters; +import org.spongycastle.crypto.params.ECKeyGenerationParameters; +import org.spongycastle.crypto.params.ECPrivateKeyParameters; +import org.spongycastle.crypto.params.ECPublicKeyParameters; +import org.spongycastle.math.ec.ECConstants; +import org.spongycastle.math.ec.ECMultiplier; +import org.spongycastle.math.ec.ECPoint; +import org.spongycastle.math.ec.FixedPointCombMultiplier; +import org.spongycastle.math.ec.WNafUtil; + +public class ECKeyPairGenerator + implements AsymmetricCipherKeyPairGenerator, ECConstants +{ + ECDomainParameters params; + SecureRandom random; + + public void init( + KeyGenerationParameters param) + { + ECKeyGenerationParameters ecP = (ECKeyGenerationParameters)param; + + this.random = ecP.getRandom(); + this.params = ecP.getDomainParameters(); + + if (this.random == null) + { + this.random = new SecureRandom(); + } + } + + /** + * Given the domain parameters this routine generates an EC key + * pair in accordance with X9.62 section 5.2.1 pages 26, 27. + */ + public AsymmetricCipherKeyPair generateKeyPair() + { + BigInteger n = params.getN(); + int nBitLength = n.bitLength(); + int minWeight = nBitLength >>> 2; + + BigInteger d; + for (;;) + { + d = new BigInteger(nBitLength, random); + + if (d.compareTo(TWO) < 0 || (d.compareTo(n) >= 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(d) < minWeight) + { + continue; + } + + break; + } + + ECPoint Q = createBasePointMultiplier().multiply(params.getG(), d); + + return new AsymmetricCipherKeyPair( + new ECPublicKeyParameters(Q, params), + new ECPrivateKeyParameters(d, params)); + } + + protected ECMultiplier createBasePointMultiplier() + { + return new FixedPointCombMultiplier(); + } +} |