private static bool TestForPrimality(BigInteger testValue) { bool result = MillerRabin.IsProbablyPrime(testValue, QuickTestCount); // Test just a few bases here, as a quick elimination test if (result) { return(MillerRabin.IsProbablyPrime(testValue, FullTestCount)); // Test more bases here to ensure candidate is really prime } else { return(false); } }
public static BigInteger GetNextPrime(BigInteger fromValue) { bool isPrime = false; BigInteger currentValue = fromValue % 2 == 0 ? fromValue + 1 : fromValue + 2; while (!isPrime) { isPrime = MillerRabin.IsProbablyPrime(currentValue, QuickTestCount); // Test just a few bases here, as a quick elimination test if (isPrime) { isPrime = MillerRabin.IsProbablyPrime(currentValue, FullTestCount); // Test more bases here to ensure candidate is really prime } currentValue += 2; } return(BigInteger.MinusOne); }
/// <summary> /// Returns a probable prime of size bits and will search n rounds for a composite /// </summary> /// <param name="bitSize">Size of prime, in bits</param> /// <param name="testCount">Number of different bases to use when testing probable prime for composites as evidence of primality</param> /// <returns></returns> public BigInteger GetProbablePrime(int bitSize, int testCount) { BigInteger result = 0; //Log.Message("."); Log.MethodEnter("ProvablePrime", nameof(bitSize), bitSize); if (cancelToken.IsCancellationRequested) { Log.Message("ProvablePrime.CancellationToken.IsCancellationRequested();"); Log.MethodLeave(); return(-1); } if (bitSize <= 20) { Log.Message("***MAXIMUM RECURSION DEPT REACHED"); result = TrialDivision.FindSmallPrimes(bitSize); Log.Message("***Hopeful prime: {0}", result); } else { //double c = 0.1; int m = 20; double r = 0.5; if (bitSize > 2 * m) { double rnd = 0; bool done = false; while (!done) { rnd = CryptoRandomSingleton.NextDouble(); r = Math.Pow(2, rnd - 1); done = (bitSize - r * bitSize) > m; } } int newBits = (int)Math.Floor(r * bitSize) + 1; BigInteger smallPrime = GetProbablePrime(newBits, testCount); if (smallPrime == -1) { Log.MethodLeave(); return(-1); } Log.Message("After Recursion: Length = {0}", smallPrime.ToString().Length); BigInteger pow = BigInteger.Pow(Two, bitSize - 1); BigInteger Q = Two * smallPrime; BigInteger I = pow / Q; bool success = false; while (!success) { if (cancelToken.IsCancellationRequested) { Log.Message("ProvablePrime.CancellationToken.IsCancellationRequested();"); Log.MethodLeave(); return(-1); } //LogMethod("Loop[{0}]: TestComposite({1})", _loopCount, result); BigInteger J = I + 1; BigInteger K = 2 * I; BigInteger rand1 = CryptoRandomSingleton.RandomRange(J, K); result = 2 * rand1; result = result * smallPrime; result = result + 1; bool isPrime = false; if (Eratosthenes.IsTooLarge(result)) { isPrime = true; } else { isPrime = Eratosthenes.IsPrime(result); } if (isPrime) { //LogMethod("ProvablePrime.RandomRange(J: {0}, K: {1}) = {2}", J, K, rand1); if (MillerRabin.IsProbablyPrime(result, testCount)) { success = true; string cert = MillerRabin.GetCertificateOfPrimality(result, rand1); if (cert != null) { Log.Message(cert); } } } } } //Log.Message("."); Log.MethodLeave(); return(result); }