package org.bouncycastle.crypto.generators; import java.math.BigInteger; import java.security.SecureRandom; class DHKeyGeneratorHelper { private static final int MAX_ITERATIONS = 1000; static final DHKeyGeneratorHelper INSTANCE = new DHKeyGeneratorHelper(); private static BigInteger ZERO = BigInteger.valueOf(0); private static BigInteger TWO = BigInteger.valueOf(2); private DHKeyGeneratorHelper() { } BigInteger calculatePrivate(BigInteger p, SecureRandom random, int limit) { // // calculate the private key // BigInteger pSub2 = p.subtract(TWO); BigInteger x; if (limit == 0) { x = createInRange(pSub2, random); } else { do { x = new BigInteger(limit, random); } while (x.equals(ZERO)); } return x; } private BigInteger createInRange(BigInteger max, SecureRandom random) { BigInteger x; int maxLength = max.bitLength(); int count = 0; do { x = new BigInteger(maxLength, random); count++; } while ((x.equals(ZERO) || x.compareTo(max) > 0) && count != MAX_ITERATIONS); if (count == MAX_ITERATIONS) // fall back to a faster (restricted) method { return new BigInteger(maxLength - 1, random).setBit(0); } return x; } BigInteger calculatePublic(BigInteger p, BigInteger g, BigInteger x) { return g.modPow(x, p); } }