private static ECPoint ImplShamirsTrick(ECPoint P, BigInteger k, ECPoint Q, BigInteger l) { int m = System.Math.Max(k.BitLength, l.BitLength); ECPoint Z = P.Add(Q); ECPoint R = P.Curve.Infinity; for (int i = m - 1; i >= 0; --i) { R = R.Twice(); if (k.TestBit(i)) { if (l.TestBit(i)) { R = R.Add(Z); } else { R = R.Add(P); } } else { if (l.TestBit(i)) { R = R.Add(Q); } } } return R; }
public DHParameters( BigInteger p, BigInteger g, BigInteger q, int m, int l, BigInteger j, DHValidationParameters validation) { if (p == null) throw new ArgumentNullException("p"); if (g == null) throw new ArgumentNullException("g"); if (!p.TestBit(0)) throw new ArgumentException("field must be an odd prime", "p"); if (g.CompareTo(BigInteger.Two) < 0 || g.CompareTo(p.Subtract(BigInteger.Two)) > 0) throw new ArgumentException("generator must in the range [2, p - 2]", "g"); if (q != null && q.BitLength >= p.BitLength) throw new ArgumentException("q too big to be a factor of (p-1)", "q"); if (m >= p.BitLength) throw new ArgumentException("m value must be < bitlength of p", "m"); if (l != 0) { // TODO Check this against the Java version, which has 'l > p.BitLength' here if (l >= p.BitLength) throw new ArgumentException("when l value specified, it must be less than bitlength(p)", "l"); if (l < m) throw new ArgumentException("when l value specified, it may not be less than m value", "l"); } if (j != null && j.CompareTo(BigInteger.Two) < 0) throw new ArgumentException("subgroup factor must be >= 2", "j"); // TODO If q, j both provided, validate p = jq + 1 ? this.p = p; this.g = g; this.q = q; this.m = m; this.l = l; this.j = j; this.validation = validation; }
/** * FIPS 186-4 C.3.1 Miller-Rabin Probabilistic Primality Test * * Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases. * * @param candidate * the {@link BigInteger} instance to test for primality. * @param random * the source of randomness to use to choose bases. * @param iterations * the number of randomly-chosen bases to perform the test for. * @return <code>false</code> if any witness to compositeness is found amongst the chosen bases * (so <code>candidate</code> is definitely NOT prime), or else <code>true</code> * (indicating primality with some probability dependent on the number of iterations * that were performed). */ public static bool IsMRProbablePrime(BigInteger candidate, SecureRandom random, int iterations) { CheckCandidate(candidate, "candidate"); if (random == null) throw new ArgumentException("cannot be null", "random"); if (iterations < 1) throw new ArgumentException("must be > 0", "iterations"); if (candidate.BitLength == 2) return true; if (!candidate.TestBit(0)) return false; BigInteger w = candidate; BigInteger wSubOne = candidate.Subtract(One); BigInteger wSubTwo = candidate.Subtract(Two); int a = wSubOne.GetLowestSetBit(); BigInteger m = wSubOne.ShiftRight(a); for (int i = 0; i < iterations; ++i) { BigInteger b = BigIntegers.CreateRandomInRange(Two, wSubTwo, random); if (!ImplMRProbablePrimeToBase(w, wSubOne, m, a, b)) return false; } return true; }
/** * FIPS 186-4 C.3.2 Enhanced Miller-Rabin Probabilistic Primality Test * * Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases. This is an * alternative to {@link #isMRProbablePrime(BigInteger, SecureRandom, int)} that provides more * information about a composite candidate, which may be useful when generating or validating * RSA moduli. * * @param candidate * the {@link BigInteger} instance to test for primality. * @param random * the source of randomness to use to choose bases. * @param iterations * the number of randomly-chosen bases to perform the test for. * @return an {@link MROutput} instance that can be further queried for details. */ public static MROutput EnhancedMRProbablePrimeTest(BigInteger candidate, SecureRandom random, int iterations) { CheckCandidate(candidate, "candidate"); if (random == null) throw new ArgumentNullException("random"); if (iterations < 1) throw new ArgumentException("must be > 0", "iterations"); if (candidate.BitLength == 2) return MROutput.ProbablyPrime(); if (!candidate.TestBit(0)) return MROutput.ProvablyCompositeWithFactor(Two); BigInteger w = candidate; BigInteger wSubOne = candidate.Subtract(One); BigInteger wSubTwo = candidate.Subtract(Two); int a = wSubOne.GetLowestSetBit(); BigInteger m = wSubOne.ShiftRight(a); for (int i = 0; i < iterations; ++i) { BigInteger b = BigIntegers.CreateRandomInRange(Two, wSubTwo, random); BigInteger g = b.Gcd(w); if (g.CompareTo(One) > 0) return MROutput.ProvablyCompositeWithFactor(g); BigInteger z = b.ModPow(m, w); if (z.Equals(One) || z.Equals(wSubOne)) continue; bool primeToBase = false; BigInteger x = z; for (int j = 1; j < a; ++j) { z = z.ModPow(Two, w); if (z.Equals(wSubOne)) { primeToBase = true; break; } if (z.Equals(One)) break; x = z; } if (!primeToBase) { if (!z.Equals(One)) { x = z; z = z.ModPow(Two, w); if (!z.Equals(One)) { x = z; } } g = x.Subtract(One).Gcd(w); if (g.CompareTo(One) > 0) return MROutput.ProvablyCompositeWithFactor(g); return MROutput.ProvablyCompositeNotPrimePower(); } } return MROutput.ProbablyPrime(); }
private BigInteger multiply( BigInteger X, BigInteger Y) { BigInteger Z = BigInteger.Zero; BigInteger V = X; for (int i = 0; i < 128; ++i) { if (Y.TestBit(127 - i)) { Z = Z.Xor(V); } bool lsb = V.TestBit(0); V = V.ShiftRight(1); if (lsb) { V = V.Xor(R); } } return Z; }
/** * Simple shift-and-add multiplication. Serves as reference implementation * to verify (possibly faster) implementations in * {@link org.bouncycastle.math.ec.ECPoint ECPoint}. * * @param p * The point to multiply. * @param k * The multiplier. * @return The result of the point multiplication <code>kP</code>. */ private ECPoint Multiply(ECPoint p, BigInteger k) { ECPoint q = p.Curve.Infinity; int t = k.BitLength; for (int i = 0; i < t; i++) { if (i != 0) { p = p.Twice(); } if (k.TestBit(i)) { q = q.Add(p); } } return q; }
public void TestTestBit() { for (int i = 0; i < 10; ++i) { BigInteger n = new BigInteger(128, random); Assert.IsFalse(n.TestBit(128)); Assert.IsTrue(n.Negate().TestBit(128)); for (int j = 0; j < 10; ++j) { int pos = random.Next(128); bool test = n.ShiftRight(pos).Remainder(two).Equals(one); Assert.AreEqual(test, n.TestBit(pos)); } } }
public void TestBitCount() { Assert.AreEqual(0, zero.BitCount); Assert.AreEqual(1, one.BitCount); Assert.AreEqual(0, minusOne.BitCount); Assert.AreEqual(1, two.BitCount); Assert.AreEqual(1, minusTwo.BitCount); for (int i = 0; i < 100; ++i) { BigInteger pow2 = one.ShiftLeft(i); Assert.AreEqual(1, pow2.BitCount); Assert.AreEqual(i, pow2.Negate().BitCount); } for (int i = 0; i < 10; ++i) { BigInteger test = new BigInteger(128, 0, random); int bitCount = 0; for (int bit = 0; bit < test.BitLength; ++bit) { if (test.TestBit(bit)) { ++bitCount; } } Assert.AreEqual(bitCount, test.BitCount); } }
public void TestShiftRight() { for (int i = 0; i < 10; ++i) { int shift = random.Next(128); BigInteger a = new BigInteger(256 + i, random).SetBit(256 + i); BigInteger b = a.ShiftRight(shift); Assert.AreEqual(a.BitLength - shift, b.BitLength); for (int j = 0; j < b.BitLength; ++j) { Assert.AreEqual(a.TestBit(j + shift), b.TestBit(j)); } } }
public void TestShiftLeft() { for (int i = 0; i < 100; ++i) { int shift = random.Next(128); BigInteger a = new BigInteger(128 + i, random).Add(one); int bits = a.BitCount; // Make sure nBits is set BigInteger negA = a.Negate(); bits = negA.BitCount; // Make sure nBits is set BigInteger b = a.ShiftLeft(shift); BigInteger c = negA.ShiftLeft(shift); Assert.AreEqual(a.BitCount, b.BitCount); Assert.AreEqual(negA.BitCount + shift, c.BitCount); Assert.AreEqual(a.BitLength + shift, b.BitLength); Assert.AreEqual(negA.BitLength + shift, c.BitLength); int j = 0; for (; j < shift; ++j) { Assert.IsFalse(b.TestBit(j)); } for (; j < b.BitLength; ++j) { Assert.AreEqual(a.TestBit(j - shift), b.TestBit(j)); } } }