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