1package org.bouncycastle.crypto.generators; 2 3import org.bouncycastle.crypto.AsymmetricCipherKeyPair; 4import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; 5import org.bouncycastle.crypto.KeyGenerationParameters; 6import org.bouncycastle.crypto.params.DSAKeyGenerationParameters; 7import org.bouncycastle.crypto.params.DSAParameters; 8import org.bouncycastle.crypto.params.DSAPrivateKeyParameters; 9import org.bouncycastle.crypto.params.DSAPublicKeyParameters; 10import org.bouncycastle.util.BigIntegers; 11 12import java.math.BigInteger; 13import java.security.SecureRandom; 14 15/** 16 * a DSA key pair generator. 17 * 18 * This generates DSA keys in line with the method described 19 * in <i>FIPS 186-3 B.1 FFC Key Pair Generation</i>. 20 */ 21public class DSAKeyPairGenerator 22 implements AsymmetricCipherKeyPairGenerator 23{ 24 private static final BigInteger ONE = BigInteger.valueOf(1); 25 26 private DSAKeyGenerationParameters param; 27 28 public void init( 29 KeyGenerationParameters param) 30 { 31 this.param = (DSAKeyGenerationParameters)param; 32 } 33 34 public AsymmetricCipherKeyPair generateKeyPair() 35 { 36 DSAParameters dsaParams = param.getParameters(); 37 38 BigInteger x = generatePrivateKey(dsaParams.getQ(), param.getRandom()); 39 BigInteger y = calculatePublicKey(dsaParams.getP(), dsaParams.getG(), x); 40 41 return new AsymmetricCipherKeyPair( 42 new DSAPublicKeyParameters(y, dsaParams), 43 new DSAPrivateKeyParameters(x, dsaParams)); 44 } 45 46 private static BigInteger generatePrivateKey(BigInteger q, SecureRandom random) 47 { 48 // TODO Prefer this method? (change test cases that used fixed random) 49 // B.1.1 Key Pair Generation Using Extra Random Bits 50// BigInteger c = new BigInteger(q.bitLength() + 64, random); 51// return c.mod(q.subtract(ONE)).add(ONE); 52 53 // B.1.2 Key Pair Generation by Testing Candidates 54 return BigIntegers.createRandomInRange(ONE, q.subtract(ONE), random); 55 } 56 57 private static BigInteger calculatePublicKey(BigInteger p, BigInteger g, BigInteger x) 58 { 59 return g.modPow(x, p); 60 } 61} 62