• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.util;
2 
3 import java.math.BigInteger;
4 import java.security.SecureRandom;
5 
6 /**
7  * BigInteger utilities.
8  */
9 public 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      */
asUnsignedByteArray( BigInteger value)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 the passed in value as an unsigned byte array.
39      *
40      * @param value value to be converted.
41      * @return a byte array without a leading zero byte if present in the signed encoding.
42      */
asUnsignedByteArray(int length, BigInteger value)43     public static byte[] asUnsignedByteArray(int length, BigInteger value)
44     {
45         byte[] bytes = value.toByteArray();
46         if (bytes.length == length)
47         {
48             return bytes;
49         }
50 
51         int start = bytes[0] == 0 ? 1 : 0;
52         int count = bytes.length - start;
53 
54         if (count > length)
55         {
56             throw new IllegalArgumentException("standard length exceeded for value");
57         }
58 
59         byte[] tmp = new byte[length];
60         System.arraycopy(bytes, start, tmp, tmp.length - count, count);
61         return tmp;
62     }
63 
64     /**
65      * Return a random BigInteger not less than 'min' and not greater than 'max'
66      *
67      * @param min the least value that may be generated
68      * @param max the greatest value that may be generated
69      * @param random the source of randomness
70      * @return a random BigInteger value in the range [min,max]
71      */
createRandomInRange( BigInteger min, BigInteger max, SecureRandom random)72     public static BigInteger createRandomInRange(
73         BigInteger      min,
74         BigInteger      max,
75         SecureRandom    random)
76     {
77         int cmp = min.compareTo(max);
78         if (cmp >= 0)
79         {
80             if (cmp > 0)
81             {
82                 throw new IllegalArgumentException("'min' may not be greater than 'max'");
83             }
84 
85             return min;
86         }
87 
88         if (min.bitLength() > max.bitLength() / 2)
89         {
90             return createRandomInRange(ZERO, max.subtract(min), random).add(min);
91         }
92 
93         for (int i = 0; i < MAX_ITERATIONS; ++i)
94         {
95             BigInteger x = new BigInteger(max.bitLength(), random);
96             if (x.compareTo(min) >= 0 && x.compareTo(max) <= 0)
97             {
98                 return x;
99             }
100         }
101 
102         // fall back to a faster (restricted) method
103         return new BigInteger(max.subtract(min).bitLength() - 1, random).add(min);
104     }
105 
fromUnsignedByteArray(byte[] buf)106     public static BigInteger fromUnsignedByteArray(byte[] buf)
107     {
108         return new BigInteger(1, buf);
109     }
110 
fromUnsignedByteArray(byte[] buf, int off, int length)111     public static BigInteger fromUnsignedByteArray(byte[] buf, int off, int length)
112     {
113         byte[] mag = buf;
114         if (off != 0 || length != buf.length)
115         {
116             mag = new byte[length];
117             System.arraycopy(buf, off, mag, 0, length);
118         }
119         return new BigInteger(1, mag);
120     }
121 }
122