Exemple #1
0
  public void initialize() {
    e = BigInteger.valueOf(65537);
    SecureRandom sr = new SecureRandom();

    BigInteger diff = BigInteger.valueOf(2).pow(256);

    /*
    generate 2 prime numbers greater than 512 bits and that have difference of 2^256
    */
    do {
      sr.generateSeed(size);
      p = new BigInteger(size, 256, sr);
      sr.generateSeed(size);
      q = new BigInteger(size, 256, sr);

    } while (p.bitLength() < size
        || q.bitLength() < size
        || !p.isProbablePrime(256)
        || !q.isProbablePrime(256)
        || p.subtract(q).abs().compareTo(diff) != 1);

    n = p.multiply(q);
    phi_n = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
    d = e.modInverse(phi_n);
  }
Exemple #2
0
  public static void setPrimes(BigInteger limit) {
    primes.add(TWO);

    for (BigInteger i = THREE; i.compareTo(limit) == -1; i = i.add(TWO)) {
      if (i.isProbablePrime(50)) primes.add(i);
    }
  }
  public static void main(String[] args) {

    // prikaz maksimalnog longa
    System.out.println("The maximum number is long:\n" + Long.MAX_VALUE);
    // pretvaramo ga u string
    String max = Long.MAX_VALUE + "";
    // definisemo da nam broj krece od maksimalnog long broja plus 1
    BigInteger big1 = new BigInteger(max).add(new BigInteger("1"));
    // definisemo brojac
    int counter = 0;
    System.out.println("The first 5 primes larger than the maximum long: ");
    // petlja radi dok je brojac ne bude 5
    while (counter != 5) {
      // objasnjenje metoda nalazi se kada ukucate big1. izbaci vam se
      // meni zatim tab da se zaustavite na prvom polju i u desnom prozoru
      // kliknete na BigInteger tu su i sve metode o bigInteger
      if (big1.isProbablePrime(7)) {
        System.out.println(big1);
        // povecaj brojac
        counter++;
      }
      // povecaj big broj za 1
      big1 = big1.add(new BigInteger("1"));
    }
  }
 public Mpk getCertificate(String pseudo, BigInteger APrime, ECPoint h) {
   // Randomly choose primes e and e' like
   Boolean search = true;
   BigInteger ePrime;
   BigInteger e;
   do {
     ePrime = new BigInteger(Constants.KePrime, Constants.certainty, new Random());
     // System.out.println(ePrime);
     e = ePrime.add(Constants.expKe);
     // System.out.println(e);
     if (e.isProbablePrime(Constants.certainty)) {
       search = false;
     }
   } while (search);
   System.out.println("I: e' = " + ePrime);
   // Compute A
   BigInteger A = this.computeA(APrime, e);
   System.out.println("I: A = " + A);
   BigInteger B = this.getRevocationManager().computeB(ePrime);
   Mpk mpk = new Mpk(A, ePrime, B, h);
   this.setNbUsers(this.getNbUsers() + 1);
   this.getMembersList().put(pseudo, mpk);
   System.out.println(
       "I: Protocol OK => Add to list:\n\tIndex = "
           + this.getNbUsers()
           + "\tPseudo = "
           + pseudo
           + "\t(A, e', B, h)");
   return mpk;
 }
  boolean isPrime(int n) {
    // System.out.println("Inside prime " + n);

    if (n == 2) {
      return true;
    }

    if ((n % 2) == 0) {
      return false;
    }

    BigInteger bigInteger = BigInteger.valueOf(n);
    if (bigInteger.isProbablePrime(8)) {
      int x = (int) Math.sqrt(n);
      for (int i = 2; i <= x; ++i) {
        if ((n % i) == 0) {

          return false;
        }
      }

      return true;
    }

    return false;
  }
 private boolean isPrime(int p) {
   if (p < n) {
     return primes.contains(p);
   } else {
     BigInteger bg = new BigInteger(String.valueOf(p));
     return bg.isProbablePrime(10);
   }
 }
Exemple #7
0
 public static void factor(BigInteger N) {
   if (N.compareTo(ONE) == 0) return;
   if (N.isProbablePrime(20)) {
     factors[prlen++] = N;
     return;
   }
   BigInteger divisor = rho(N);
   factor(divisor);
   factor(N.divide(divisor));
 }
  /*
    See IEEE P1363 A.15.5 (10/05/98 Draft)
  */
  public static BigInteger generateRandomPrime(
      BigInteger r, BigInteger a, int pmin, int pmax, BigInteger f) {
    BigInteger d, w;

    // Step 1 - generate prime
    BigInteger p = new BigInteger((pmax + pmin) / 2, new Random());

    steptwo:
    { // Step 2
      w = p.mod(r.multiply(BigInteger.valueOf(2)));

      // Step 3
      p = p.add(r.multiply(BigInteger.valueOf(2)));
      p = p.subtract(w);
      p = p.add(a);

      // Step 4 - test for even
      if (p.mod(BigInteger.valueOf(2)).compareTo(BigInteger.valueOf(0)) == 0) p = p.add(r);

      for (; ; ) {
        // Step 5
        if (p.compareTo(BigInteger.valueOf(1).shiftLeft(pmax)) > 0) {
          // Step 5.1
          p = p.subtract(BigInteger.valueOf(1).shiftLeft(pmax));
          p = p.add(BigInteger.valueOf(1).shiftLeft(pmin));
          p = p.subtract(BigInteger.valueOf(1));

          // Step 5.2 - goto to Step 2
          break steptwo;
        }

        // Step 6
        d = p.subtract(BigInteger.valueOf(1));
        d = d.gcd(f);

        // Step 7 - test d
        if (d.compareTo(BigInteger.valueOf(1)) == 0) {
          // Step 7.1 - test primality
          if (p.isProbablePrime(1) == true) {
            // Step 7.2;
            return p;
          }
        }
        // Step 8
        p = p.add(r.multiply(BigInteger.valueOf(2)));

        // Step 9
      }
    }
    // Should never reach here but makes the compiler happy
    return BigInteger.valueOf(0);
  }
Exemple #9
0
 private static void factor(BigInteger N) {
   if (N.compareTo(ONE) == 0) return;
   if (N.isProbablePrime(5)) {
     Integer p = mp.remove(N);
     if (p == null) p = new Integer(0);
     p = (Integer) (p.intValue() + 1);
     mp.put(N, p);
     return;
   }
   BigInteger divisor = rho(N);
   factor(divisor);
   factor(N.divide(divisor));
 }
 static void largePrimesProduct(BigInteger a, BigInteger b, String c) {
   BigInteger wp = a.multiply(b);
   assertFalse(
       "isProbablePrime failed for product of two large primes" + a + " * " + b + " = " + c,
       wp.isProbablePrime(80));
   BigInteger wpMinusOne = wp.subtract(BigInteger.ONE);
   BigInteger next = wpMinusOne.nextProbablePrime();
   //        System.out.println(c);
   //        System.out.println(next);
   assertTrue(
       "nextProbablePrime returns wrong number: " + next + "instead of expected: " + c,
       next.toString().equals(c));
 }
Exemple #11
0
  public static void main(String[] args) {
    // Generics, varargs & boxing working together:
    List<Integer> li = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    Integer result = reduce(li, new IntegerAdder());
    print(result);

    result = reduce(li, new IntegerSubtracter());
    print(result);

    print(filter(li, new GreaterThan<Integer>(4)));

    print(forEach(li, new MultiplyingIntegerCollector()).result());

    print(
        forEach(filter(li, new GreaterThan<Integer>(4)), new MultiplyingIntegerCollector())
            .result());

    MathContext mc = new MathContext(7);
    List<BigDecimal> lbd =
        Arrays.asList(
            new BigDecimal(1.1, mc),
            new BigDecimal(2.2, mc),
            new BigDecimal(3.3, mc),
            new BigDecimal(4.4, mc));
    BigDecimal rbd = reduce(lbd, new BigDecimalAdder());
    print(rbd);

    print(filter(lbd, new GreaterThan<BigDecimal>(new BigDecimal(3))));

    // Use the prime-generation facility of BigInteger:
    List<BigInteger> lbi = new ArrayList<BigInteger>();
    BigInteger bi = BigInteger.valueOf(11);
    for (int i = 0; i < 11; i++) {
      lbi.add(bi);
      bi = bi.nextProbablePrime();
    }
    print(lbi);

    BigInteger rbi = reduce(lbi, new BigIntegerAdder());
    print(rbi);
    // The sum of this list of primes is also prime:
    print(rbi.isProbablePrime(5));

    List<AtomicLong> lal =
        Arrays.asList(
            new AtomicLong(11), new AtomicLong(47), new AtomicLong(74), new AtomicLong(133));
    AtomicLong ral = reduce(lal, new AtomicLongAdder());
    print(ral);

    print(transform(lbd, new BigDecimalUlp()));
  }
 /** @tests java.math.BigInteger#probablePrime(int, java.util.Random) */
 @TestTargetNew(
     level = TestLevel.COMPLETE,
     notes = "",
     method = "probablePrime",
     args = {int.class, java.util.Random.class})
 public void test_probablePrime() {
   for (int bitLength = 50; bitLength <= 1050; bitLength += 100) {
     BigInteger a = BigInteger.probablePrime(bitLength, rand);
     assertTrue("isProbablePrime(probablePrime()) failed for: " + bi, a.isProbablePrime(80));
     //            System.out.println(a);
     //            BigInteger prime = a.nextProbablePrime();
     //            System.out.print("Next Probable Prime is ");
     //            System.out.println(prime);
   }
 }
  /*
    See IEEE P1363 A.15.4 (10/05/98 Draft)
  */
  public static BigInteger generateRandomPrime(int pmin, int pmax, BigInteger f) {
    BigInteger d;

    // Step 1 - generate prime
    BigInteger p = new BigInteger((pmax + pmin) / 2, new Random());
    if (p.compareTo(BigInteger.valueOf(1).shiftLeft(pmin)) <= 0) {
      p = p.add(BigInteger.valueOf(1).shiftLeft(pmin).subtract(p));
    }

    // Step 2 - test for even
    if (p.mod(BigInteger.valueOf(2)).compareTo(BigInteger.valueOf(0)) == 0)
      p = p.add(BigInteger.valueOf(1));

    for (; ; ) {
      // Step 3
      if (p.compareTo(BigInteger.valueOf(1).shiftLeft(pmax)) > 0) {
        // Step 3.1
        p = p.subtract(BigInteger.valueOf(1).shiftLeft(pmax));
        p = p.add(BigInteger.valueOf(1).shiftLeft(pmin));
        p = p.subtract(BigInteger.valueOf(1));

        // Step 3.2
        // put step 2 code here so looping code is cleaner
        // Step 2 - test for even
        if (p.mod(BigInteger.valueOf(2)).compareTo(BigInteger.valueOf(0)) == 0)
          p = p.add(BigInteger.valueOf(1));
        continue;
      }

      // Step 4 - compute GCD
      d = p.subtract(BigInteger.valueOf(1));
      d = d.gcd(f);

      // Step 5 - test d
      if (d.compareTo(BigInteger.valueOf(1)) == 0) {
        // Step 5.1 - test primality
        if (p.isProbablePrime(1) == true) {
          // Step 5.2;
          return p;
        }
      }
      // Step 6
      p = p.add(BigInteger.valueOf(2));

      // Step 7
    }
  }
  public static void nextProbablePrime() throws Exception {
    int failCount = 0;
    BigInteger p1, p2, p3;
    p1 = p2 = p3 = ZERO;

    // First test nextProbablePrime on the low range starting at zero
    for (int i = 0; i < primesTo100.length; i++) {
      p1 = p1.nextProbablePrime();
      if (p1.longValue() != primesTo100[i]) {
        System.err.println("low range primes failed");
        System.err.println("p1 is " + p1);
        System.err.println("expected " + primesTo100[i]);
        failCount++;
      }
    }

    // Test nextProbablePrime on a relatively small, known prime sequence
    p1 = BigInteger.valueOf(aPrimeSequence[0]);
    for (int i = 1; i < aPrimeSequence.length; i++) {
      p1 = p1.nextProbablePrime();
      if (p1.longValue() != aPrimeSequence[i]) {
        System.err.println("prime sequence failed");
        failCount++;
      }
    }

    // Next, pick some large primes, use nextProbablePrime to find the
    // next one, and make sure there are no primes in between
    for (int i = 0; i < 100; i += 10) {
      p1 = BigInteger.probablePrime(50 + i, rnd);
      p2 = p1.add(ONE);
      p3 = p1.nextProbablePrime();
      while (p2.compareTo(p3) < 0) {
        if (p2.isProbablePrime(100)) {
          System.err.println("nextProbablePrime failed");
          System.err.println("along range " + p1.toString(16));
          System.err.println("to " + p3.toString(16));
          failCount++;
          break;
        }
        p2 = p2.add(ONE);
      }
    }

    report("nextProbablePrime", failCount);
  }
  /*
   * We note that we probably only need to iterate through O(J) coinjams until
   * we find enough, which should be doable in reasonable time given J < 500
   *
   * Uses Pollard rho factorization
   */
  public void solve() throws IOException {
    int T = nextInt();
    for (int t = 1; t <= T; t++) {
      int N = nextInt();
      int J = nextInt();

      out.format("Case #%d:%n", t);

      boolean[] bitmask = new boolean[N - 2];
      int count = 0;
      while (count < J) {
        BigInteger[] factors = new BigInteger[9];
        boolean success = true;
        for (int base = 2; base <= 10; base++) {
          BigInteger value = BigInteger.ONE;
          BigInteger biBase = BigInteger.valueOf(base);

          for (int i = 0; i < N - 2; i++) {
            if (bitmask[i]) {
              value = value.add(biBase.pow(i + 1));
            }
          }
          value = value.add(biBase.pow(N - 1));

          if (value.isProbablePrime(10)) {
            success = false;
            break;
          } else {
            // Pollard rho
            BigInteger x = BigInteger.valueOf(2);
            BigInteger y = BigInteger.valueOf(2);
            BigInteger d = BigInteger.ONE;
            while (d.compareTo(BigInteger.ONE) == 0) {
              x = x.pow(2).add(BigInteger.ONE).mod(value);
              y = y.pow(2).add(BigInteger.ONE).mod(value).pow(2).add(BigInteger.ONE).mod(value);
              d = x.subtract(y).gcd(value);
            }
            if (d.compareTo(value) != 0) {
              factors[base - 2] = d;
            } else {
              success = false;
              break;
            }
          }
        }
        if (success) {
          count++;
          StringBuilder sb = new StringBuilder("1");
          for (int i = N - 3; i >= 0; i--) {
            if (bitmask[i]) {
              sb.append(1);
            } else {
              sb.append(0);
            }
          }
          sb.append(1);

          System.out.println(sb.toString() + " " + count);
          out.print(sb.toString());
          for (int i = 0; i < 9; i++) {
            out.print(" ");
            out.print(factors[i].toString());
          }
          out.println();
        }

        // Increment bitmask
        for (int i = 0; i < N - 2; i++) {
          if (!bitmask[i]) {
            bitmask[i] = true;
            break;
          } else {
            bitmask[i] = false;
          }
        }
      }
    }
  }
Exemple #16
0
  public static boolean isGoodPrime(byte[] prime, int g) {
    if (!(g >= 2 && g <= 7)) {
      return false;
    }

    if (prime.length != 256 || prime[0] >= 0) {
      return false;
    }

    String hex = bytesToHex(prime);
    for (String cached : goodPrimes) {
      if (cached.equals(hex)) {
        return true;
      }
    }

    BigInteger dhBI = new BigInteger(1, prime);

    if (g == 2) { // p mod 8 = 7 for g = 2;
      BigInteger res = dhBI.mod(BigInteger.valueOf(8));
      if (res.intValue() != 7) {
        return false;
      }
    } else if (g == 3) { // p mod 3 = 2 for g = 3;
      BigInteger res = dhBI.mod(BigInteger.valueOf(3));
      if (res.intValue() != 2) {
        return false;
      }
    } else if (g == 5) { // p mod 5 = 1 or 4 for g = 5;
      BigInteger res = dhBI.mod(BigInteger.valueOf(5));
      int val = res.intValue();
      if (val != 1 && val != 4) {
        return false;
      }
    } else if (g == 6) { // p mod 24 = 19 or 23 for g = 6;
      BigInteger res = dhBI.mod(BigInteger.valueOf(24));
      int val = res.intValue();
      if (val != 19 && val != 23) {
        return false;
      }
    } else if (g == 7) { // p mod 7 = 3, 5 or 6 for g = 7.
      BigInteger res = dhBI.mod(BigInteger.valueOf(7));
      int val = res.intValue();
      if (val != 3 && val != 5 && val != 6) {
        return false;
      }
    }

    BigInteger dhBI2 = dhBI.subtract(BigInteger.valueOf(1)).divide(BigInteger.valueOf(2));
    if (!dhBI.isProbablePrime(30) || !dhBI2.isProbablePrime(30)) {
      return false;
    }

    goodPrimes.add(hex);

    globalQueue.postRunnable(
        new Runnable() {
          @Override
          public void run() {
            try {
              SerializedData data = new SerializedData();
              data.writeInt32(goodPrimes.size());
              for (String pr : goodPrimes) {
                data.writeString(pr);
              }
              byte[] bytes = data.toByteArray();
              SharedPreferences preferences =
                  ApplicationLoader.applicationContext.getSharedPreferences(
                      "primes", Context.MODE_PRIVATE);
              SharedPreferences.Editor editor = preferences.edit();
              editor.putString("primes", Base64.encodeToString(bytes, Base64.DEFAULT));
              editor.commit();
            } catch (Exception e) {
              FileLog.e("tmessages", e);
            }
          }
        });

    return true;
  }
  public static void prime() {
    BigInteger p1, p2, c1;
    int failCount = 0;

    // Test consistency
    for (int i = 0; i < 10; i++) {
      p1 = BigInteger.probablePrime(100, rnd);
      if (!p1.isProbablePrime(100)) {
        System.err.println("Consistency " + p1.toString(16));
        failCount++;
      }
    }

    // Test some known Mersenne primes (2^n)-1
    // The array holds the exponents, not the numbers being tested
    for (int i = 0; i < NUM_MERSENNES_TO_TEST; i++) {
      p1 = new BigInteger("2");
      p1 = p1.pow(mersenne_powers[i]);
      p1 = p1.subtract(BigInteger.ONE);
      if (!p1.isProbablePrime(100)) {
        System.err.println("Mersenne prime " + i + " failed.");
        failCount++;
      }
    }

    // Test some primes reported by customers as failing in the past
    for (int i = 0; i < customer_primes.length; i++) {
      p1 = new BigInteger(customer_primes[i]);
      if (!p1.isProbablePrime(100)) {
        System.err.println("Customer prime " + i + " failed.");
        failCount++;
      }
    }

    // Test some known Carmichael numbers.
    for (int i = 0; i < carmichaels.length; i++) {
      c1 = BigInteger.valueOf(carmichaels[i]);
      if (c1.isProbablePrime(100)) {
        System.err.println("Carmichael " + i + " reported as prime.");
        failCount++;
      }
    }

    // Test some computed Carmichael numbers.
    // Numbers of the form (6k+1)(12k+1)(18k+1) are Carmichael numbers if
    // each of the factors is prime
    int found = 0;
    BigInteger f1 = new BigInteger(40, 100, rnd);
    while (found < NUM_CARMICHAELS_TO_TEST) {
      BigInteger k = null;
      BigInteger f2, f3;
      f1 = f1.nextProbablePrime();
      BigInteger[] result = f1.subtract(ONE).divideAndRemainder(SIX);
      if (result[1].equals(ZERO)) {
        k = result[0];
        f2 = k.multiply(TWELVE).add(ONE);
        if (f2.isProbablePrime(100)) {
          f3 = k.multiply(EIGHTEEN).add(ONE);
          if (f3.isProbablePrime(100)) {
            c1 = f1.multiply(f2).multiply(f3);
            if (c1.isProbablePrime(100)) {
              System.err.println("Computed Carmichael " + c1.toString(16));
              failCount++;
            }
            found++;
          }
        }
      }
      f1 = f1.add(TWO);
    }

    // Test some composites that are products of 2 primes
    for (int i = 0; i < 50; i++) {
      p1 = BigInteger.probablePrime(100, rnd);
      p2 = BigInteger.probablePrime(100, rnd);
      c1 = p1.multiply(p2);
      if (c1.isProbablePrime(100)) {
        System.err.println("Composite failed " + c1.toString(16));
        failCount++;
      }
    }

    for (int i = 0; i < 4; i++) {
      p1 = BigInteger.probablePrime(600, rnd);
      p2 = BigInteger.probablePrime(600, rnd);
      c1 = p1.multiply(p2);
      if (c1.isProbablePrime(100)) {
        System.err.println("Composite failed " + c1.toString(16));
        failCount++;
      }
    }

    report("Prime", failCount);
  }
  /**
   * Compute BN parameters for a given field size, which must be a multiple of 8 between 48 and 512
   * (inclusive).
   *
   * <p>The BN parameter u is the largest one with the smallest possible Hamming weight, leading to
   * a field prime p satisfying both p = 3 (mod 4) and p = 4 (mod 9), speeding up the computation of
   * square and cube roots in both F_p and F_{p^2}. Besides, for i \in F_{p^2} such that i^2 + 1 =
   * 0, the element v = 1 + i is neither a square nor a cube, so that one can represent F_{p^(2m)}
   * as F_{p^2}[z]/(z^m - 1/v) or F_{p^2}[z]/(z^m - v) for m = 2, 3, 6.
   *
   * <p>The standard curve is E(F_p): y^2 = x^3 + 3, whose default generator is G = (1, 2). Its
   * (sextic) twist is E'(F_{p^2}): y'^2 = x'^3 + 3v, whose default generator has the form G' =
   * [p-1+t]*(1, y') for some y'.
   *
   * <p>The standard isomorphism psi: E'(F_{p^2}) -> E(F_{p^12}) is defined as psi(x', y') =
   * (x'*z^2, y'*z^3) for the first representation of F_{p^12} above, and as psi(x', y') = (x'/z^2,
   * y'/z^3) = (x'*z^4/v, y'*z^3/v) for the second representation.
   */
  public BNParams(int fieldBits) {
    m = fieldBits;
    b = 3; // default assumption; corrected below on demand
    switch (fieldBits) {
      case 5:
        u = new BigInteger("-1", 2);
        break;
      case 34: ////////////////////////////////
        b = 2;
        u = new BigInteger("-10000101", 2); // Hamming weight 3
        break;
      case 48:
        u = new BigInteger("-11001011001", 2); // Hamming weight 6
        break;
      case 56:
        u = new BigInteger("1011001111011", 2); // Hamming weight 9
        break;
      case 64:
        u = new BigInteger("110010000111111", 2); // Hamming weight 9
        break;
      case 72:
        u = new BigInteger("10110000111001011", 2); // Hamming weight 9
        break;
      case 80:
        u = new BigInteger("1101000010001011011", 2); // Hamming weight 9
        break;
      case 88:
        u = new BigInteger("-110000011000001110001", 2); // Hamming weight 8
        break;
      case 96:
        u = new BigInteger("11010000000000000010111", 2); // Hamming weight 7
        break;
      case 104:
        u = new BigInteger("1101000000000000000100011", 2); // Hamming weight 6
        break;
      case 112:
        u = new BigInteger("-110000001100001000000000001", 2); // Hamming weight 6
        break;
      case 120:
        u = new BigInteger("11000000100000000100100000011", 2); // Hamming weight 7
        break;
      case 128:
        u = new BigInteger("-1100111000000000000000000000001", 2); // Hamming weight 6
        break;
      case 136:
        u = new BigInteger("-110000100000000000000001100000001", 2); // Hamming weight 6
        break;
      case 144:
        u = new BigInteger("-10110010000000010000000000000000001", 2); // Hamming weight 6
        break;
      case 152:
        u = new BigInteger("-1100100001000000100000000000000000001", 2); // Hamming weight 6
        break;
      case 158: ////////////////////////////////
        b = 2;
        u = new BigInteger("100000000000000100000000000000000100011", 2); // Hamming weight 5
        // u = new BigInteger("-100000010000000100000000010000000000001", 2); // Hamming weight 5
        break;
      case 160:
        // u = new BigInteger("110100001000000000000100010000000000011", 2); // *** ISO, Hamming
        // weight 8
        u = new BigInteger("-110010001000000010000000000000001000001", 2); // Hamming weight 7
        break;
      case 168:
        u = new BigInteger("-11001000000000000000000010000001000000001", 2); // Hamming weight 6
        break;
      case 176:
        u = new BigInteger("-1100100100000000000000000010000000000000001", 2); // Hamming weight 6
        break;
      case 184:
        u = new BigInteger("-110000001100000000000000000000001000000000001", 2); // Hamming weight 6
        break;
      case 190: ////////////////////////////////
        b = 2;
        u =
            new BigInteger(
                "-10000000010000100100000000000000000000000000001", 2); // Hamming weight 5
        // u = new BigInteger("10000000010000000000000000000000000000001000011", 2); // Hamming
        // weight 5
        break;
      case 192:
        // u = new BigInteger("11000000000000000001000000000000000010000010011", 2); // *** ISO,
        // Hamming weight 7
        u =
            new BigInteger(
                "-11000000000000000000010010000000000010000000001", 2); // Hamming weight 6
        break;
      case 200:
        u =
            new BigInteger(
                "-1101000000000000000000001000000000000010000000001", 2); // Hamming weight 6
        break;
      case 208:
        u =
            new BigInteger(
                "110000000000000000000000000000000000000000100000011", 2); // Hamming weight 5
        break;
      case 216:
        u =
            new BigInteger(
                "-11000000000000000010000000000000000000000000000000001", 2); // Hamming weight 4
        break;
      case 222: ////////////////////////////////
        b = 2;
        u =
            new BigInteger(
                "1000010000000000010000000000000000000000000000000000011", 2); // Hamming weight 5
        // u = new BigInteger("1000000000000000000000000000000000000000100100000000011", 2); //
        // Hamming weight 5
        break;
      case 224:
        // u = new BigInteger("1100000000000000000000100000001000000000000001000000011", 2); // ***
        // ISO, Hamming weight 7
        u =
            new BigInteger(
                "-1100000100000000000000000010000000100000000000000000001", 2); // Hamming weight 6
        break;
      case 232:
        u =
            new BigInteger(
                "-110000000100000000100000000000000000000000000010000000001",
                2); // Hamming weight 6
        break;
      case 240:
        u =
            new BigInteger(
                "-11000100000000000000000000000010000000000000000000100000001",
                2); // Hamming weight 6
        break;
      case 248:
        u =
            new BigInteger(
                "-1100010000001000000000100000000000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 254: ////////////////////////////////
        // b = 2; u = new
        // BigInteger("-100000010000000000000000000000000000000000000000000000000000001", 2); //
        // Hamming weight 3
        // u = new BigInteger("-100000010000000000000000000000000000000001000000000001000000001",
        // 2); // Hamming weight 5
        b = 5;
        u =
            new BigInteger(
                "100100010000000000000000000000000000000000000001000001111111111",
                2); // Hamming weight 14 : Subgroup Secure u!
        break;
      case 256:
        u =
            new BigInteger(
                "110000010000000000000000000000000000000000001000000000001000011",
                2); // *** ISO, Hamming weight 7
        // u = new BigInteger("-110000100000100000000001000000000000000000000000000000000000001",
        // 2); // Hamming weight 6
        break;
      case 264:
        u =
            new BigInteger(
                "11000000000000000001000000000000000000000000000000000100000000011",
                2); // Hamming weight 6
        break;
      case 272:
        u =
            new BigInteger(
                "1100000100000000000010000000000000000000000000000000000000001000011",
                2); // Hamming weight 7
        break;
      case 280:
        u =
            new BigInteger(
                "-110001000000000000000000000000100000100000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 288:
        u =
            new BigInteger(
                "11000000000000000000000000000000000100000001000000000000000000000000011",
                2); // Hamming weight 6
        break;
      case 296:
        u =
            new BigInteger(
                "-1100000000000100000000000000100000000000000000000000000000000000000010001",
                2); // Hamming weight 6
        break;
      case 304:
        u =
            new BigInteger(
                "110000000000000100000000000000000000000000000000000000000001000000000000011",
                2); // Hamming weight 6
        break;
      case 312:
        u =
            new BigInteger(
                "-11000000000000001000000000000000000000000001000010000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 318: ////////////////////////////////
        b = 2;
        u =
            new BigInteger(
                "1000000000000000100000000000000000000000000000000000000000000000000000000000011",
                2); // Hamming weight 4
        // u = new
        // BigInteger("-1000000000000000100000000000000000000000000000000000000000000000001000000010001", 2); // Hamming weight 5
        break;
      case 320:
        u =
            new BigInteger(
                "-1100000001000000000000000000000000000000000010001000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 328:
        u =
            new BigInteger(
                "-110000000000100000000000000000000000000000000000000010000000000100000000000000001",
                2); // Hamming weight 6
        break;
      case 336:
        u =
            new BigInteger(
                "-11000000000000000000000000000000000000010000000000000000000100000000000000000000001",
                2); // Hamming weight 5
        break;
      case 344:
        u =
            new BigInteger(
                "-1100100000000000000000000000000000000000010000001000000000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 352:
        u =
            new BigInteger(
                "-110000100000000000000000000000000000001000000000000000000000010000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 360:
        u =
            new BigInteger(
                "-11000100001000000000000000000000000000000000000000001000000000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 368:
        u =
            new BigInteger(
                "-1100000000000000001010000000000000000000000001000000000000000000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 376:
        u =
            new BigInteger(
                "-110000000010000000000100000000000000000000000000000000000000000000000000000000000000100000001",
                2); // Hamming weight 6
        break;
      case 382: ////////////////////////////////
        b = 2;
        u =
            new BigInteger(
                "-10000000000000000010001000000000000000000000000000000000000000000000000000000000000000000000001",
                2); // Hamming weight 4
        break;
      case 384:
        // u = new
        // BigInteger("11001000000000000010000000000000000000000000000000000000000000000100000000000000000000000000011", 2); // *** ISO, Hamming weight 7
        u =
            new BigInteger(
                "-11000000000000000000000000000000000001000000000000000000000000000000000000000001000000000000001",
                2); // Hamming weight 5
        break;
      case 392:
        u =
            new BigInteger(
                "-1100100001000000000000000000000000000000000000000000000000000000000000000000100000000000000000001",
                2); // Hamming weight 6
        break;
      case 400:
        u =
            new BigInteger(
                "110000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000011",
                2); // Hamming weight 6
        break;
      case 408:
        u =
            new BigInteger(
                "-11000000000000010000000000000000000000000000000000000000000000000000000000000000000010000000000010001",
                2); // Hamming weight 6
        break;
      case 416:
        u =
            new BigInteger(
                "-1100100000000000000000000000000000010000000000000000000000000000001000000000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 424:
        u =
            new BigInteger(
                "-110000000000000000000000000000100000000000010000000000000000000000001000000000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 432:
        u =
            new BigInteger(
                "-11000000000000000000000000000000000000000000000000010010000000000000000000000000000000000010000000000000001",
                2); // Hamming weight 6
        break;
      case 440:
        u =
            new BigInteger(
                "-1100100000000000000000000000000000000000001000000000000000000000000000010000000000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 446: ////////////////////////////////
        b = 2;
        u =
            new BigInteger(
                "-100000000000000000000000000000000000000000000010000000001000000000000000000000000000000000000000000000000000001",
                2); // Hamming weight 4
        break;
      case 448:
        u =
            new BigInteger(
                "110000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000001000000000000011",
                2); // Hamming weight 6
        break;
      case 456:
        u =
            new BigInteger(
                "-11000000000000000000000000000100000000000000000000000000000000000000000000010000000000000000000000000000000000001",
                2); // Hamming weight 5
        break;
      case 464:
        u =
            new BigInteger(
                "-1100100000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 472:
        u =
            new BigInteger(
                "-110000001000000000000000000000000000000000000000000000000000000000000000010000000000000000000000100000000000000000001",
                2); // Hamming weight 6
        break;
      case 480:
        u =
            new BigInteger(
                "-11000000000000000100000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
                2); // Hamming weight 5
        break;
      case 488:
        u =
            new BigInteger(
                "-1100000001000000000000000000000000000000000000000010000000000000000000000000000000001000000000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 496:
        u =
            new BigInteger(
                "-110010000000000000000000000100000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000001",
                2); // Hamming weight 6
        break;
      case 504:
        u =
            new BigInteger(
                "-11010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000001",
                2); // Hamming weight 5
        break;
      case 512:
        // u = new
        // BigInteger("1100001000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001000000000000000011", 2); // *** ISO, Hamming weight 7
        u =
            new BigInteger(
                "-1100001000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000001",
                2); // Hamming weight 6
        break;
      default:
        throw new IllegalArgumentException(
            invalidParams + ": " + "Field size in bits must be a multiple of 8 between 56 and 512");
    }
    // p = 36*u^4 + 36*u^3 + 24*u^2 + 6*u + 1 = (((u + 1)*6*u + 4)*u + 1)*6*u + 1
    p =
        u.add(_1)
            .multiply(_6.multiply(u))
            .add(_4)
            .multiply(u)
            .add(_1)
            .multiply(_6.multiply(u))
            .add(_1);
    assert (p.mod(_4).intValue() == 3);
    // assert (p.mod(_9).intValue() == 4);
    assert (p.isProbablePrime(PRIMALITY_CERTAINTY));
    t = _6.multiply(u).multiply(u).add(_1); // 6*u^2 + 1
    ht = p.subtract(_1).add(t);
    // n = 36*u^4 + 36*u^3 + 18*u^2 + 6*u + 1
    n = p.add(_1).subtract(t);
    assert (n.isProbablePrime(PRIMALITY_CERTAINTY));
    // zeta = 18*u^3 + 18*u^2 + 9*u + 1;
    zeta = _9.multiply(u).multiply(u.shiftLeft(1).multiply(u.add(_1)).add(_1)).add(_1);
    // System.out.println("zeta = " + zeta);
    zeta0 = zeta;
    zeta1 = zeta.add(_1);
    // rho = |36*u^3 + 18*u^2 + 6*u + 1| = |6*u*(3*u*(2*u + 1) + 1) + 1)|;
    rho = _6.multiply(u).multiply(_3.multiply(u).multiply(u.shiftLeft(1).add(_1)).add(_1)).add(_1);
    // *
    if (rho.signum() < 0) {
      rho = rho.negate();
    }
    // */
    optOrd = _6.multiply(u).add(_2);
    // *
    if (optOrd.signum() < 0) {
      optOrd = optOrd.negate();
    }
    // */
    sqrtExponent = p.add(_1).shiftRight(2); // (p + 1)/4
    cbrtExponent = p.add(p).add(_1).divide(_9); // (2*p + 1)/9
    sqrtExponent2 = p.multiply(p).add(_7).shiftRight(4); // (p^2 + 7)/16
    cbrtExponent2 = p.multiply(p).add(_2).divide(_9); // (p^2 + 2)/9
    sigma =
        p.subtract(_4)
            .modPow(p.subtract(_1).subtract(p.add(_5).divide(_24)), p); // (-1/4)^((p+5)/24)
    zeta0sigma = zeta0.multiply(sigma).mod(p);
    zeta1sigma = zeta1.multiply(sigma).mod(p);

    //  2*sigma^2 = -zeta
    // -2*sigma^3 = -sigma*(2*sigma^2) = sigma*zeta
    // -4*sigma^4 = zeta+1
    // -4*sigma^5 = -4*sigma^4*sigma = (zeta+1)*sigma
    //  8*sigma^6 = -1
    // -16*sigma^9 = -2*sigma^3*(8*sigma^6) = 2*sigma^3
    invSqrtMinus2 =
        p.subtract(_2)
            .modPow(
                p.subtract(_1).subtract(p.add(_1).shiftRight(2)),
                p); // 1/sqrt(-2) = (-2)^{-(p+1)/4}
    sqrtI =
        new BNField2(
            this,
            invSqrtMinus2,
            (invSqrtMinus2.signum() != 0) ? p.subtract(invSqrtMinus2) : invSqrtMinus2,
            false); // sqrt(i) = (1 - i)/sqrt(-2)
    Fp2_0 = new BNField2(this, _0);
    Fp2_1 = new BNField2(this, _1);
    Fp2_i = new BNField2(this, _0, _1, false);
    Fp12_0 = new BNField12(this, _0);
    Fp12_1 = new BNField12(this, _1);

    latInv = new BigInteger[4];
    latInv[0] = u.shiftLeft(1).add(_3).multiply(u).add(_1); // 2*u^2 + 3*u + 1 = (2*u + 3)*u + 1
    latInv[1] =
        u.multiply(_3)
            .add(_2)
            .multiply(u)
            .multiply(u)
            .shiftLeft(2)
            .add(u); // 12*u^3 + 8*u^2 + u = ((3*u + 2)*u)*4*u + u
    latInv[2] =
        u.multiply(_3)
            .add(_2)
            .multiply(u)
            .multiply(u)
            .shiftLeft(1)
            .add(u); //  6*u^3 + 4*u^2 + u = ((3*u + 2)*u)*2*u + u
    latInv[3] = u.multiply(u).shiftLeft(1).add(u).negate(); // -(2*u^2 + u)

    latRed = new BigInteger[4][4];
    /*
       u+1,       u,      u,  -2*u,
       2*u+1,    -u, -(u+1),    -u,
       2*u,   2*u+1,  2*u+1, 2*u+1,
       u-1,   4*u+2, -2*u+1,   u-1
    */

    latRed[0][0] = u.add(_1);
    latRed[0][1] = u;
    latRed[0][2] = u;
    latRed[0][3] = u.shiftLeft(1).negate();

    latRed[1][0] = u.shiftLeft(1).add(_1);
    latRed[1][1] = u.negate();
    latRed[1][2] = u.add(_1).negate();
    latRed[1][3] = u.negate();

    latRed[2][0] = u.shiftLeft(1);
    latRed[2][1] = u.shiftLeft(1).add(_1);
    latRed[2][2] = u.shiftLeft(1).add(_1);
    latRed[2][3] = u.shiftLeft(1).add(_1);

    latRed[3][0] = u.subtract(_1);
    latRed[3][1] = u.shiftLeft(2).add(_2);
    latRed[3][2] = u.shiftLeft(1).negate().add(_1);
    latRed[3][3] = u.subtract(_1);
  }
Exemple #19
0
 public boolean isProbablePrime(String val) {
   BigInteger i = new BigInteger(val, 10);
   return i.isProbablePrime(80);
 }
  /**
   * generate suitable parameters for DSA, in line with <i>FIPS 186-3 A.1 Generation of the FFC
   * Primes p and q</i>.
   */
  private DSAParameters generateParameters_FIPS186_3() {
    // A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
    // FIXME This should be configurable (digest size in bits must be >= N)
    Digest d = digest;
    int outlen = d.getDigestSize() * 8;

    // 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If
    //    the pair is not in the list, then return INVALID.
    // Note: checked at initialisation

    // 2. If (seedlen < N), then return INVALID.
    // FIXME This should be configurable (must be >= N)
    int seedlen = N;
    byte[] seed = new byte[seedlen / 8];

    // 3. n = ceiling(L ⁄ outlen) – 1.
    int n = (L - 1) / outlen;

    // 4. b = L – 1 – (n ∗ outlen).
    int b = (L - 1) % outlen;

    byte[] output = new byte[d.getDigestSize()];
    for (; ; ) {
      // 5. Get an arbitrary sequence of seedlen bits as the domain_parameter_seed.
      random.nextBytes(seed);

      // 6. U = Hash (domain_parameter_seed) mod 2^(N–1).
      hash(d, seed, output);

      BigInteger U = new BigInteger(1, output).mod(ONE.shiftLeft(N - 1));

      // 7. q = 2^(N–1) + U + 1 – ( U mod 2).
      BigInteger q = ONE.shiftLeft(N - 1).add(U).add(ONE).subtract(U.mod(TWO));

      // 8. Test whether or not q is prime as specified in Appendix C.3.
      // TODO Review C.3 for primality checking
      if (!q.isProbablePrime(certainty)) {
        // 9. If q is not a prime, then go to step 5.
        continue;
      }

      // 10. offset = 1.
      // Note: 'offset' value managed incrementally
      byte[] offset = Arrays.clone(seed);

      // 11. For counter = 0 to (4L – 1) do
      int counterLimit = 4 * L;
      for (int counter = 0; counter < counterLimit; ++counter) {
        // 11.1 For j = 0 to n do
        //      Vj = Hash ((domain_parameter_seed + offset + j) mod 2^seedlen).
        // 11.2 W = V0 + (V1 ∗ 2^outlen) + ... + (V^(n–1) ∗ 2^((n–1) ∗ outlen)) + ((Vn mod 2^b) ∗
        // 2^(n ∗ outlen)).
        // TODO Assemble w as a byte array
        BigInteger W = ZERO;
        for (int j = 0, exp = 0; j <= n; ++j, exp += outlen) {
          inc(offset);
          hash(d, offset, output);

          BigInteger Vj = new BigInteger(1, output);
          if (j == n) {
            Vj = Vj.mod(ONE.shiftLeft(b));
          }

          W = W.add(Vj.shiftLeft(exp));
        }

        // 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2L–1; hence, 2L–1 ≤ X < 2L.
        BigInteger X = W.add(ONE.shiftLeft(L - 1));

        // 11.4 c = X mod 2q.
        BigInteger c = X.mod(q.shiftLeft(1));

        // 11.5 p = X - (c - 1). Comment: p ≡ 1 (mod 2q).
        BigInteger p = X.subtract(c.subtract(ONE));

        // 11.6 If (p < 2^(L - 1)), then go to step 11.9
        if (p.bitLength() != L) {
          continue;
        }

        // 11.7 Test whether or not p is prime as specified in Appendix C.3.
        // TODO Review C.3 for primality checking
        if (p.isProbablePrime(certainty)) {
          // 11.8 If p is determined to be prime, then return VALID and the values of p, q and
          //      (optionally) the values of domain_parameter_seed and counter.
          if (usageIndex >= 0) {
            BigInteger g = calculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, usageIndex);
            if (g != null) {
              return new DSAParameters(
                  p, q, g, new DSAValidationParameters(seed, counter, usageIndex));
            }
          }

          BigInteger g = calculateGenerator_FIPS186_3_Unverifiable(p, q, random);

          return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter));
        }

        // 11.9 offset = offset + n + 1.      Comment: Increment offset; then, as part of
        //                                    the loop in step 11, increment counter; if
        //                                    counter < 4L, repeat steps 11.1 through 11.8.
        // Note: 'offset' value already incremented in inner loop
      }
      // 12. Go to step 5.
    }
  }
  private DSAParameters generateParameters_FIPS186_2() {
    byte[] seed = new byte[20];
    byte[] part1 = new byte[20];
    byte[] part2 = new byte[20];
    byte[] u = new byte[20];
    int n = (L - 1) / 160;
    byte[] w = new byte[L / 8];

    // BEGIN android-changed
    if (!(digest.getAlgorithmName().equals("SHA-1")))
    // END android-changed
    {
      throw new IllegalStateException("can only use SHA-1 for generating FIPS 186-2 parameters");
    }

    for (; ; ) {
      random.nextBytes(seed);

      hash(digest, seed, part1);
      System.arraycopy(seed, 0, part2, 0, seed.length);
      inc(part2);
      hash(digest, part2, part2);

      for (int i = 0; i != u.length; i++) {
        u[i] = (byte) (part1[i] ^ part2[i]);
      }

      u[0] |= (byte) 0x80;
      u[19] |= (byte) 0x01;

      BigInteger q = new BigInteger(1, u);

      if (!q.isProbablePrime(certainty)) {
        continue;
      }

      byte[] offset = Arrays.clone(seed);
      inc(offset);

      for (int counter = 0; counter < 4096; ++counter) {
        for (int k = 0; k < n; k++) {
          inc(offset);
          hash(digest, offset, part1);
          System.arraycopy(part1, 0, w, w.length - (k + 1) * part1.length, part1.length);
        }

        inc(offset);
        hash(digest, offset, part1);
        System.arraycopy(
            part1,
            part1.length - ((w.length - (n) * part1.length)),
            w,
            0,
            w.length - n * part1.length);

        w[0] |= (byte) 0x80;

        BigInteger x = new BigInteger(1, w);

        BigInteger c = x.mod(q.shiftLeft(1));

        BigInteger p = x.subtract(c.subtract(ONE));

        if (p.bitLength() != L) {
          continue;
        }

        if (p.isProbablePrime(certainty)) {
          BigInteger g = calculateGenerator_FIPS186_2(p, q, random);

          return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter));
        }
      }
    }
  }
 public static BigInteger nextPrime(BigInteger start) {
   if (isEven(start)) start = start.add(ONE);
   else start = start.add(TWO);
   if (start.isProbablePrime(ERR_VAL)) return (start);
   else return (nextPrime(start));
 }
  /** @tests java.math.BigInteger#isProbablePrime(int) */
  @TestTargets({
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "isProbablePrime",
        args = {int.class}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "probablePrime",
        args = {int.class, java.util.Random.class})
  })
  public void test_isProbablePrimeI() {
    int fails = 0;
    bi = new BigInteger(20, 20, rand);
    if (!bi.isProbablePrime(17)) {
      fails++;
    }
    bi = new BigInteger("4", 10);
    if (bi.isProbablePrime(17)) {
      fail("isProbablePrime failed for: " + bi);
    }
    bi = BigInteger.valueOf(17L * 13L);
    if (bi.isProbablePrime(17)) {
      fail("isProbablePrime failed for: " + bi);
    }
    for (long a = 2; a < 1000; a++) {
      if (isPrime(a)) {
        assertTrue(
            "false negative on prime number <1000", BigInteger.valueOf(a).isProbablePrime(5));
      } else if (BigInteger.valueOf(a).isProbablePrime(17)) {
        System.out.println("isProbablePrime failed for: " + a);
        fails++;
      }
    }
    for (int a = 0; a < 1000; a++) {
      bi =
          BigInteger.valueOf(rand.nextInt(1000000))
              .multiply(BigInteger.valueOf(rand.nextInt(1000000)));
      if (bi.isProbablePrime(17)) {
        System.out.println("isProbablePrime failed for: " + bi);
        fails++;
      }
    }
    for (int a = 0; a < 200; a++) {
      bi = new BigInteger(70, rand).multiply(new BigInteger(70, rand));
      if (bi.isProbablePrime(17)) {
        System.out.println("isProbablePrime failed for: " + bi);
        fails++;
      }
    }
    assertTrue("Too many false positives - may indicate a problem", fails <= 1);

    //
    // And now some tests on real big integers:
    //
    bi =
        new BigInteger(
            "153890972191202256150310830154922163807316525358455215516067727076235016932726922093888770552128767458882963869421440585369743",
            10);
    if (!bi.isProbablePrime(80)) {
      fail("isProbablePrime failed for: " + bi);
    }
    bi =
        new BigInteger(
            "2090575416269141767246491983797422123741252476560371649798066134123893524014911825188890458270426076468664046568752890122415061377308817346303546688282957897504000216241497550243010257911214329646877810655164658470278901030511157372440751259674247310396158238588463284702737181653",
            10);
    if (!bi.isProbablePrime(80)) {
      fail("isProbablePrime failed for: " + bi);
    }
    //
    for (int bitLength = 100; bitLength <= 600; bitLength += 100) {
      BigInteger a = BigInteger.probablePrime(bitLength, rand);
      BigInteger b = BigInteger.probablePrime(bitLength, rand);
      BigInteger c = a.multiply(b);
      assertFalse(
          "isProbablePrime failed for product of two large primes"
              + a
              + " * "
              + b
              + " = "
              + c
              + " (bitLength = "
              + bitLength
              + ")",
          c.isProbablePrime(80));
    }
  }
  /**
   * which generates the p and g values from the given parameters, returning the DSAParameters
   * object.
   *
   * <p>Note: can take a while...
   */
  public DSAParameters generateParameters() {
    byte[] seed = new byte[20];
    byte[] part1 = new byte[20];
    byte[] part2 = new byte[20];
    byte[] u = new byte[20];
    SHA1Digest sha1 = new SHA1Digest();
    int n = (size - 1) / 160;
    byte[] w = new byte[size / 8];

    BigInteger q = null, p = null, g = null;
    int counter = 0;
    boolean primesFound = false;

    while (!primesFound) {
      do {
        random.nextBytes(seed);

        sha1.update(seed, 0, seed.length);

        sha1.doFinal(part1, 0);

        System.arraycopy(seed, 0, part2, 0, seed.length);

        add(part2, seed, 1);

        sha1.update(part2, 0, part2.length);

        sha1.doFinal(part2, 0);

        for (int i = 0; i != u.length; i++) {
          u[i] = (byte) (part1[i] ^ part2[i]);
        }

        u[0] |= (byte) 0x80;
        u[19] |= (byte) 0x01;

        q = new BigInteger(1, u);
      } while (!q.isProbablePrime(certainty));

      counter = 0;

      int offset = 2;

      while (counter < 4096) {
        for (int k = 0; k < n; k++) {
          add(part1, seed, offset + k);
          sha1.update(part1, 0, part1.length);
          sha1.doFinal(part1, 0);
          System.arraycopy(part1, 0, w, w.length - (k + 1) * part1.length, part1.length);
        }

        add(part1, seed, offset + n);
        sha1.update(part1, 0, part1.length);
        sha1.doFinal(part1, 0);
        System.arraycopy(
            part1,
            part1.length - ((w.length - (n) * part1.length)),
            w,
            0,
            w.length - n * part1.length);

        w[0] |= (byte) 0x80;

        BigInteger x = new BigInteger(1, w);

        BigInteger c = x.mod(q.multiply(TWO));

        p = x.subtract(c.subtract(ONE));

        if (p.testBit(size - 1)) {
          if (p.isProbablePrime(certainty)) {
            primesFound = true;
            break;
          }
        }

        counter += 1;
        offset += n + 1;
      }
    }

    //
    // calculate the generator g
    //
    BigInteger pMinusOneOverQ = p.subtract(ONE).divide(q);

    for (; ; ) {
      BigInteger h = new BigInteger(size, random);

      if (h.compareTo(ONE) <= 0 || h.compareTo(p.subtract(ONE)) >= 0) {
        continue;
      }

      g = h.modPow(pMinusOneOverQ, p);
      if (g.compareTo(ONE) <= 0) {
        continue;
      }

      break;
    }

    return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter));
  }