/** * 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()); }
public static MROutput EnhancedMRProbablePrimeTest(BigInteger candidate, SecureRandom random, int iterations) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) 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 bigInteger = candidate.Subtract(One); BigInteger max = candidate.Subtract(Two); int lowestSetBit = bigInteger.GetLowestSetBit(); BigInteger e = bigInteger.ShiftRight(lowestSetBit); for (int i = 0; i < iterations; i++) { BigInteger bigInteger2 = BigIntegers.CreateRandomInRange(Two, max, random); BigInteger bigInteger3 = bigInteger2.Gcd(candidate); if (bigInteger3.CompareTo(One) > 0) { return(MROutput.ProvablyCompositeWithFactor(bigInteger3)); } BigInteger bigInteger4 = bigInteger2.ModPow(e, candidate); if (bigInteger4.Equals(One) || bigInteger4.Equals(bigInteger)) { continue; } bool flag = false; BigInteger bigInteger5 = bigInteger4; for (int j = 1; j < lowestSetBit; j++) { bigInteger4 = bigInteger4.ModPow(Two, candidate); if (bigInteger4.Equals(bigInteger)) { flag = true; break; } if (bigInteger4.Equals(One)) { break; } bigInteger5 = bigInteger4; } if (flag) { continue; } if (!bigInteger4.Equals(One)) { bigInteger5 = bigInteger4; bigInteger4 = bigInteger4.ModPow(Two, candidate); if (!bigInteger4.Equals(One)) { bigInteger5 = bigInteger4; } } bigInteger3 = bigInteger5.Subtract(One).Gcd(candidate); if (bigInteger3.CompareTo(One) > 0) { return(MROutput.ProvablyCompositeWithFactor(bigInteger3)); } return(MROutput.ProvablyCompositeNotPrimePower()); } return(MROutput.ProbablyPrime()); }