blob: c8d63261e706ef0ba49ea87d8afa254543fdf3a8 [file] [log] [blame]
darcy32db4492009-01-26 19:49:26 -08001/*
bpb28090952013-06-19 08:59:39 -07002 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
darcy32db4492009-01-26 19:49:26 -08003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
ohair2283b9d2010-05-25 15:58:33 -070019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
darcy32db4492009-01-26 19:49:26 -080022 */
23
24/*
25 * @test
bpb28090952013-06-19 08:59:39 -070026 * @bug 4181191 4161971 4227146 4194389 4823171 4624738 4812225 4837946
darcy32db4492009-01-26 19:49:26 -080027 * @summary tests methods in BigInteger
28 * @run main/timeout=400 BigIntegerTest
29 * @author madbot
30 */
31
bpb28090952013-06-19 08:59:39 -070032import java.io.File;
33import java.io.FileInputStream;
34import java.io.FileOutputStream;
35import java.io.ObjectInputStream;
36import java.io.ObjectOutputStream;
darcy32db4492009-01-26 19:49:26 -080037import java.math.BigInteger;
bpb28090952013-06-19 08:59:39 -070038import java.util.Random;
darcy32db4492009-01-26 19:49:26 -080039
40/**
41 * This is a simple test class created to ensure that the results
42 * generated by BigInteger adhere to certain identities. Passing
43 * this test is a strong assurance that the BigInteger operations
44 * are working correctly.
45 *
bpb4e3b9202013-07-26 17:03:19 -070046 * Four arguments may be specified which give the number of
47 * decimal digits you desire in the four batches of test numbers.
darcy32db4492009-01-26 19:49:26 -080048 *
49 * The tests are performed on arrays of random numbers which are
50 * generated by a Random class as well as special cases which
bpb4a9dee72013-07-26 17:09:30 -070051 * throw in boundary numbers such as 0, 1, maximum sized, etc.
darcy32db4492009-01-26 19:49:26 -080052 *
53 */
54public class BigIntegerTest {
bpb28090952013-06-19 08:59:39 -070055 //
56 // Bit large number thresholds based on the int thresholds
57 // defined in BigInteger itself:
58 //
bpb3c7ad6d2013-12-05 07:44:59 -080059 // KARATSUBA_THRESHOLD = 80 ints = 2560 bits
60 // TOOM_COOK_THRESHOLD = 240 ints = 7680 bits
61 // KARATSUBA_SQUARE_THRESHOLD = 128 ints = 4096 bits
62 // TOOM_COOK_SQUARE_THRESHOLD = 216 ints = 6912 bits
bpb28090952013-06-19 08:59:39 -070063 //
bpb3c7ad6d2013-12-05 07:44:59 -080064 // SCHOENHAGE_BASE_CONVERSION_THRESHOLD = 20 ints = 640 bits
bpb3c584672013-06-20 12:15:24 -070065 //
bpb3c7ad6d2013-12-05 07:44:59 -080066 // BURNIKEL_ZIEGLER_THRESHOLD = 80 ints = 2560 bits
bpb4e3b9202013-07-26 17:03:19 -070067 //
bpb3c7ad6d2013-12-05 07:44:59 -080068 static final int BITS_KARATSUBA = 2560;
69 static final int BITS_TOOM_COOK = 7680;
70 static final int BITS_KARATSUBA_SQUARE = 4096;
71 static final int BITS_TOOM_COOK_SQUARE = 6912;
72 static final int BITS_SCHOENHAGE_BASE = 640;
73 static final int BITS_BURNIKEL_ZIEGLER = 2560;
bpb17ba0532014-09-15 13:25:08 -070074 static final int BITS_BURNIKEL_ZIEGLER_OFFSET = 1280;
bpb28090952013-06-19 08:59:39 -070075
76 static final int ORDER_SMALL = 60;
77 static final int ORDER_MEDIUM = 100;
bpbc2dd2732013-08-12 16:21:10 -070078 // #bits for testing Karatsuba
bpb3c7ad6d2013-12-05 07:44:59 -080079 static final int ORDER_KARATSUBA = 2760;
bpbc2dd2732013-08-12 16:21:10 -070080 // #bits for testing Toom-Cook and Burnikel-Ziegler
bpb3c7ad6d2013-12-05 07:44:59 -080081 static final int ORDER_TOOM_COOK = 8000;
bpb28090952013-06-19 08:59:39 -070082 // #bits for testing Karatsuba squaring
bpb3c7ad6d2013-12-05 07:44:59 -080083 static final int ORDER_KARATSUBA_SQUARE = 4200;
bpb28090952013-06-19 08:59:39 -070084 // #bits for testing Toom-Cook squaring
bpb3c7ad6d2013-12-05 07:44:59 -080085 static final int ORDER_TOOM_COOK_SQUARE = 7000;
bpb28090952013-06-19 08:59:39 -070086
bpb4e3b9202013-07-26 17:03:19 -070087 static final int SIZE = 1000; // numbers per batch
88
darcy32db4492009-01-26 19:49:26 -080089 static Random rnd = new Random();
darcy32db4492009-01-26 19:49:26 -080090 static boolean failure = false;
91
bpb28090952013-06-19 08:59:39 -070092 public static void pow(int order) {
darcy32db4492009-01-26 19:49:26 -080093 int failCount1 = 0;
94
bpb4e3b9202013-07-26 17:03:19 -070095 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -070096 // Test identity x^power == x*x*x ... *x
97 int power = rnd.nextInt(6) + 2;
98 BigInteger x = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -080099 BigInteger y = x.pow(power);
100 BigInteger z = x;
101
102 for (int j=1; j<power; j++)
103 z = z.multiply(x);
104
105 if (!y.equals(z))
106 failCount1++;
107 }
bpb28090952013-06-19 08:59:39 -0700108 report("pow for " + order + " bits", failCount1);
darcy32db4492009-01-26 19:49:26 -0800109 }
110
bpb28090952013-06-19 08:59:39 -0700111 public static void square(int order) {
112 int failCount1 = 0;
113
bpb4e3b9202013-07-26 17:03:19 -0700114 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700115 // Test identity x^2 == x*x
116 BigInteger x = fetchNumber(order);
117 BigInteger xx = x.multiply(x);
118 BigInteger x2 = x.pow(2);
119
120 if (!x2.equals(xx))
121 failCount1++;
122 }
123 report("square for " + order + " bits", failCount1);
124 }
125
126 public static void arithmetic(int order) {
darcy32db4492009-01-26 19:49:26 -0800127 int failCount = 0;
128
bpb4e3b9202013-07-26 17:03:19 -0700129 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700130 BigInteger x = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -0800131 while(x.compareTo(BigInteger.ZERO) != 1)
bpb28090952013-06-19 08:59:39 -0700132 x = fetchNumber(order);
133 BigInteger y = fetchNumber(order/2);
darcy32db4492009-01-26 19:49:26 -0800134 while(x.compareTo(y) == -1)
bpb28090952013-06-19 08:59:39 -0700135 y = fetchNumber(order/2);
darcy32db4492009-01-26 19:49:26 -0800136 if (y.equals(BigInteger.ZERO))
137 y = y.add(BigInteger.ONE);
138
bpb28090952013-06-19 08:59:39 -0700139 // Test identity ((x/y))*y + x%y - x == 0
140 // using separate divide() and remainder()
darcy32db4492009-01-26 19:49:26 -0800141 BigInteger baz = x.divide(y);
142 baz = baz.multiply(y);
143 baz = baz.add(x.remainder(y));
144 baz = baz.subtract(x);
145 if (!baz.equals(BigInteger.ZERO))
146 failCount++;
147 }
bpb28090952013-06-19 08:59:39 -0700148 report("Arithmetic I for " + order + " bits", failCount);
darcy32db4492009-01-26 19:49:26 -0800149
150 failCount = 0;
151 for (int i=0; i<100; i++) {
bpb28090952013-06-19 08:59:39 -0700152 BigInteger x = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -0800153 while(x.compareTo(BigInteger.ZERO) != 1)
bpb28090952013-06-19 08:59:39 -0700154 x = fetchNumber(order);
155 BigInteger y = fetchNumber(order/2);
darcy32db4492009-01-26 19:49:26 -0800156 while(x.compareTo(y) == -1)
bpb28090952013-06-19 08:59:39 -0700157 y = fetchNumber(order/2);
darcy32db4492009-01-26 19:49:26 -0800158 if (y.equals(BigInteger.ZERO))
159 y = y.add(BigInteger.ONE);
160
bpb28090952013-06-19 08:59:39 -0700161 // Test identity ((x/y))*y + x%y - x == 0
162 // using divideAndRemainder()
darcy32db4492009-01-26 19:49:26 -0800163 BigInteger baz[] = x.divideAndRemainder(y);
164 baz[0] = baz[0].multiply(y);
165 baz[0] = baz[0].add(baz[1]);
166 baz[0] = baz[0].subtract(x);
167 if (!baz[0].equals(BigInteger.ZERO))
168 failCount++;
169 }
bpb28090952013-06-19 08:59:39 -0700170 report("Arithmetic II for " + order + " bits", failCount);
171 }
172
173 /**
174 * Sanity test for Karatsuba and 3-way Toom-Cook multiplication.
175 * For each of the Karatsuba and 3-way Toom-Cook multiplication thresholds,
176 * construct two factors each with a mag array one element shorter than the
177 * threshold, and with the most significant bit set and the rest of the bits
178 * random. Each of these numbers will therefore be below the threshold but
179 * if shifted left be above the threshold. Call the numbers 'u' and 'v' and
180 * define random shifts 'a' and 'b' in the range [1,32]. Then we have the
181 * identity
182 * <pre>
183 * (u << a)*(v << b) = (u*v) << (a + b)
184 * </pre>
185 * For Karatsuba multiplication, the right hand expression will be evaluated
186 * using the standard naive algorithm, and the left hand expression using
187 * the Karatsuba algorithm. For 3-way Toom-Cook multiplication, the right
188 * hand expression will be evaluated using Karatsuba multiplication, and the
189 * left hand expression using 3-way Toom-Cook multiplication.
190 */
191 public static void multiplyLarge() {
192 int failCount = 0;
193
194 BigInteger base = BigInteger.ONE.shiftLeft(BITS_KARATSUBA - 32 - 1);
bpb4e3b9202013-07-26 17:03:19 -0700195 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700196 BigInteger x = fetchNumber(BITS_KARATSUBA - 32 - 1);
197 BigInteger u = base.add(x);
198 int a = 1 + rnd.nextInt(31);
199 BigInteger w = u.shiftLeft(a);
200
201 BigInteger y = fetchNumber(BITS_KARATSUBA - 32 - 1);
202 BigInteger v = base.add(y);
203 int b = 1 + rnd.nextInt(32);
204 BigInteger z = v.shiftLeft(b);
205
206 BigInteger multiplyResult = u.multiply(v).shiftLeft(a + b);
207 BigInteger karatsubaMultiplyResult = w.multiply(z);
208
209 if (!multiplyResult.equals(karatsubaMultiplyResult)) {
210 failCount++;
211 }
212 }
213
214 report("multiplyLarge Karatsuba", failCount);
215
216 failCount = 0;
217 base = base.shiftLeft(BITS_TOOM_COOK - BITS_KARATSUBA);
bpb4e3b9202013-07-26 17:03:19 -0700218 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700219 BigInteger x = fetchNumber(BITS_TOOM_COOK - 32 - 1);
220 BigInteger u = base.add(x);
221 BigInteger u2 = u.shiftLeft(1);
222 BigInteger y = fetchNumber(BITS_TOOM_COOK - 32 - 1);
223 BigInteger v = base.add(y);
224 BigInteger v2 = v.shiftLeft(1);
225
226 BigInteger multiplyResult = u.multiply(v).shiftLeft(2);
227 BigInteger toomCookMultiplyResult = u2.multiply(v2);
228
229 if (!multiplyResult.equals(toomCookMultiplyResult)) {
230 failCount++;
231 }
232 }
233
234 report("multiplyLarge Toom-Cook", failCount);
235 }
236
237 /**
238 * Sanity test for Karatsuba and 3-way Toom-Cook squaring.
239 * This test is analogous to {@link AbstractMethodError#multiplyLarge}
240 * with both factors being equal. The squaring methods will not be tested
241 * unless the <code>bigInteger.multiply(bigInteger)</code> tests whether
242 * the parameter is the same instance on which the method is being invoked
243 * and calls <code>square()</code> accordingly.
244 */
245 public static void squareLarge() {
246 int failCount = 0;
247
248 BigInteger base = BigInteger.ONE.shiftLeft(BITS_KARATSUBA_SQUARE - 32 - 1);
bpb4e3b9202013-07-26 17:03:19 -0700249 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700250 BigInteger x = fetchNumber(BITS_KARATSUBA_SQUARE - 32 - 1);
251 BigInteger u = base.add(x);
252 int a = 1 + rnd.nextInt(31);
253 BigInteger w = u.shiftLeft(a);
254
255 BigInteger squareResult = u.multiply(u).shiftLeft(2*a);
256 BigInteger karatsubaSquareResult = w.multiply(w);
257
258 if (!squareResult.equals(karatsubaSquareResult)) {
259 failCount++;
260 }
261 }
262
263 report("squareLarge Karatsuba", failCount);
264
265 failCount = 0;
266 base = base.shiftLeft(BITS_TOOM_COOK_SQUARE - BITS_KARATSUBA_SQUARE);
bpb4e3b9202013-07-26 17:03:19 -0700267 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700268 BigInteger x = fetchNumber(BITS_TOOM_COOK_SQUARE - 32 - 1);
269 BigInteger u = base.add(x);
270 int a = 1 + rnd.nextInt(31);
271 BigInteger w = u.shiftLeft(a);
272
273 BigInteger squareResult = u.multiply(u).shiftLeft(2*a);
274 BigInteger toomCookSquareResult = w.multiply(w);
275
276 if (!squareResult.equals(toomCookSquareResult)) {
277 failCount++;
278 }
279 }
280
281 report("squareLarge Toom-Cook", failCount);
darcy32db4492009-01-26 19:49:26 -0800282 }
283
bpb4e3b9202013-07-26 17:03:19 -0700284 /**
285 * Sanity test for Burnikel-Ziegler division. The Burnikel-Ziegler division
286 * algorithm is used when each of the dividend and the divisor has at least
287 * a specified number of ints in its representation. This test is based on
288 * the observation that if {@code w = u*pow(2,a)} and {@code z = v*pow(2,b)}
289 * where {@code abs(u) > abs(v)} and {@code a > b && b > 0}, then if
290 * {@code w/z = q1*z + r1} and {@code u/v = q2*v + r2}, then
291 * {@code q1 = q2*pow(2,a-b)} and {@code r1 = r2*pow(2,b)}. The test
bpb7dca50a2014-09-17 11:04:16 -0700292 * ensures that {@code v} is just under the B-Z threshold, that {@code z} is
293 * over the threshold and {@code w} is much larger than {@code z}. This
294 * implies that {@code u/v} uses the standard division algorithm and
bpb29b3f7f2014-09-18 10:34:58 -0700295 * {@code w/z} uses the B-Z algorithm. The results of the two algorithms
bpb7dca50a2014-09-17 11:04:16 -0700296 * are then compared using the observation described in the foregoing and
297 * if they are not equal a failure is logged.
bpb4e3b9202013-07-26 17:03:19 -0700298 */
299 public static void divideLarge() {
300 int failCount = 0;
301
bpb17ba0532014-09-15 13:25:08 -0700302 BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 33);
bpb4e3b9202013-07-26 17:03:19 -0700303 for (int i=0; i<SIZE; i++) {
bpb17ba0532014-09-15 13:25:08 -0700304 BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 34, rnd);
bpb4e3b9202013-07-26 17:03:19 -0700305 BigInteger v = base.add(addend);
306
307 BigInteger u = v.multiply(BigInteger.valueOf(2 + rnd.nextInt(Short.MAX_VALUE - 1)));
308
309 if(rnd.nextBoolean()) {
310 u = u.negate();
311 }
312 if(rnd.nextBoolean()) {
313 v = v.negate();
314 }
315
bpb17ba0532014-09-15 13:25:08 -0700316 int a = BITS_BURNIKEL_ZIEGLER_OFFSET + rnd.nextInt(16);
bpb4e3b9202013-07-26 17:03:19 -0700317 int b = 1 + rnd.nextInt(16);
bpb17ba0532014-09-15 13:25:08 -0700318 BigInteger w = u.multiply(BigInteger.ONE.shiftLeft(a));
319 BigInteger z = v.multiply(BigInteger.ONE.shiftLeft(b));
bpb4e3b9202013-07-26 17:03:19 -0700320
321 BigInteger[] divideResult = u.divideAndRemainder(v);
bpb17ba0532014-09-15 13:25:08 -0700322 divideResult[0] = divideResult[0].multiply(BigInteger.ONE.shiftLeft(a - b));
323 divideResult[1] = divideResult[1].multiply(BigInteger.ONE.shiftLeft(b));
bpb4e3b9202013-07-26 17:03:19 -0700324 BigInteger[] bzResult = w.divideAndRemainder(z);
325
326 if (divideResult[0].compareTo(bzResult[0]) != 0 ||
327 divideResult[1].compareTo(bzResult[1]) != 0) {
328 failCount++;
329 }
330 }
331
332 report("divideLarge", failCount);
333 }
334
darcy32db4492009-01-26 19:49:26 -0800335 public static void bitCount() {
336 int failCount = 0;
337
bpb4e3b9202013-07-26 17:03:19 -0700338 for (int i=0; i<SIZE*10; i++) {
darcy32db4492009-01-26 19:49:26 -0800339 int x = rnd.nextInt();
340 BigInteger bigX = BigInteger.valueOf((long)x);
341 int bit = (x < 0 ? 0 : 1);
342 int tmp = x, bitCount = 0;
343 for (int j=0; j<32; j++) {
344 bitCount += ((tmp & 1) == bit ? 1 : 0);
345 tmp >>= 1;
346 }
347
348 if (bigX.bitCount() != bitCount) {
349 //System.err.println(x+": "+bitCount+", "+bigX.bitCount());
350 failCount++;
351 }
352 }
353 report("Bit Count", failCount);
354 }
355
356 public static void bitLength() {
357 int failCount = 0;
358
bpb4e3b9202013-07-26 17:03:19 -0700359 for (int i=0; i<SIZE*10; i++) {
darcy32db4492009-01-26 19:49:26 -0800360 int x = rnd.nextInt();
361 BigInteger bigX = BigInteger.valueOf((long)x);
362 int signBit = (x < 0 ? 0x80000000 : 0);
363 int tmp = x, bitLength, j;
364 for (j=0; j<32 && (tmp & 0x80000000)==signBit; j++)
365 tmp <<= 1;
366 bitLength = 32 - j;
367
368 if (bigX.bitLength() != bitLength) {
369 //System.err.println(x+": "+bitLength+", "+bigX.bitLength());
370 failCount++;
371 }
372 }
373
374 report("BitLength", failCount);
375 }
376
bpb28090952013-06-19 08:59:39 -0700377 public static void bitOps(int order) {
darcy32db4492009-01-26 19:49:26 -0800378 int failCount1 = 0, failCount2 = 0, failCount3 = 0;
379
bpb4e3b9202013-07-26 17:03:19 -0700380 for (int i=0; i<SIZE*5; i++) {
bpb28090952013-06-19 08:59:39 -0700381 BigInteger x = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -0800382 BigInteger y;
383
bpb28090952013-06-19 08:59:39 -0700384 // Test setBit and clearBit (and testBit)
darcy32db4492009-01-26 19:49:26 -0800385 if (x.signum() < 0) {
386 y = BigInteger.valueOf(-1);
387 for (int j=0; j<x.bitLength(); j++)
388 if (!x.testBit(j))
389 y = y.clearBit(j);
390 } else {
391 y = BigInteger.ZERO;
392 for (int j=0; j<x.bitLength(); j++)
393 if (x.testBit(j))
394 y = y.setBit(j);
395 }
396 if (!x.equals(y))
397 failCount1++;
398
bpb28090952013-06-19 08:59:39 -0700399 // Test flipBit (and testBit)
darcy32db4492009-01-26 19:49:26 -0800400 y = BigInteger.valueOf(x.signum()<0 ? -1 : 0);
401 for (int j=0; j<x.bitLength(); j++)
402 if (x.signum()<0 ^ x.testBit(j))
403 y = y.flipBit(j);
404 if (!x.equals(y))
405 failCount2++;
406 }
bpb28090952013-06-19 08:59:39 -0700407 report("clearBit/testBit for " + order + " bits", failCount1);
408 report("flipBit/testBit for " + order + " bits", failCount2);
darcy32db4492009-01-26 19:49:26 -0800409
bpb4e3b9202013-07-26 17:03:19 -0700410 for (int i=0; i<SIZE*5; i++) {
bpb28090952013-06-19 08:59:39 -0700411 BigInteger x = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -0800412
bpb28090952013-06-19 08:59:39 -0700413 // Test getLowestSetBit()
darcy32db4492009-01-26 19:49:26 -0800414 int k = x.getLowestSetBit();
415 if (x.signum() == 0) {
416 if (k != -1)
417 failCount3++;
418 } else {
419 BigInteger z = x.and(x.negate());
420 int j;
421 for (j=0; j<z.bitLength() && !z.testBit(j); j++)
422 ;
423 if (k != j)
424 failCount3++;
425 }
426 }
bpb28090952013-06-19 08:59:39 -0700427 report("getLowestSetBit for " + order + " bits", failCount3);
darcy32db4492009-01-26 19:49:26 -0800428 }
429
bpb28090952013-06-19 08:59:39 -0700430 public static void bitwise(int order) {
darcy32db4492009-01-26 19:49:26 -0800431
bpb28090952013-06-19 08:59:39 -0700432 // Test identity x^y == x|y &~ x&y
darcy32db4492009-01-26 19:49:26 -0800433 int failCount = 0;
bpb4e3b9202013-07-26 17:03:19 -0700434 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700435 BigInteger x = fetchNumber(order);
436 BigInteger y = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -0800437 BigInteger z = x.xor(y);
438 BigInteger w = x.or(y).andNot(x.and(y));
439 if (!z.equals(w))
440 failCount++;
441 }
bpb28090952013-06-19 08:59:39 -0700442 report("Logic (^ | & ~) for " + order + " bits", failCount);
darcy32db4492009-01-26 19:49:26 -0800443
bpb28090952013-06-19 08:59:39 -0700444 // Test identity x &~ y == ~(~x | y)
darcy32db4492009-01-26 19:49:26 -0800445 failCount = 0;
bpb4e3b9202013-07-26 17:03:19 -0700446 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700447 BigInteger x = fetchNumber(order);
448 BigInteger y = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -0800449 BigInteger z = x.andNot(y);
450 BigInteger w = x.not().or(y).not();
451 if (!z.equals(w))
452 failCount++;
453 }
bpb28090952013-06-19 08:59:39 -0700454 report("Logic (&~ | ~) for " + order + " bits", failCount);
darcy32db4492009-01-26 19:49:26 -0800455 }
456
bpb28090952013-06-19 08:59:39 -0700457 public static void shift(int order) {
darcy32db4492009-01-26 19:49:26 -0800458 int failCount1 = 0;
459 int failCount2 = 0;
460 int failCount3 = 0;
461
462 for (int i=0; i<100; i++) {
bpb28090952013-06-19 08:59:39 -0700463 BigInteger x = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -0800464 int n = Math.abs(rnd.nextInt()%200);
465
466 if (!x.shiftLeft(n).equals
467 (x.multiply(BigInteger.valueOf(2L).pow(n))))
468 failCount1++;
469
470 BigInteger y[] =x.divideAndRemainder(BigInteger.valueOf(2L).pow(n));
471 BigInteger z = (x.signum()<0 && y[1].signum()!=0
472 ? y[0].subtract(BigInteger.ONE)
473 : y[0]);
474
475 BigInteger b = x.shiftRight(n);
476
477 if (!b.equals(z)) {
478 System.err.println("Input is "+x.toString(2));
479 System.err.println("shift is "+n);
480
481 System.err.println("Divided "+z.toString(2));
482 System.err.println("Shifted is "+b.toString(2));
483 if (b.toString().equals(z.toString()))
484 System.err.println("Houston, we have a problem.");
485 failCount2++;
486 }
487
488 if (!x.shiftLeft(n).shiftRight(n).equals(x))
489 failCount3++;
490 }
bpb28090952013-06-19 08:59:39 -0700491 report("baz shiftLeft for " + order + " bits", failCount1);
492 report("baz shiftRight for " + order + " bits", failCount2);
493 report("baz shiftLeft/Right for " + order + " bits", failCount3);
darcy32db4492009-01-26 19:49:26 -0800494 }
495
bpb28090952013-06-19 08:59:39 -0700496 public static void divideAndRemainder(int order) {
darcy32db4492009-01-26 19:49:26 -0800497 int failCount1 = 0;
498
bpb4e3b9202013-07-26 17:03:19 -0700499 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700500 BigInteger x = fetchNumber(order).abs();
darcy32db4492009-01-26 19:49:26 -0800501 while(x.compareTo(BigInteger.valueOf(3L)) != 1)
bpb28090952013-06-19 08:59:39 -0700502 x = fetchNumber(order).abs();
darcy32db4492009-01-26 19:49:26 -0800503 BigInteger z = x.divide(BigInteger.valueOf(2L));
504 BigInteger y[] = x.divideAndRemainder(x);
505 if (!y[0].equals(BigInteger.ONE)) {
506 failCount1++;
507 System.err.println("fail1 x :"+x);
508 System.err.println(" y :"+y);
509 }
510 else if (!y[1].equals(BigInteger.ZERO)) {
511 failCount1++;
512 System.err.println("fail2 x :"+x);
513 System.err.println(" y :"+y);
514 }
515
516 y = x.divideAndRemainder(z);
517 if (!y[0].equals(BigInteger.valueOf(2))) {
518 failCount1++;
519 System.err.println("fail3 x :"+x);
520 System.err.println(" y :"+y);
521 }
522 }
bpb28090952013-06-19 08:59:39 -0700523 report("divideAndRemainder for " + order + " bits", failCount1);
darcy32db4492009-01-26 19:49:26 -0800524 }
525
526 public static void stringConv() {
527 int failCount = 0;
528
bpb3c584672013-06-20 12:15:24 -0700529 // Generic string conversion.
darcy32db4492009-01-26 19:49:26 -0800530 for (int i=0; i<100; i++) {
531 byte xBytes[] = new byte[Math.abs(rnd.nextInt())%100+1];
532 rnd.nextBytes(xBytes);
533 BigInteger x = new BigInteger(xBytes);
534
bpb3c584672013-06-20 12:15:24 -0700535 for (int radix=Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {
darcy32db4492009-01-26 19:49:26 -0800536 String result = x.toString(radix);
537 BigInteger test = new BigInteger(result, radix);
538 if (!test.equals(x)) {
539 failCount++;
540 System.err.println("BigInteger toString: "+x);
541 System.err.println("Test: "+test);
542 System.err.println(radix);
543 }
544 }
545 }
bpb3c584672013-06-20 12:15:24 -0700546
547 // String conversion straddling the Schoenhage algorithm crossover
548 // threshold, and at twice and four times the threshold.
549 for (int k = 0; k <= 2; k++) {
550 int factor = 1 << k;
551 int upper = factor * BITS_SCHOENHAGE_BASE + 33;
552 int lower = upper - 35;
553
554 for (int bits = upper; bits >= lower; bits--) {
555 for (int i = 0; i < 50; i++) {
556 BigInteger x = BigInteger.ONE.shiftLeft(bits - 1).or(new BigInteger(bits - 2, rnd));
557
558 for (int radix = Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {
559 String result = x.toString(radix);
560 BigInteger test = new BigInteger(result, radix);
561 if (!test.equals(x)) {
562 failCount++;
563 System.err.println("BigInteger toString: " + x);
564 System.err.println("Test: " + test);
565 System.err.println(radix);
566 }
567 }
568 }
569 }
570 }
571
darcy32db4492009-01-26 19:49:26 -0800572 report("String Conversion", failCount);
573 }
574
bpb28090952013-06-19 08:59:39 -0700575 public static void byteArrayConv(int order) {
darcy32db4492009-01-26 19:49:26 -0800576 int failCount = 0;
577
bpb4e3b9202013-07-26 17:03:19 -0700578 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700579 BigInteger x = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -0800580 while (x.equals(BigInteger.ZERO))
bpb28090952013-06-19 08:59:39 -0700581 x = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -0800582 BigInteger y = new BigInteger(x.toByteArray());
583 if (!x.equals(y)) {
584 failCount++;
585 System.err.println("orig is "+x);
586 System.err.println("new is "+y);
587 }
588 }
bpb28090952013-06-19 08:59:39 -0700589 report("Array Conversion for " + order + " bits", failCount);
darcy32db4492009-01-26 19:49:26 -0800590 }
591
bpb28090952013-06-19 08:59:39 -0700592 public static void modInv(int order) {
darcy32db4492009-01-26 19:49:26 -0800593 int failCount = 0, successCount = 0, nonInvCount = 0;
594
bpb4e3b9202013-07-26 17:03:19 -0700595 for (int i=0; i<SIZE; i++) {
bpb28090952013-06-19 08:59:39 -0700596 BigInteger x = fetchNumber(order);
darcy32db4492009-01-26 19:49:26 -0800597 while(x.equals(BigInteger.ZERO))
bpb28090952013-06-19 08:59:39 -0700598 x = fetchNumber(order);
599 BigInteger m = fetchNumber(order).abs();
darcy32db4492009-01-26 19:49:26 -0800600 while(m.compareTo(BigInteger.ONE) != 1)
bpb28090952013-06-19 08:59:39 -0700601 m = fetchNumber(order).abs();
darcy32db4492009-01-26 19:49:26 -0800602
603 try {
604 BigInteger inv = x.modInverse(m);
605 BigInteger prod = inv.multiply(x).remainder(m);
606
607 if (prod.signum() == -1)
608 prod = prod.add(m);
609
610 if (prod.equals(BigInteger.ONE))
611 successCount++;
612 else
613 failCount++;
614 } catch(ArithmeticException e) {
615 nonInvCount++;
616 }
617 }
bpb28090952013-06-19 08:59:39 -0700618 report("Modular Inverse for " + order + " bits", failCount);
darcy32db4492009-01-26 19:49:26 -0800619 }
620
bpb28090952013-06-19 08:59:39 -0700621 public static void modExp(int order1, int order2) {
darcy32db4492009-01-26 19:49:26 -0800622 int failCount = 0;
623
bpb4e3b9202013-07-26 17:03:19 -0700624 for (int i=0; i<SIZE/10; i++) {
darcy32db4492009-01-26 19:49:26 -0800625 BigInteger m = fetchNumber(order1).abs();
626 while(m.compareTo(BigInteger.ONE) != 1)
627 m = fetchNumber(order1).abs();
628 BigInteger base = fetchNumber(order2);
629 BigInteger exp = fetchNumber(8).abs();
630
631 BigInteger z = base.modPow(exp, m);
632 BigInteger w = base.pow(exp.intValue()).mod(m);
633 if (!z.equals(w)) {
634 System.err.println("z is "+z);
635 System.err.println("w is "+w);
636 System.err.println("mod is "+m);
637 System.err.println("base is "+base);
638 System.err.println("exp is "+exp);
639 failCount++;
640 }
641 }
bpb28090952013-06-19 08:59:39 -0700642 report("Exponentiation I for " + order1 + " and " +
643 order2 + " bits", failCount);
darcy32db4492009-01-26 19:49:26 -0800644 }
645
646 // This test is based on Fermat's theorem
647 // which is not ideal because base must not be multiple of modulus
648 // and modulus must be a prime or pseudoprime (Carmichael number)
bpb28090952013-06-19 08:59:39 -0700649 public static void modExp2(int order) {
darcy32db4492009-01-26 19:49:26 -0800650 int failCount = 0;
651
652 for (int i=0; i<10; i++) {
653 BigInteger m = new BigInteger(100, 5, rnd);
654 while(m.compareTo(BigInteger.ONE) != 1)
655 m = new BigInteger(100, 5, rnd);
656 BigInteger exp = m.subtract(BigInteger.ONE);
bpb28090952013-06-19 08:59:39 -0700657 BigInteger base = fetchNumber(order).abs();
darcy32db4492009-01-26 19:49:26 -0800658 while(base.compareTo(m) != -1)
bpb28090952013-06-19 08:59:39 -0700659 base = fetchNumber(order).abs();
darcy32db4492009-01-26 19:49:26 -0800660 while(base.equals(BigInteger.ZERO))
bpb28090952013-06-19 08:59:39 -0700661 base = fetchNumber(order).abs();
darcy32db4492009-01-26 19:49:26 -0800662
663 BigInteger one = base.modPow(exp, m);
664 if (!one.equals(BigInteger.ONE)) {
665 System.err.println("m is "+m);
666 System.err.println("base is "+base);
667 System.err.println("exp is "+exp);
668 failCount++;
669 }
670 }
bpb28090952013-06-19 08:59:39 -0700671 report("Exponentiation II for " + order + " bits", failCount);
darcy32db4492009-01-26 19:49:26 -0800672 }
673
674 private static final int[] mersenne_powers = {
675 521, 607, 1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213, 19937,
676 21701, 23209, 44497, 86243, 110503, 132049, 216091, 756839, 859433,
677 1257787, 1398269, 2976221, 3021377, 6972593, 13466917 };
678
679 private static final long[] carmichaels = {
680 561,1105,1729,2465,2821,6601,8911,10585,15841,29341,41041,46657,52633,
681 62745,63973,75361,101101,115921,126217,162401,172081,188461,252601,
682 278545,294409,314821,334153,340561,399001,410041,449065,488881,512461,
683 225593397919L };
684
685 // Note: testing the larger ones takes too long.
686 private static final int NUM_MERSENNES_TO_TEST = 7;
687 // Note: this constant used for computed Carmichaels, not the array above
688 private static final int NUM_CARMICHAELS_TO_TEST = 5;
689
690 private static final String[] customer_primes = {
691 "120000000000000000000000000000000019",
692 "633825300114114700748351603131",
693 "1461501637330902918203684832716283019651637554291",
694 "779626057591079617852292862756047675913380626199",
695 "857591696176672809403750477631580323575362410491",
696 "910409242326391377348778281801166102059139832131",
697 "929857869954035706722619989283358182285540127919",
698 "961301750640481375785983980066592002055764391999",
699 "1267617700951005189537696547196156120148404630231",
700 "1326015641149969955786344600146607663033642528339" };
701
702 private static final BigInteger ZERO = BigInteger.ZERO;
703 private static final BigInteger ONE = BigInteger.ONE;
704 private static final BigInteger TWO = new BigInteger("2");
705 private static final BigInteger SIX = new BigInteger("6");
706 private static final BigInteger TWELVE = new BigInteger("12");
707 private static final BigInteger EIGHTEEN = new BigInteger("18");
708
709 public static void prime() {
710 BigInteger p1, p2, c1;
711 int failCount = 0;
712
713 // Test consistency
714 for(int i=0; i<10; i++) {
715 p1 = BigInteger.probablePrime(100, rnd);
716 if (!p1.isProbablePrime(100)) {
717 System.err.println("Consistency "+p1.toString(16));
718 failCount++;
719 }
720 }
721
722 // Test some known Mersenne primes (2^n)-1
723 // The array holds the exponents, not the numbers being tested
724 for (int i=0; i<NUM_MERSENNES_TO_TEST; i++) {
725 p1 = new BigInteger("2");
726 p1 = p1.pow(mersenne_powers[i]);
727 p1 = p1.subtract(BigInteger.ONE);
728 if (!p1.isProbablePrime(100)) {
729 System.err.println("Mersenne prime "+i+ " failed.");
730 failCount++;
731 }
732 }
733
734 // Test some primes reported by customers as failing in the past
735 for (int i=0; i<customer_primes.length; i++) {
736 p1 = new BigInteger(customer_primes[i]);
737 if (!p1.isProbablePrime(100)) {
738 System.err.println("Customer prime "+i+ " failed.");
739 failCount++;
740 }
741 }
742
743 // Test some known Carmichael numbers.
744 for (int i=0; i<carmichaels.length; i++) {
745 c1 = BigInteger.valueOf(carmichaels[i]);
746 if(c1.isProbablePrime(100)) {
747 System.err.println("Carmichael "+i+ " reported as prime.");
748 failCount++;
749 }
750 }
751
752 // Test some computed Carmichael numbers.
753 // Numbers of the form (6k+1)(12k+1)(18k+1) are Carmichael numbers if
754 // each of the factors is prime
755 int found = 0;
756 BigInteger f1 = new BigInteger(40, 100, rnd);
757 while (found < NUM_CARMICHAELS_TO_TEST) {
758 BigInteger k = null;
759 BigInteger f2, f3;
760 f1 = f1.nextProbablePrime();
761 BigInteger[] result = f1.subtract(ONE).divideAndRemainder(SIX);
762 if (result[1].equals(ZERO)) {
763 k = result[0];
764 f2 = k.multiply(TWELVE).add(ONE);
765 if (f2.isProbablePrime(100)) {
766 f3 = k.multiply(EIGHTEEN).add(ONE);
767 if (f3.isProbablePrime(100)) {
768 c1 = f1.multiply(f2).multiply(f3);
769 if (c1.isProbablePrime(100)) {
770 System.err.println("Computed Carmichael "
771 +c1.toString(16));
772 failCount++;
773 }
774 found++;
775 }
776 }
777 }
778 f1 = f1.add(TWO);
779 }
780
781 // Test some composites that are products of 2 primes
782 for (int i=0; i<50; i++) {
783 p1 = BigInteger.probablePrime(100, rnd);
784 p2 = BigInteger.probablePrime(100, rnd);
785 c1 = p1.multiply(p2);
786 if (c1.isProbablePrime(100)) {
787 System.err.println("Composite failed "+c1.toString(16));
788 failCount++;
789 }
790 }
791
792 for (int i=0; i<4; i++) {
793 p1 = BigInteger.probablePrime(600, rnd);
794 p2 = BigInteger.probablePrime(600, rnd);
795 c1 = p1.multiply(p2);
796 if (c1.isProbablePrime(100)) {
797 System.err.println("Composite failed "+c1.toString(16));
798 failCount++;
799 }
800 }
801
802 report("Prime", failCount);
803 }
804
805 private static final long[] primesTo100 = {
806 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97
807 };
808
809 private static final long[] aPrimeSequence = {
810 1999999003L, 1999999013L, 1999999049L, 1999999061L, 1999999081L,
811 1999999087L, 1999999093L, 1999999097L, 1999999117L, 1999999121L,
812 1999999151L, 1999999171L, 1999999207L, 1999999219L, 1999999271L,
813 1999999321L, 1999999373L, 1999999423L, 1999999439L, 1999999499L,
814 1999999553L, 1999999559L, 1999999571L, 1999999609L, 1999999613L,
815 1999999621L, 1999999643L, 1999999649L, 1999999657L, 1999999747L,
816 1999999763L, 1999999777L, 1999999811L, 1999999817L, 1999999829L,
817 1999999853L, 1999999861L, 1999999871L, 1999999873
818 };
819
820 public static void nextProbablePrime() throws Exception {
821 int failCount = 0;
822 BigInteger p1, p2, p3;
823 p1 = p2 = p3 = ZERO;
824
825 // First test nextProbablePrime on the low range starting at zero
826 for (int i=0; i<primesTo100.length; i++) {
827 p1 = p1.nextProbablePrime();
828 if (p1.longValue() != primesTo100[i]) {
829 System.err.println("low range primes failed");
830 System.err.println("p1 is "+p1);
831 System.err.println("expected "+primesTo100[i]);
832 failCount++;
833 }
834 }
835
836 // Test nextProbablePrime on a relatively small, known prime sequence
837 p1 = BigInteger.valueOf(aPrimeSequence[0]);
838 for (int i=1; i<aPrimeSequence.length; i++) {
839 p1 = p1.nextProbablePrime();
840 if (p1.longValue() != aPrimeSequence[i]) {
841 System.err.println("prime sequence failed");
842 failCount++;
843 }
844 }
845
846 // Next, pick some large primes, use nextProbablePrime to find the
847 // next one, and make sure there are no primes in between
848 for (int i=0; i<100; i+=10) {
849 p1 = BigInteger.probablePrime(50 + i, rnd);
850 p2 = p1.add(ONE);
851 p3 = p1.nextProbablePrime();
852 while(p2.compareTo(p3) < 0) {
853 if (p2.isProbablePrime(100)){
854 System.err.println("nextProbablePrime failed");
855 System.err.println("along range "+p1.toString(16));
856 System.err.println("to "+p3.toString(16));
857 failCount++;
858 break;
859 }
860 p2 = p2.add(ONE);
861 }
862 }
863
864 report("nextProbablePrime", failCount);
865 }
866
867 public static void serialize() throws Exception {
868 int failCount = 0;
869
870 String bitPatterns[] = {
871 "ffffffff00000000ffffffff00000000ffffffff00000000",
872 "ffffffffffffffffffffffff000000000000000000000000",
873 "ffffffff0000000000000000000000000000000000000000",
874 "10000000ffffffffffffffffffffffffffffffffffffffff",
875 "100000000000000000000000000000000000000000000000",
876 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
877 "-ffffffff00000000ffffffff00000000ffffffff00000000",
878 "-ffffffffffffffffffffffff000000000000000000000000",
879 "-ffffffff0000000000000000000000000000000000000000",
880 "-10000000ffffffffffffffffffffffffffffffffffffffff",
881 "-100000000000000000000000000000000000000000000000",
882 "-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
883 };
884
885 for(int i = 0; i < bitPatterns.length; i++) {
886 BigInteger b1 = new BigInteger(bitPatterns[i], 16);
darcye5dbfef2009-12-22 21:48:19 -0800887 BigInteger b2 = null;
darcy32db4492009-01-26 19:49:26 -0800888
889 File f = new File("serialtest");
smarks1dba3592011-02-22 15:34:17 -0800890
891 try (FileOutputStream fos = new FileOutputStream(f)) {
892 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
darcye5dbfef2009-12-22 21:48:19 -0800893 oos.writeObject(b1);
894 oos.flush();
darcye5dbfef2009-12-22 21:48:19 -0800895 }
darcy32db4492009-01-26 19:49:26 -0800896
smarks1dba3592011-02-22 15:34:17 -0800897 try (FileInputStream fis = new FileInputStream(f);
898 ObjectInputStream ois = new ObjectInputStream(fis))
899 {
900 b2 = (BigInteger)ois.readObject();
darcye5dbfef2009-12-22 21:48:19 -0800901 }
902
903 if (!b1.equals(b2) ||
904 !b1.equals(b1.or(b2))) {
905 failCount++;
906 System.err.println("Serialized failed for hex " +
907 b1.toString(16));
908 }
darcy32db4492009-01-26 19:49:26 -0800909 }
910 f.delete();
911 }
912
913 for(int i=0; i<10; i++) {
914 BigInteger b1 = fetchNumber(rnd.nextInt(100));
darcye5dbfef2009-12-22 21:48:19 -0800915 BigInteger b2 = null;
darcy32db4492009-01-26 19:49:26 -0800916 File f = new File("serialtest");
smarks1dba3592011-02-22 15:34:17 -0800917 try (FileOutputStream fos = new FileOutputStream(f)) {
918 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
darcye5dbfef2009-12-22 21:48:19 -0800919 oos.writeObject(b1);
920 oos.flush();
darcye5dbfef2009-12-22 21:48:19 -0800921 }
922
smarks1dba3592011-02-22 15:34:17 -0800923 try (FileInputStream fis = new FileInputStream(f);
924 ObjectInputStream ois = new ObjectInputStream(fis))
925 {
926 b2 = (BigInteger)ois.readObject();
darcye5dbfef2009-12-22 21:48:19 -0800927 }
darcye5dbfef2009-12-22 21:48:19 -0800928 }
darcy32db4492009-01-26 19:49:26 -0800929
930 if (!b1.equals(b2) ||
931 !b1.equals(b1.or(b2)))
932 failCount++;
933 f.delete();
934 }
935
936 report("Serialize", failCount);
937 }
938
939 /**
940 * Main to interpret arguments and run several tests.
941 *
bpb4e3b9202013-07-26 17:03:19 -0700942 * Up to three arguments may be given to specify the SIZE of BigIntegers
943 * used for call parameters 1, 2, and 3. The SIZE is interpreted as
darcy32db4492009-01-26 19:49:26 -0800944 * the maximum number of decimal digits that the parameters will have.
945 *
946 */
947 public static void main(String[] args) throws Exception {
948
bpb28090952013-06-19 08:59:39 -0700949 // Some variables for sizing test numbers in bits
950 int order1 = ORDER_MEDIUM;
951 int order2 = ORDER_SMALL;
952 int order3 = ORDER_KARATSUBA;
953 int order4 = ORDER_TOOM_COOK;
954
darcy32db4492009-01-26 19:49:26 -0800955 if (args.length >0)
956 order1 = (int)((Integer.parseInt(args[0]))* 3.333);
957 if (args.length >1)
958 order2 = (int)((Integer.parseInt(args[1]))* 3.333);
959 if (args.length >2)
960 order3 = (int)((Integer.parseInt(args[2]))* 3.333);
bpb28090952013-06-19 08:59:39 -0700961 if (args.length >3)
962 order4 = (int)((Integer.parseInt(args[3]))* 3.333);
darcy32db4492009-01-26 19:49:26 -0800963
964 prime();
965 nextProbablePrime();
966
bpb28090952013-06-19 08:59:39 -0700967 arithmetic(order1); // small numbers
bpbc2dd2732013-08-12 16:21:10 -0700968 arithmetic(order3); // Karatsuba range
969 arithmetic(order4); // Toom-Cook / Burnikel-Ziegler range
bpb28090952013-06-19 08:59:39 -0700970
971 divideAndRemainder(order1); // small numbers
bpbc2dd2732013-08-12 16:21:10 -0700972 divideAndRemainder(order3); // Karatsuba range
973 divideAndRemainder(order4); // Toom-Cook / Burnikel-Ziegler range
bpb28090952013-06-19 08:59:39 -0700974
975 pow(order1);
976 pow(order3);
977 pow(order4);
978
979 square(ORDER_MEDIUM);
980 square(ORDER_KARATSUBA_SQUARE);
981 square(ORDER_TOOM_COOK_SQUARE);
darcy32db4492009-01-26 19:49:26 -0800982
983 bitCount();
984 bitLength();
bpb28090952013-06-19 08:59:39 -0700985 bitOps(order1);
986 bitwise(order1);
darcy32db4492009-01-26 19:49:26 -0800987
bpb28090952013-06-19 08:59:39 -0700988 shift(order1);
darcy32db4492009-01-26 19:49:26 -0800989
bpb28090952013-06-19 08:59:39 -0700990 byteArrayConv(order1);
darcy32db4492009-01-26 19:49:26 -0800991
bpb28090952013-06-19 08:59:39 -0700992 modInv(order1); // small numbers
bpbc2dd2732013-08-12 16:21:10 -0700993 modInv(order3); // Karatsuba range
994 modInv(order4); // Toom-Cook / Burnikel-Ziegler range
bpb28090952013-06-19 08:59:39 -0700995
996 modExp(order1, order2);
997 modExp2(order1);
darcy32db4492009-01-26 19:49:26 -0800998
999 stringConv();
1000 serialize();
1001
bpb28090952013-06-19 08:59:39 -07001002 multiplyLarge();
1003 squareLarge();
bpb4e3b9202013-07-26 17:03:19 -07001004 divideLarge();
bpb28090952013-06-19 08:59:39 -07001005
darcy32db4492009-01-26 19:49:26 -08001006 if (failure)
1007 throw new RuntimeException("Failure in BigIntegerTest.");
1008 }
1009
1010 /*
1011 * Get a random or boundary-case number. This is designed to provide
bpb4a9dee72013-07-26 17:09:30 -07001012 * a lot of numbers that will find failure points, such as max sized
darcy32db4492009-01-26 19:49:26 -08001013 * numbers, empty BigIntegers, etc.
1014 *
1015 * If order is less than 2, order is changed to 2.
1016 */
1017 private static BigInteger fetchNumber(int order) {
1018 boolean negative = rnd.nextBoolean();
bpb28090952013-06-19 08:59:39 -07001019 int numType = rnd.nextInt(7);
darcy32db4492009-01-26 19:49:26 -08001020 BigInteger result = null;
1021 if (order < 2) order = 2;
1022
1023 switch (numType) {
1024 case 0: // Empty
1025 result = BigInteger.ZERO;
1026 break;
1027
1028 case 1: // One
1029 result = BigInteger.ONE;
1030 break;
1031
1032 case 2: // All bits set in number
1033 int numBytes = (order+7)/8;
1034 byte[] fullBits = new byte[numBytes];
1035 for(int i=0; i<numBytes; i++)
1036 fullBits[i] = (byte)0xff;
1037 int excessBits = 8*numBytes - order;
1038 fullBits[0] &= (1 << (8-excessBits)) - 1;
1039 result = new BigInteger(1, fullBits);
1040 break;
1041
1042 case 3: // One bit in number
1043 result = BigInteger.ONE.shiftLeft(rnd.nextInt(order));
1044 break;
1045
1046 case 4: // Random bit density
bpb4e3b9202013-07-26 17:03:19 -07001047 byte[] val = new byte[(order+7)/8];
1048 int iterations = rnd.nextInt(order);
1049 for (int i=0; i<iterations; i++) {
1050 int bitIdx = rnd.nextInt(order);
1051 val[bitIdx/8] |= 1 << (bitIdx%8);
darcy32db4492009-01-26 19:49:26 -08001052 }
bpb4e3b9202013-07-26 17:03:19 -07001053 result = new BigInteger(1, val);
darcy32db4492009-01-26 19:49:26 -08001054 break;
bpb28090952013-06-19 08:59:39 -07001055 case 5: // Runs of consecutive ones and zeros
1056 result = ZERO;
1057 int remaining = order;
1058 int bit = rnd.nextInt(2);
1059 while (remaining > 0) {
1060 int runLength = Math.min(remaining, rnd.nextInt(order));
1061 result = result.shiftLeft(runLength);
1062 if (bit > 0)
1063 result = result.add(ONE.shiftLeft(runLength).subtract(ONE));
1064 remaining -= runLength;
1065 bit = 1 - bit;
1066 }
1067 break;
darcy32db4492009-01-26 19:49:26 -08001068
1069 default: // random bits
1070 result = new BigInteger(order, rnd);
1071 }
1072
1073 if (negative)
1074 result = result.negate();
1075
1076 return result;
1077 }
1078
1079 static void report(String testName, int failCount) {
1080 System.err.println(testName+": " +
1081 (failCount==0 ? "Passed":"Failed("+failCount+")"));
1082 if (failCount > 0)
1083 failure = true;
1084 }
1085}