01: package org.bouncycastle.crypto.generators;
02:
03: import java.math.BigInteger;
04: import java.security.SecureRandom;
05:
06: class DHParametersHelper {
07: private static final BigInteger ONE = BigInteger.valueOf(1);
08: private static final BigInteger TWO = BigInteger.valueOf(2);
09:
10: // Finds a pair of prime BigInteger's {p, q: p = 2q + 1}
11: static BigInteger[] generateSafePrimes(int size, int certainty,
12: SecureRandom random) {
13: BigInteger p, q;
14: int qLength = size - 1;
15:
16: for (;;) {
17: q = new BigInteger(qLength, 2, random);
18:
19: // p <- 2q + 1
20: p = q.shiftLeft(1).add(ONE);
21:
22: if (p.isProbablePrime(certainty)
23: && (certainty <= 2 || q.isProbablePrime(certainty))) {
24: break;
25: }
26: }
27:
28: return new BigInteger[] { p, q };
29: }
30:
31: // Select a high order element of the multiplicative group Zp*
32: // p and q must be s.t. p = 2*q + 1, where p and q are prime
33: static BigInteger selectGenerator(BigInteger p, BigInteger q,
34: SecureRandom random) {
35: BigInteger pMinusTwo = p.subtract(TWO);
36: BigInteger g;
37:
38: // Handbook of Applied Cryptography 4.86
39: do {
40: g = createInRange(TWO, pMinusTwo, random);
41: } while (g.modPow(TWO, p).equals(ONE)
42: || g.modPow(q, p).equals(ONE));
43:
44: /*
45: // RFC 2631 2.1.1 (and see Handbook of Applied Cryptography 4.81)
46: do
47: {
48: BigInteger h = createInRange(TWO, pMinusTwo, random);
49:
50: g = h.modPow(TWO, p);
51: }
52: while (g.equals(ONE));
53: */
54:
55: return g;
56: }
57:
58: private static BigInteger createInRange(BigInteger min,
59: BigInteger max, SecureRandom random) {
60: BigInteger x;
61: do {
62: x = new BigInteger(max.bitLength(), random);
63: } while (x.compareTo(min) < 0 || x.compareTo(max) > 0);
64: return x;
65: }
66: }
|