1 /*
   2  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * 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  *
  19  * 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.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 4181191 4161971 4227146 4194389 4823171 4624738 4812225 4837946 4026465
  27  * @summary tests methods in BigInteger
  28  * @run main/timeout=400 BigIntegerTest
  29  * @author madbot
  30  */
  31 
  32 import java.io.File;
  33 import java.io.FileInputStream;
  34 import java.io.FileOutputStream;
  35 import java.io.ObjectInputStream;
  36 import java.io.ObjectOutputStream;
  37 import java.math.BigInteger;
  38 import java.util.Random;
  39 
  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  *
  46  * Four arguments may be specified which give the number of
  47  * decimal digits you desire in the four batches of test numbers.
  48  *
  49  * The tests are performed on arrays of random numbers which are
  50  * generated by a Random class as well as special cases which
  51  * throw in boundary numbers such as 0, 1, maximum sized, etc.
  52  *
  53  */
  54 public class BigIntegerTest {
  55     //
  56     // Bit large number thresholds based on the int thresholds
  57     // defined in BigInteger itself:
  58     //
  59     // 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
  63     //
  64     // SCHOENHAGE_BASE_CONVERSION_THRESHOLD = 20 ints = 640 bits
  65     //
  66     // BURNIKEL_ZIEGLER_THRESHOLD = 80  ints = 2560 bits
  67     //
  68     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;
  74     static final int BITS_BURNIKEL_ZIEGLER_OFFSET = 1280;
  75 
  76     static final int ORDER_SMALL = 60;
  77     static final int ORDER_MEDIUM = 100;
  78     // #bits for testing Karatsuba
  79     static final int ORDER_KARATSUBA = 2760;
  80     // #bits for testing Toom-Cook and Burnikel-Ziegler
  81     static final int ORDER_TOOM_COOK = 8000;
  82     // #bits for testing Karatsuba squaring
  83     static final int ORDER_KARATSUBA_SQUARE = 4200;
  84     // #bits for testing Toom-Cook squaring
  85     static final int ORDER_TOOM_COOK_SQUARE = 7000;
  86 
  87     static final int SIZE = 1000; // numbers per batch
  88 
  89     static Random rnd = new Random();
  90     static boolean failure = false;
  91 
  92     public static void constructor() {
  93         int failCount = 0;
  94 
  95         byte[] magZeroLength = new byte[0];
  96         for (int signum = -1; signum <= 1; signum++) {
  97             BigInteger bi = new BigInteger(signum, magZeroLength);
  98             if (bi.compareTo(BigInteger.ZERO) != 0) {
  99                 System.err.println("A: Zero length BigInteger != 0 for signum " + signum);
 100                 failCount++;
 101             }
 102         }
 103 
 104         for (int signum = -1; signum <= 1; signum++) {
 105             BigInteger bi = new BigInteger(signum, magZeroLength, 0, 0);
 106             if (bi.compareTo(BigInteger.ZERO) != 0) {
 107                 System.err.println("B: Zero length BigInteger != 0 for signum " + signum);
 108                 failCount++;
 109             }
 110         }
 111 
 112         byte[] magNonZeroLength = new byte[42];
 113         rnd.nextBytes(magNonZeroLength);
 114         for (int signum = -1; signum <= 1; signum++) {
 115             BigInteger bi = new BigInteger(signum, magNonZeroLength, 0, 0);
 116             if (bi.compareTo(BigInteger.ZERO) != 0) {
 117                 System.err.println("C: Zero length BigInteger != 0 for signum " + signum);
 118                 failCount++;
 119             }
 120         }
 121 
 122         for (int i = 0; i < SIZE; i++) {
 123             BigInteger reference = new BigInteger(rnd.nextInt(5000), rnd);
 124 
 125             byte[] refArray = reference.toByteArray();
 126             int refLen = refArray.length;
 127             int factor = rnd.nextInt(5);
 128             int objLen = refArray.length + factor*rnd.nextInt(refArray.length) + 1;
 129             int offset = rnd.nextInt(objLen - refLen);
 130             byte[] objArray = new byte[objLen];
 131             System.arraycopy(refArray, 0, objArray, offset, refLen);
 132 
 133             BigInteger twosComp = new BigInteger(objArray, offset, refLen);
 134             if (twosComp.compareTo(reference) != 0) {
 135                 System.err.println("Two's-complement BigInteger not equal for offset " +
 136                         offset + " and length " + refLen);
 137                 failCount++;
 138             }
 139 
 140             boolean isNegative = rnd.nextBoolean();
 141             BigInteger signMag = new BigInteger(isNegative ? -1 : 1, objArray, offset, refLen);
 142             if (signMag.compareTo(isNegative ? reference.negate() : reference) != 0) {
 143                 System.err.println("Sign-magnitude BigInteger not equal for offset " +
 144                         offset + " and length " + refLen);
 145                 failCount++;
 146             }
 147         }
 148 
 149         report("Constructor", failCount);
 150     }
 151 
 152     public static void pow(int order) {
 153         int failCount1 = 0;
 154 
 155         for (int i=0; i<SIZE; i++) {
 156             // Test identity x^power == x*x*x ... *x
 157             int power = rnd.nextInt(6) + 2;
 158             BigInteger x = fetchNumber(order);
 159             BigInteger y = x.pow(power);
 160             BigInteger z = x;
 161 
 162             for (int j=1; j<power; j++)
 163                 z = z.multiply(x);
 164 
 165             if (!y.equals(z))
 166                 failCount1++;
 167         }
 168         report("pow for " + order + " bits", failCount1);
 169     }
 170 
 171     public static void square(int order) {
 172         int failCount1 = 0;
 173 
 174         for (int i=0; i<SIZE; i++) {
 175             // Test identity x^2 == x*x
 176             BigInteger x  = fetchNumber(order);
 177             BigInteger xx = x.multiply(x);
 178             BigInteger x2 = x.pow(2);
 179 
 180             if (!x2.equals(xx))
 181                 failCount1++;
 182         }
 183         report("square for " + order + " bits", failCount1);
 184     }
 185 
 186     public static void arithmetic(int order) {
 187         int failCount = 0;
 188 
 189         for (int i=0; i<SIZE; i++) {
 190             BigInteger x = fetchNumber(order);
 191             while(x.compareTo(BigInteger.ZERO) != 1)
 192                 x = fetchNumber(order);
 193             BigInteger y = fetchNumber(order/2);
 194             while(x.compareTo(y) == -1)
 195                 y = fetchNumber(order/2);
 196             if (y.equals(BigInteger.ZERO))
 197                 y = y.add(BigInteger.ONE);
 198 
 199             // Test identity ((x/y))*y + x%y - x == 0
 200             // using separate divide() and remainder()
 201             BigInteger baz = x.divide(y);
 202             baz = baz.multiply(y);
 203             baz = baz.add(x.remainder(y));
 204             baz = baz.subtract(x);
 205             if (!baz.equals(BigInteger.ZERO))
 206                 failCount++;
 207         }
 208         report("Arithmetic I for " + order + " bits", failCount);
 209 
 210         failCount = 0;
 211         for (int i=0; i<100; i++) {
 212             BigInteger x = fetchNumber(order);
 213             while(x.compareTo(BigInteger.ZERO) != 1)
 214                 x = fetchNumber(order);
 215             BigInteger y = fetchNumber(order/2);
 216             while(x.compareTo(y) == -1)
 217                 y = fetchNumber(order/2);
 218             if (y.equals(BigInteger.ZERO))
 219                 y = y.add(BigInteger.ONE);
 220 
 221             // Test identity ((x/y))*y + x%y - x == 0
 222             // using divideAndRemainder()
 223             BigInteger baz[] = x.divideAndRemainder(y);
 224             baz[0] = baz[0].multiply(y);
 225             baz[0] = baz[0].add(baz[1]);
 226             baz[0] = baz[0].subtract(x);
 227             if (!baz[0].equals(BigInteger.ZERO))
 228                 failCount++;
 229         }
 230         report("Arithmetic II for " + order + " bits", failCount);
 231     }
 232 
 233     /**
 234      * Sanity test for Karatsuba and 3-way Toom-Cook multiplication.
 235      * For each of the Karatsuba and 3-way Toom-Cook multiplication thresholds,
 236      * construct two factors each with a mag array one element shorter than the
 237      * threshold, and with the most significant bit set and the rest of the bits
 238      * random. Each of these numbers will therefore be below the threshold but
 239      * if shifted left be above the threshold. Call the numbers 'u' and 'v' and
 240      * define random shifts 'a' and 'b' in the range [1,32]. Then we have the
 241      * identity
 242      * <pre>
 243      * (u << a)*(v << b) = (u*v) << (a + b)
 244      * </pre>
 245      * For Karatsuba multiplication, the right hand expression will be evaluated
 246      * using the standard naive algorithm, and the left hand expression using
 247      * the Karatsuba algorithm. For 3-way Toom-Cook multiplication, the right
 248      * hand expression will be evaluated using Karatsuba multiplication, and the
 249      * left hand expression using 3-way Toom-Cook multiplication.
 250      */
 251     public static void multiplyLarge() {
 252         int failCount = 0;
 253 
 254         BigInteger base = BigInteger.ONE.shiftLeft(BITS_KARATSUBA - 32 - 1);
 255         for (int i=0; i<SIZE; i++) {
 256             BigInteger x = fetchNumber(BITS_KARATSUBA - 32 - 1);
 257             BigInteger u = base.add(x);
 258             int a = 1 + rnd.nextInt(31);
 259             BigInteger w = u.shiftLeft(a);
 260 
 261             BigInteger y = fetchNumber(BITS_KARATSUBA - 32 - 1);
 262             BigInteger v = base.add(y);
 263             int b = 1 + rnd.nextInt(32);
 264             BigInteger z = v.shiftLeft(b);
 265 
 266             BigInteger multiplyResult = u.multiply(v).shiftLeft(a + b);
 267             BigInteger karatsubaMultiplyResult = w.multiply(z);
 268 
 269             if (!multiplyResult.equals(karatsubaMultiplyResult)) {
 270                 failCount++;
 271             }
 272         }
 273 
 274         report("multiplyLarge Karatsuba", failCount);
 275 
 276         failCount = 0;
 277         base = base.shiftLeft(BITS_TOOM_COOK - BITS_KARATSUBA);
 278         for (int i=0; i<SIZE; i++) {
 279             BigInteger x = fetchNumber(BITS_TOOM_COOK - 32 - 1);
 280             BigInteger u = base.add(x);
 281             BigInteger u2 = u.shiftLeft(1);
 282             BigInteger y = fetchNumber(BITS_TOOM_COOK - 32 - 1);
 283             BigInteger v = base.add(y);
 284             BigInteger v2 = v.shiftLeft(1);
 285 
 286             BigInteger multiplyResult = u.multiply(v).shiftLeft(2);
 287             BigInteger toomCookMultiplyResult = u2.multiply(v2);
 288 
 289             if (!multiplyResult.equals(toomCookMultiplyResult)) {
 290                 failCount++;
 291             }
 292         }
 293 
 294         report("multiplyLarge Toom-Cook", failCount);
 295     }
 296 
 297     /**
 298      * Sanity test for Karatsuba and 3-way Toom-Cook squaring.
 299      * This test is analogous to {@link AbstractMethodError#multiplyLarge}
 300      * with both factors being equal. The squaring methods will not be tested
 301      * unless the <code>bigInteger.multiply(bigInteger)</code> tests whether
 302      * the parameter is the same instance on which the method is being invoked
 303      * and calls <code>square()</code> accordingly.
 304      */
 305     public static void squareLarge() {
 306         int failCount = 0;
 307 
 308         BigInteger base = BigInteger.ONE.shiftLeft(BITS_KARATSUBA_SQUARE - 32 - 1);
 309         for (int i=0; i<SIZE; i++) {
 310             BigInteger x = fetchNumber(BITS_KARATSUBA_SQUARE - 32 - 1);
 311             BigInteger u = base.add(x);
 312             int a = 1 + rnd.nextInt(31);
 313             BigInteger w = u.shiftLeft(a);
 314 
 315             BigInteger squareResult = u.multiply(u).shiftLeft(2*a);
 316             BigInteger karatsubaSquareResult = w.multiply(w);
 317 
 318             if (!squareResult.equals(karatsubaSquareResult)) {
 319                 failCount++;
 320             }
 321         }
 322 
 323         report("squareLarge Karatsuba", failCount);
 324 
 325         failCount = 0;
 326         base = base.shiftLeft(BITS_TOOM_COOK_SQUARE - BITS_KARATSUBA_SQUARE);
 327         for (int i=0; i<SIZE; i++) {
 328             BigInteger x = fetchNumber(BITS_TOOM_COOK_SQUARE - 32 - 1);
 329             BigInteger u = base.add(x);
 330             int a = 1 + rnd.nextInt(31);
 331             BigInteger w = u.shiftLeft(a);
 332 
 333             BigInteger squareResult = u.multiply(u).shiftLeft(2*a);
 334             BigInteger toomCookSquareResult = w.multiply(w);
 335 
 336             if (!squareResult.equals(toomCookSquareResult)) {
 337                 failCount++;
 338             }
 339         }
 340 
 341         report("squareLarge Toom-Cook", failCount);
 342     }
 343 
 344     /**
 345      * Sanity test for Burnikel-Ziegler division.  The Burnikel-Ziegler division
 346      * algorithm is used when each of the dividend and the divisor has at least
 347      * a specified number of ints in its representation.  This test is based on
 348      * the observation that if {@code w = u*pow(2,a)} and {@code z = v*pow(2,b)}
 349      * where {@code abs(u) > abs(v)} and {@code a > b && b > 0}, then if
 350      * {@code w/z = q1*z + r1} and {@code u/v = q2*v + r2}, then
 351      * {@code q1 = q2*pow(2,a-b)} and {@code r1 = r2*pow(2,b)}.  The test
 352      * ensures that {@code v} is just under the B-Z threshold, that {@code z} is
 353      * over the threshold and {@code w} is much larger than {@code z}. This
 354      * implies that {@code u/v} uses the standard division algorithm and
 355      * {@code w/z} uses the B-Z algorithm.  The results of the two algorithms
 356      * are then compared using the observation described in the foregoing and
 357      * if they are not equal a failure is logged.
 358      */
 359     public static void divideLarge() {
 360         int failCount = 0;
 361 
 362         BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 33);
 363         for (int i=0; i<SIZE; i++) {
 364             BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 34, rnd);
 365             BigInteger v = base.add(addend);
 366 
 367             BigInteger u = v.multiply(BigInteger.valueOf(2 + rnd.nextInt(Short.MAX_VALUE - 1)));
 368 
 369             if(rnd.nextBoolean()) {
 370                 u = u.negate();
 371             }
 372             if(rnd.nextBoolean()) {
 373                 v = v.negate();
 374             }
 375 
 376             int a = BITS_BURNIKEL_ZIEGLER_OFFSET + rnd.nextInt(16);
 377             int b = 1 + rnd.nextInt(16);
 378             BigInteger w = u.multiply(BigInteger.ONE.shiftLeft(a));
 379             BigInteger z = v.multiply(BigInteger.ONE.shiftLeft(b));
 380 
 381             BigInteger[] divideResult = u.divideAndRemainder(v);
 382             divideResult[0] = divideResult[0].multiply(BigInteger.ONE.shiftLeft(a - b));
 383             divideResult[1] = divideResult[1].multiply(BigInteger.ONE.shiftLeft(b));
 384             BigInteger[] bzResult = w.divideAndRemainder(z);
 385 
 386             if (divideResult[0].compareTo(bzResult[0]) != 0 ||
 387                     divideResult[1].compareTo(bzResult[1]) != 0) {
 388                 failCount++;
 389             }
 390         }
 391 
 392         report("divideLarge", failCount);
 393     }
 394 
 395     public static void bitCount() {
 396         int failCount = 0;
 397 
 398         for (int i=0; i<SIZE*10; i++) {
 399             int x = rnd.nextInt();
 400             BigInteger bigX = BigInteger.valueOf((long)x);
 401             int bit = (x < 0 ? 0 : 1);
 402             int tmp = x, bitCount = 0;
 403             for (int j=0; j<32; j++) {
 404                 bitCount += ((tmp & 1) == bit ? 1 : 0);
 405                 tmp >>= 1;
 406             }
 407 
 408             if (bigX.bitCount() != bitCount) {
 409                 //System.err.println(x+": "+bitCount+", "+bigX.bitCount());
 410                 failCount++;
 411             }
 412         }
 413         report("Bit Count", failCount);
 414     }
 415 
 416     public static void bitLength() {
 417         int failCount = 0;
 418 
 419         for (int i=0; i<SIZE*10; i++) {
 420             int x = rnd.nextInt();
 421             BigInteger bigX = BigInteger.valueOf((long)x);
 422             int signBit = (x < 0 ? 0x80000000 : 0);
 423             int tmp = x, bitLength, j;
 424             for (j=0; j<32 && (tmp & 0x80000000)==signBit; j++)
 425                 tmp <<= 1;
 426             bitLength = 32 - j;
 427 
 428             if (bigX.bitLength() != bitLength) {
 429                 //System.err.println(x+": "+bitLength+", "+bigX.bitLength());
 430                 failCount++;
 431             }
 432         }
 433 
 434         report("BitLength", failCount);
 435     }
 436 
 437     public static void bitOps(int order) {
 438         int failCount1 = 0, failCount2 = 0, failCount3 = 0;
 439 
 440         for (int i=0; i<SIZE*5; i++) {
 441             BigInteger x = fetchNumber(order);
 442             BigInteger y;
 443 
 444             // Test setBit and clearBit (and testBit)
 445             if (x.signum() < 0) {
 446                 y = BigInteger.valueOf(-1);
 447                 for (int j=0; j<x.bitLength(); j++)
 448                     if (!x.testBit(j))
 449                         y = y.clearBit(j);
 450             } else {
 451                 y = BigInteger.ZERO;
 452                 for (int j=0; j<x.bitLength(); j++)
 453                     if (x.testBit(j))
 454                         y = y.setBit(j);
 455             }
 456             if (!x.equals(y))
 457                 failCount1++;
 458 
 459             // Test flipBit (and testBit)
 460             y = BigInteger.valueOf(x.signum()<0 ? -1 : 0);
 461             for (int j=0; j<x.bitLength(); j++)
 462                 if (x.signum()<0  ^  x.testBit(j))
 463                     y = y.flipBit(j);
 464             if (!x.equals(y))
 465                 failCount2++;
 466         }
 467         report("clearBit/testBit for " + order + " bits", failCount1);
 468         report("flipBit/testBit for " + order + " bits", failCount2);
 469 
 470         for (int i=0; i<SIZE*5; i++) {
 471             BigInteger x = fetchNumber(order);
 472 
 473             // Test getLowestSetBit()
 474             int k = x.getLowestSetBit();
 475             if (x.signum() == 0) {
 476                 if (k != -1)
 477                     failCount3++;
 478             } else {
 479                 BigInteger z = x.and(x.negate());
 480                 int j;
 481                 for (j=0; j<z.bitLength() && !z.testBit(j); j++)
 482                     ;
 483                 if (k != j)
 484                     failCount3++;
 485             }
 486         }
 487         report("getLowestSetBit for " + order + " bits", failCount3);
 488     }
 489 
 490     public static void bitwise(int order) {
 491 
 492         // Test identity x^y == x|y &~ x&y
 493         int failCount = 0;
 494         for (int i=0; i<SIZE; i++) {
 495             BigInteger x = fetchNumber(order);
 496             BigInteger y = fetchNumber(order);
 497             BigInteger z = x.xor(y);
 498             BigInteger w = x.or(y).andNot(x.and(y));
 499             if (!z.equals(w))
 500                 failCount++;
 501         }
 502         report("Logic (^ | & ~) for " + order + " bits", failCount);
 503 
 504         // Test identity x &~ y == ~(~x | y)
 505         failCount = 0;
 506         for (int i=0; i<SIZE; i++) {
 507             BigInteger x = fetchNumber(order);
 508             BigInteger y = fetchNumber(order);
 509             BigInteger z = x.andNot(y);
 510             BigInteger w = x.not().or(y).not();
 511             if (!z.equals(w))
 512                 failCount++;
 513         }
 514         report("Logic (&~ | ~) for " + order + " bits", failCount);
 515     }
 516 
 517     public static void shift(int order) {
 518         int failCount1 = 0;
 519         int failCount2 = 0;
 520         int failCount3 = 0;
 521 
 522         for (int i=0; i<100; i++) {
 523             BigInteger x = fetchNumber(order);
 524             int n = Math.abs(rnd.nextInt()%200);
 525 
 526             if (!x.shiftLeft(n).equals
 527                 (x.multiply(BigInteger.valueOf(2L).pow(n))))
 528                 failCount1++;
 529 
 530             BigInteger y[] =x.divideAndRemainder(BigInteger.valueOf(2L).pow(n));
 531             BigInteger z = (x.signum()<0 && y[1].signum()!=0
 532                             ? y[0].subtract(BigInteger.ONE)
 533                             : y[0]);
 534 
 535             BigInteger b = x.shiftRight(n);
 536 
 537             if (!b.equals(z)) {
 538                 System.err.println("Input is "+x.toString(2));
 539                 System.err.println("shift is "+n);
 540 
 541                 System.err.println("Divided "+z.toString(2));
 542                 System.err.println("Shifted is "+b.toString(2));
 543                 if (b.toString().equals(z.toString()))
 544                     System.err.println("Houston, we have a problem.");
 545                 failCount2++;
 546             }
 547 
 548             if (!x.shiftLeft(n).shiftRight(n).equals(x))
 549                 failCount3++;
 550         }
 551         report("baz shiftLeft for " + order + " bits", failCount1);
 552         report("baz shiftRight for " + order + " bits", failCount2);
 553         report("baz shiftLeft/Right for " + order + " bits", failCount3);
 554     }
 555 
 556     public static void divideAndRemainder(int order) {
 557         int failCount1 = 0;
 558 
 559         for (int i=0; i<SIZE; i++) {
 560             BigInteger x = fetchNumber(order).abs();
 561             while(x.compareTo(BigInteger.valueOf(3L)) != 1)
 562                 x = fetchNumber(order).abs();
 563             BigInteger z = x.divide(BigInteger.valueOf(2L));
 564             BigInteger y[] = x.divideAndRemainder(x);
 565             if (!y[0].equals(BigInteger.ONE)) {
 566                 failCount1++;
 567                 System.err.println("fail1 x :"+x);
 568                 System.err.println("      y :"+y);
 569             }
 570             else if (!y[1].equals(BigInteger.ZERO)) {
 571                 failCount1++;
 572                 System.err.println("fail2 x :"+x);
 573                 System.err.println("      y :"+y);
 574             }
 575 
 576             y = x.divideAndRemainder(z);
 577             if (!y[0].equals(BigInteger.valueOf(2))) {
 578                 failCount1++;
 579                 System.err.println("fail3 x :"+x);
 580                 System.err.println("      y :"+y);
 581             }
 582         }
 583         report("divideAndRemainder for " + order + " bits", failCount1);
 584     }
 585 
 586     public static void stringConv() {
 587         int failCount = 0;
 588 
 589         // Generic string conversion.
 590         for (int i=0; i<100; i++) {
 591             byte xBytes[] = new byte[Math.abs(rnd.nextInt())%100+1];
 592             rnd.nextBytes(xBytes);
 593             BigInteger x = new BigInteger(xBytes);
 594 
 595             for (int radix=Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {
 596                 String result = x.toString(radix);
 597                 BigInteger test = new BigInteger(result, radix);
 598                 if (!test.equals(x)) {
 599                     failCount++;
 600                     System.err.println("BigInteger toString: "+x);
 601                     System.err.println("Test: "+test);
 602                     System.err.println(radix);
 603                 }
 604             }
 605         }
 606 
 607         // String conversion straddling the Schoenhage algorithm crossover
 608         // threshold, and at twice and four times the threshold.
 609         for (int k = 0; k <= 2; k++) {
 610             int factor = 1 << k;
 611             int upper = factor * BITS_SCHOENHAGE_BASE + 33;
 612             int lower = upper - 35;
 613 
 614             for (int bits = upper; bits >= lower; bits--) {
 615                 for (int i = 0; i < 50; i++) {
 616                     BigInteger x = BigInteger.ONE.shiftLeft(bits - 1).or(new BigInteger(bits - 2, rnd));
 617 
 618                     for (int radix = Character.MIN_RADIX; radix < Character.MAX_RADIX; radix++) {
 619                         String result = x.toString(radix);
 620                         BigInteger test = new BigInteger(result, radix);
 621                         if (!test.equals(x)) {
 622                             failCount++;
 623                             System.err.println("BigInteger toString: " + x);
 624                             System.err.println("Test: " + test);
 625                             System.err.println(radix);
 626                         }
 627                     }
 628                 }
 629             }
 630         }
 631 
 632         report("String Conversion", failCount);
 633     }
 634 
 635     public static void byteArrayConv(int order) {
 636         int failCount = 0;
 637 
 638         for (int i=0; i<SIZE; i++) {
 639             BigInteger x = fetchNumber(order);
 640             while (x.equals(BigInteger.ZERO))
 641                 x = fetchNumber(order);
 642             BigInteger y = new BigInteger(x.toByteArray());
 643             if (!x.equals(y)) {
 644                 failCount++;
 645                 System.err.println("orig is "+x);
 646                 System.err.println("new is "+y);
 647             }
 648         }
 649         report("Array Conversion for " + order + " bits", failCount);
 650     }
 651 
 652     public static void modInv(int order) {
 653         int failCount = 0, successCount = 0, nonInvCount = 0;
 654 
 655         for (int i=0; i<SIZE; i++) {
 656             BigInteger x = fetchNumber(order);
 657             while(x.equals(BigInteger.ZERO))
 658                 x = fetchNumber(order);
 659             BigInteger m = fetchNumber(order).abs();
 660             while(m.compareTo(BigInteger.ONE) != 1)
 661                 m = fetchNumber(order).abs();
 662 
 663             try {
 664                 BigInteger inv = x.modInverse(m);
 665                 BigInteger prod = inv.multiply(x).remainder(m);
 666 
 667                 if (prod.signum() == -1)
 668                     prod = prod.add(m);
 669 
 670                 if (prod.equals(BigInteger.ONE))
 671                     successCount++;
 672                 else
 673                     failCount++;
 674             } catch(ArithmeticException e) {
 675                 nonInvCount++;
 676             }
 677         }
 678         report("Modular Inverse for " + order + " bits", failCount);
 679     }
 680 
 681     public static void modExp(int order1, int order2) {
 682         int failCount = 0;
 683 
 684         for (int i=0; i<SIZE/10; i++) {
 685             BigInteger m = fetchNumber(order1).abs();
 686             while(m.compareTo(BigInteger.ONE) != 1)
 687                 m = fetchNumber(order1).abs();
 688             BigInteger base = fetchNumber(order2);
 689             BigInteger exp = fetchNumber(8).abs();
 690 
 691             BigInteger z = base.modPow(exp, m);
 692             BigInteger w = base.pow(exp.intValue()).mod(m);
 693             if (!z.equals(w)) {
 694                 System.err.println("z is "+z);
 695                 System.err.println("w is "+w);
 696                 System.err.println("mod is "+m);
 697                 System.err.println("base is "+base);
 698                 System.err.println("exp is "+exp);
 699                 failCount++;
 700             }
 701         }
 702         report("Exponentiation I for " + order1 + " and " +
 703                order2 + " bits", failCount);
 704     }
 705 
 706     // This test is based on Fermat's theorem
 707     // which is not ideal because base must not be multiple of modulus
 708     // and modulus must be a prime or pseudoprime (Carmichael number)
 709     public static void modExp2(int order) {
 710         int failCount = 0;
 711 
 712         for (int i=0; i<10; i++) {
 713             BigInteger m = new BigInteger(100, 5, rnd);
 714             while(m.compareTo(BigInteger.ONE) != 1)
 715                 m = new BigInteger(100, 5, rnd);
 716             BigInteger exp = m.subtract(BigInteger.ONE);
 717             BigInteger base = fetchNumber(order).abs();
 718             while(base.compareTo(m) != -1)
 719                 base = fetchNumber(order).abs();
 720             while(base.equals(BigInteger.ZERO))
 721                 base = fetchNumber(order).abs();
 722 
 723             BigInteger one = base.modPow(exp, m);
 724             if (!one.equals(BigInteger.ONE)) {
 725                 System.err.println("m is "+m);
 726                 System.err.println("base is "+base);
 727                 System.err.println("exp is "+exp);
 728                 failCount++;
 729             }
 730         }
 731         report("Exponentiation II for " + order + " bits", failCount);
 732     }
 733 
 734     private static final int[] mersenne_powers = {
 735         521, 607, 1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941, 11213, 19937,
 736         21701, 23209, 44497, 86243, 110503, 132049, 216091, 756839, 859433,
 737         1257787, 1398269, 2976221, 3021377, 6972593, 13466917 };
 738 
 739     private static final long[] carmichaels = {
 740       561,1105,1729,2465,2821,6601,8911,10585,15841,29341,41041,46657,52633,
 741       62745,63973,75361,101101,115921,126217,162401,172081,188461,252601,
 742       278545,294409,314821,334153,340561,399001,410041,449065,488881,512461,
 743       225593397919L };
 744 
 745     // Note: testing the larger ones takes too long.
 746     private static final int NUM_MERSENNES_TO_TEST = 7;
 747     // Note: this constant used for computed Carmichaels, not the array above
 748     private static final int NUM_CARMICHAELS_TO_TEST = 5;
 749 
 750     private static final String[] customer_primes = {
 751         "120000000000000000000000000000000019",
 752         "633825300114114700748351603131",
 753         "1461501637330902918203684832716283019651637554291",
 754         "779626057591079617852292862756047675913380626199",
 755         "857591696176672809403750477631580323575362410491",
 756         "910409242326391377348778281801166102059139832131",
 757         "929857869954035706722619989283358182285540127919",
 758         "961301750640481375785983980066592002055764391999",
 759         "1267617700951005189537696547196156120148404630231",
 760         "1326015641149969955786344600146607663033642528339" };
 761 
 762     private static final BigInteger ZERO = BigInteger.ZERO;
 763     private static final BigInteger ONE = BigInteger.ONE;
 764     private static final BigInteger TWO = new BigInteger("2");
 765     private static final BigInteger SIX = new BigInteger("6");
 766     private static final BigInteger TWELVE = new BigInteger("12");
 767     private static final BigInteger EIGHTEEN = new BigInteger("18");
 768 
 769     public static void prime() {
 770         BigInteger p1, p2, c1;
 771         int failCount = 0;
 772 
 773         // Test consistency
 774         for(int i=0; i<10; i++) {
 775             p1 = BigInteger.probablePrime(100, rnd);
 776             if (!p1.isProbablePrime(100)) {
 777                 System.err.println("Consistency "+p1.toString(16));
 778                 failCount++;
 779             }
 780         }
 781 
 782         // Test some known Mersenne primes (2^n)-1
 783         // The array holds the exponents, not the numbers being tested
 784         for (int i=0; i<NUM_MERSENNES_TO_TEST; i++) {
 785             p1 = new BigInteger("2");
 786             p1 = p1.pow(mersenne_powers[i]);
 787             p1 = p1.subtract(BigInteger.ONE);
 788             if (!p1.isProbablePrime(100)) {
 789                 System.err.println("Mersenne prime "+i+ " failed.");
 790                 failCount++;
 791             }
 792         }
 793 
 794         // Test some primes reported by customers as failing in the past
 795         for (int i=0; i<customer_primes.length; i++) {
 796             p1 = new BigInteger(customer_primes[i]);
 797             if (!p1.isProbablePrime(100)) {
 798                 System.err.println("Customer prime "+i+ " failed.");
 799                 failCount++;
 800             }
 801         }
 802 
 803         // Test some known Carmichael numbers.
 804         for (int i=0; i<carmichaels.length; i++) {
 805             c1 = BigInteger.valueOf(carmichaels[i]);
 806             if(c1.isProbablePrime(100)) {
 807                 System.err.println("Carmichael "+i+ " reported as prime.");
 808                 failCount++;
 809             }
 810         }
 811 
 812         // Test some computed Carmichael numbers.
 813         // Numbers of the form (6k+1)(12k+1)(18k+1) are Carmichael numbers if
 814         // each of the factors is prime
 815         int found = 0;
 816         BigInteger f1 = new BigInteger(40, 100, rnd);
 817         while (found < NUM_CARMICHAELS_TO_TEST) {
 818             BigInteger k = null;
 819             BigInteger f2, f3;
 820             f1 = f1.nextProbablePrime();
 821             BigInteger[] result = f1.subtract(ONE).divideAndRemainder(SIX);
 822             if (result[1].equals(ZERO)) {
 823                 k = result[0];
 824                 f2 = k.multiply(TWELVE).add(ONE);
 825                 if (f2.isProbablePrime(100)) {
 826                     f3 = k.multiply(EIGHTEEN).add(ONE);
 827                     if (f3.isProbablePrime(100)) {
 828                         c1 = f1.multiply(f2).multiply(f3);
 829                         if (c1.isProbablePrime(100)) {
 830                             System.err.println("Computed Carmichael "
 831                                                +c1.toString(16));
 832                             failCount++;
 833                         }
 834                         found++;
 835                     }
 836                 }
 837             }
 838             f1 = f1.add(TWO);
 839         }
 840 
 841         // Test some composites that are products of 2 primes
 842         for (int i=0; i<50; i++) {
 843             p1 = BigInteger.probablePrime(100, rnd);
 844             p2 = BigInteger.probablePrime(100, rnd);
 845             c1 = p1.multiply(p2);
 846             if (c1.isProbablePrime(100)) {
 847                 System.err.println("Composite failed "+c1.toString(16));
 848                 failCount++;
 849             }
 850         }
 851 
 852         for (int i=0; i<4; i++) {
 853             p1 = BigInteger.probablePrime(600, rnd);
 854             p2 = BigInteger.probablePrime(600, rnd);
 855             c1 = p1.multiply(p2);
 856             if (c1.isProbablePrime(100)) {
 857                 System.err.println("Composite failed "+c1.toString(16));
 858                 failCount++;
 859             }
 860         }
 861 
 862         report("Prime", failCount);
 863     }
 864 
 865     private static final long[] primesTo100 = {
 866         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
 867     };
 868 
 869     private static final long[] aPrimeSequence = {
 870         1999999003L, 1999999013L, 1999999049L, 1999999061L, 1999999081L,
 871         1999999087L, 1999999093L, 1999999097L, 1999999117L, 1999999121L,
 872         1999999151L, 1999999171L, 1999999207L, 1999999219L, 1999999271L,
 873         1999999321L, 1999999373L, 1999999423L, 1999999439L, 1999999499L,
 874         1999999553L, 1999999559L, 1999999571L, 1999999609L, 1999999613L,
 875         1999999621L, 1999999643L, 1999999649L, 1999999657L, 1999999747L,
 876         1999999763L, 1999999777L, 1999999811L, 1999999817L, 1999999829L,
 877         1999999853L, 1999999861L, 1999999871L, 1999999873
 878     };
 879 
 880     public static void nextProbablePrime() throws Exception {
 881         int failCount = 0;
 882         BigInteger p1, p2, p3;
 883         p1 = p2 = p3 = ZERO;
 884 
 885         // First test nextProbablePrime on the low range starting at zero
 886         for (int i=0; i<primesTo100.length; i++) {
 887             p1 = p1.nextProbablePrime();
 888             if (p1.longValue() != primesTo100[i]) {
 889                 System.err.println("low range primes failed");
 890                 System.err.println("p1 is "+p1);
 891                 System.err.println("expected "+primesTo100[i]);
 892                 failCount++;
 893             }
 894         }
 895 
 896         // Test nextProbablePrime on a relatively small, known prime sequence
 897         p1 = BigInteger.valueOf(aPrimeSequence[0]);
 898         for (int i=1; i<aPrimeSequence.length; i++) {
 899             p1 = p1.nextProbablePrime();
 900             if (p1.longValue() != aPrimeSequence[i]) {
 901                 System.err.println("prime sequence failed");
 902                 failCount++;
 903             }
 904         }
 905 
 906         // Next, pick some large primes, use nextProbablePrime to find the
 907         // next one, and make sure there are no primes in between
 908         for (int i=0; i<100; i+=10) {
 909             p1 = BigInteger.probablePrime(50 + i, rnd);
 910             p2 = p1.add(ONE);
 911             p3 = p1.nextProbablePrime();
 912             while(p2.compareTo(p3) < 0) {
 913                 if (p2.isProbablePrime(100)){
 914                     System.err.println("nextProbablePrime failed");
 915                     System.err.println("along range "+p1.toString(16));
 916                     System.err.println("to "+p3.toString(16));
 917                     failCount++;
 918                     break;
 919                 }
 920                 p2 = p2.add(ONE);
 921             }
 922         }
 923 
 924         report("nextProbablePrime", failCount);
 925     }
 926 
 927     public static void serialize() throws Exception {
 928         int failCount = 0;
 929 
 930         String bitPatterns[] = {
 931              "ffffffff00000000ffffffff00000000ffffffff00000000",
 932              "ffffffffffffffffffffffff000000000000000000000000",
 933              "ffffffff0000000000000000000000000000000000000000",
 934              "10000000ffffffffffffffffffffffffffffffffffffffff",
 935              "100000000000000000000000000000000000000000000000",
 936              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
 937             "-ffffffff00000000ffffffff00000000ffffffff00000000",
 938             "-ffffffffffffffffffffffff000000000000000000000000",
 939             "-ffffffff0000000000000000000000000000000000000000",
 940             "-10000000ffffffffffffffffffffffffffffffffffffffff",
 941             "-100000000000000000000000000000000000000000000000",
 942             "-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 943         };
 944 
 945         for(int i = 0; i < bitPatterns.length; i++) {
 946             BigInteger b1 = new BigInteger(bitPatterns[i], 16);
 947             BigInteger b2 = null;
 948 
 949             File f = new File("serialtest");
 950 
 951             try (FileOutputStream fos = new FileOutputStream(f)) {
 952                 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
 953                     oos.writeObject(b1);
 954                     oos.flush();
 955                 }
 956 
 957                 try (FileInputStream fis = new FileInputStream(f);
 958                      ObjectInputStream ois = new ObjectInputStream(fis))
 959                 {
 960                     b2 = (BigInteger)ois.readObject();
 961                 }
 962 
 963                 if (!b1.equals(b2) ||
 964                     !b1.equals(b1.or(b2))) {
 965                     failCount++;
 966                     System.err.println("Serialized failed for hex " +
 967                                        b1.toString(16));
 968                 }
 969             }
 970             f.delete();
 971         }
 972 
 973         for(int i=0; i<10; i++) {
 974             BigInteger b1 = fetchNumber(rnd.nextInt(100));
 975             BigInteger b2 = null;
 976             File f = new File("serialtest");
 977             try (FileOutputStream fos = new FileOutputStream(f)) {
 978                 try (ObjectOutputStream oos = new ObjectOutputStream(fos)) {
 979                     oos.writeObject(b1);
 980                     oos.flush();
 981                 }
 982 
 983                 try (FileInputStream fis = new FileInputStream(f);
 984                      ObjectInputStream ois = new ObjectInputStream(fis))
 985                 {
 986                     b2 = (BigInteger)ois.readObject();
 987                 }
 988             }
 989 
 990             if (!b1.equals(b2) ||
 991                 !b1.equals(b1.or(b2)))
 992                 failCount++;
 993             f.delete();
 994         }
 995 
 996         report("Serialize", failCount);
 997     }
 998 
 999     /**
1000      * Main to interpret arguments and run several tests.
1001      *
1002      * Up to three arguments may be given to specify the SIZE of BigIntegers
1003      * used for call parameters 1, 2, and 3. The SIZE is interpreted as
1004      * the maximum number of decimal digits that the parameters will have.
1005      *
1006      */
1007     public static void main(String[] args) throws Exception {
1008 
1009         // Some variables for sizing test numbers in bits
1010         int order1 = ORDER_MEDIUM;
1011         int order2 = ORDER_SMALL;
1012         int order3 = ORDER_KARATSUBA;
1013         int order4 = ORDER_TOOM_COOK;
1014 
1015         if (args.length >0)
1016             order1 = (int)((Integer.parseInt(args[0]))* 3.333);
1017         if (args.length >1)
1018             order2 = (int)((Integer.parseInt(args[1]))* 3.333);
1019         if (args.length >2)
1020             order3 = (int)((Integer.parseInt(args[2]))* 3.333);
1021         if (args.length >3)
1022             order4 = (int)((Integer.parseInt(args[3]))* 3.333);
1023 
1024         constructor();
1025 
1026         prime();
1027         nextProbablePrime();
1028 
1029         arithmetic(order1);   // small numbers
1030         arithmetic(order3);   // Karatsuba range
1031         arithmetic(order4);   // Toom-Cook / Burnikel-Ziegler range
1032 
1033         divideAndRemainder(order1);   // small numbers
1034         divideAndRemainder(order3);   // Karatsuba range
1035         divideAndRemainder(order4);   // Toom-Cook / Burnikel-Ziegler range
1036 
1037         pow(order1);
1038         pow(order3);
1039         pow(order4);
1040 
1041         square(ORDER_MEDIUM);
1042         square(ORDER_KARATSUBA_SQUARE);
1043         square(ORDER_TOOM_COOK_SQUARE);
1044 
1045         bitCount();
1046         bitLength();
1047         bitOps(order1);
1048         bitwise(order1);
1049 
1050         shift(order1);
1051 
1052         byteArrayConv(order1);
1053 
1054         modInv(order1);   // small numbers
1055         modInv(order3);   // Karatsuba range
1056         modInv(order4);   // Toom-Cook / Burnikel-Ziegler range
1057 
1058         modExp(order1, order2);
1059         modExp2(order1);
1060 
1061         stringConv();
1062         serialize();
1063 
1064         multiplyLarge();
1065         squareLarge();
1066         divideLarge();
1067 
1068         if (failure)
1069             throw new RuntimeException("Failure in BigIntegerTest.");
1070     }
1071 
1072     /*
1073      * Get a random or boundary-case number. This is designed to provide
1074      * a lot of numbers that will find failure points, such as max sized
1075      * numbers, empty BigIntegers, etc.
1076      *
1077      * If order is less than 2, order is changed to 2.
1078      */
1079     private static BigInteger fetchNumber(int order) {
1080         boolean negative = rnd.nextBoolean();
1081         int numType = rnd.nextInt(7);
1082         BigInteger result = null;
1083         if (order < 2) order = 2;
1084 
1085         switch (numType) {
1086             case 0: // Empty
1087                 result = BigInteger.ZERO;
1088                 break;
1089 
1090             case 1: // One
1091                 result = BigInteger.ONE;
1092                 break;
1093 
1094             case 2: // All bits set in number
1095                 int numBytes = (order+7)/8;
1096                 byte[] fullBits = new byte[numBytes];
1097                 for(int i=0; i<numBytes; i++)
1098                     fullBits[i] = (byte)0xff;
1099                 int excessBits = 8*numBytes - order;
1100                 fullBits[0] &= (1 << (8-excessBits)) - 1;
1101                 result = new BigInteger(1, fullBits);
1102                 break;
1103 
1104             case 3: // One bit in number
1105                 result = BigInteger.ONE.shiftLeft(rnd.nextInt(order));
1106                 break;
1107 
1108             case 4: // Random bit density
1109                 byte[] val = new byte[(order+7)/8];
1110                 int iterations = rnd.nextInt(order);
1111                 for (int i=0; i<iterations; i++) {
1112                     int bitIdx = rnd.nextInt(order);
1113                     val[bitIdx/8] |= 1 << (bitIdx%8);
1114                 }
1115                 result = new BigInteger(1, val);
1116                 break;
1117             case 5: // Runs of consecutive ones and zeros
1118                 result = ZERO;
1119                 int remaining = order;
1120                 int bit = rnd.nextInt(2);
1121                 while (remaining > 0) {
1122                     int runLength = Math.min(remaining, rnd.nextInt(order));
1123                     result = result.shiftLeft(runLength);
1124                     if (bit > 0)
1125                         result = result.add(ONE.shiftLeft(runLength).subtract(ONE));
1126                     remaining -= runLength;
1127                     bit = 1 - bit;
1128                 }
1129                 break;
1130 
1131             default: // random bits
1132                 result = new BigInteger(order, rnd);
1133         }
1134 
1135         if (negative)
1136             result = result.negate();
1137 
1138         return result;
1139     }
1140 
1141     static void report(String testName, int failCount) {
1142         System.err.println(testName+": " +
1143                            (failCount==0 ? "Passed":"Failed("+failCount+")"));
1144         if (failCount > 0)
1145             failure = true;
1146     }
1147 }