| package org.bouncycastle.util; |
| |
| import java.math.BigInteger; |
| import java.security.SecureRandom; |
| |
| /** |
| * BigInteger utilities. |
| */ |
| public final class BigIntegers |
| { |
| private static final int MAX_ITERATIONS = 1000; |
| private static final BigInteger ZERO = BigInteger.valueOf(0); |
| |
| /** |
| * Return the passed in value as an unsigned byte array. |
| * |
| * @param value value to be converted. |
| * @return a byte array without a leading zero byte if present in the signed encoding. |
| */ |
| public static byte[] asUnsignedByteArray( |
| BigInteger value) |
| { |
| byte[] bytes = value.toByteArray(); |
| |
| if (bytes[0] == 0) |
| { |
| byte[] tmp = new byte[bytes.length - 1]; |
| |
| System.arraycopy(bytes, 1, tmp, 0, tmp.length); |
| |
| return tmp; |
| } |
| |
| return bytes; |
| } |
| |
| /** |
| * Return a random BigInteger not less than 'min' and not greater than 'max' |
| * |
| * @param min the least value that may be generated |
| * @param max the greatest value that may be generated |
| * @param random the source of randomness |
| * @return a random BigInteger value in the range [min,max] |
| */ |
| public static BigInteger createRandomInRange( |
| BigInteger min, |
| BigInteger max, |
| SecureRandom random) |
| { |
| int cmp = min.compareTo(max); |
| if (cmp >= 0) |
| { |
| if (cmp > 0) |
| { |
| throw new IllegalArgumentException("'min' may not be greater than 'max'"); |
| } |
| |
| return min; |
| } |
| |
| if (min.bitLength() > max.bitLength() / 2) |
| { |
| return createRandomInRange(ZERO, max.subtract(min), random).add(min); |
| } |
| |
| for (int i = 0; i < MAX_ITERATIONS; ++i) |
| { |
| BigInteger x = new BigInteger(max.bitLength(), random); |
| if (x.compareTo(min) >= 0 && x.compareTo(max) <= 0) |
| { |
| return x; |
| } |
| } |
| |
| // fall back to a faster (restricted) method |
| return new BigInteger(max.subtract(min).bitLength() - 1, random).add(min); |
| } |
| } |