1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.crypto.generators; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.math.BigInteger; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.SecureRandom; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.crypto.params.DHParameters; 7d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.math.ec.WNafUtil; 8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.util.BigIntegers; 9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamclass DHKeyGeneratorHelper 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam static final DHKeyGeneratorHelper INSTANCE = new DHKeyGeneratorHelper(); 13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final BigInteger ONE = BigInteger.valueOf(1); 15c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final BigInteger TWO = BigInteger.valueOf(2); 16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam private DHKeyGeneratorHelper() 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 20c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 21c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger calculatePrivate(DHParameters dhParams, SecureRandom random) 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int limit = dhParams.getL(); 24c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (limit != 0) 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 27d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int minWeight = limit >>> 2; 28d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root for (;;) 29d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 30d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root BigInteger x = new BigInteger(limit, random).setBit(limit - 1); 31d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (WNafUtil.getNafWeight(x) >= minWeight) 32d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 33d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return x; 34d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 35d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger min = TWO; 39c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int m = dhParams.getM(); 40c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (m != 0) 41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom min = ONE.shiftLeft(m - 1); 43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 44c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 45c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger q = dhParams.getQ(); 46d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (q == null) 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 48d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root q = dhParams.getP(); 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 50d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root BigInteger max = q.subtract(TWO); 51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 52d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root int minWeight = max.bitLength() >>> 2; 53d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root for (;;) 54d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 55d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root BigInteger x = BigIntegers.createRandomInRange(min, max, random); 56d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root if (WNafUtil.getNafWeight(x) >= minWeight) 57d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root { 58d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root return x; 59d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 60d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root } 61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger calculatePublic(DHParameters dhParams, BigInteger x) 64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return dhParams.getG().modPow(x, dhParams.getP()); 66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 68