BigIntegers.java revision c37f4a04ef89e73a39a59f3c5a179af8c8ab5974
1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.util; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.math.BigInteger; 4c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.security.SecureRandom; 5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * BigInteger utilities. 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic final class BigIntegers 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final int MAX_ITERATIONS = 1000; 12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final BigInteger ZERO = BigInteger.valueOf(0); 13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Return the passed in value as an unsigned byte array. 16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param value value to be converted. 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @return a byte array without a leading zero byte if present in the signed encoding. 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static byte[] asUnsignedByteArray( 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam BigInteger value) 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] bytes = value.toByteArray(); 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (bytes[0] == 0) 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] tmp = new byte[bytes.length - 1]; 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam System.arraycopy(bytes, 1, tmp, 0, tmp.length); 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return tmp; 32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return bytes; 35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom /** 38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * Return a random BigInteger not less than 'min' and not greater than 'max' 39c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * 40c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param min the least value that may be generated 41c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param max the greatest value that may be generated 42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param random the source of randomness 43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @return a random BigInteger value in the range [min,max] 44c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 45c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public static BigInteger createRandomInRange( 46c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger min, 47c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger max, 48c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom SecureRandom random) 49c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int cmp = min.compareTo(max); 51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (cmp >= 0) 52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (cmp > 0) 54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IllegalArgumentException("'min' may not be greater than 'max'"); 56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 57c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return min; 59c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 60c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 61c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (min.bitLength() > max.bitLength() / 2) 62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return createRandomInRange(ZERO, max.subtract(min), random).add(min); 64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom for (int i = 0; i < MAX_ITERATIONS; ++i) 67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger x = new BigInteger(max.bitLength(), random); 69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (x.compareTo(min) >= 0 && x.compareTo(max) <= 0) 70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return x; 72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // fall back to a faster (restricted) method 76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return new BigInteger(max.subtract(min).bitLength() - 1, random).add(min); 77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 79