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