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