public void TestEnhancedMRProbablePrime() { int mrIterations = (PRIME_CERTAINTY + 1) / 2; for (int iterations = 0; iterations < ITERATIONS; ++iterations) { BigInteger prime = RandomPrime(); Primes.MROutput mr = Primes.EnhancedMRProbablePrimeTest(prime, R, mrIterations); Assert.False(mr.IsProvablyComposite); Assert.False(mr.IsNotPrimePower); Assert.Null(mr.Factor); BigInteger primePower = prime; for (int i = 0; i <= (iterations % 8); ++i) { primePower = primePower.Multiply(prime); } Primes.MROutput mr2 = Primes.EnhancedMRProbablePrimeTest(primePower, R, mrIterations); Assert.True(mr2.IsProvablyComposite); Assert.False(mr2.IsNotPrimePower); Assert.AreEqual(mr2.Factor, prime); BigInteger nonPrimePower = RandomPrime().Multiply(prime); Primes.MROutput mr3 = Primes.EnhancedMRProbablePrimeTest(nonPrimePower, R, mrIterations); Assert.True(mr3.IsProvablyComposite); Assert.True(mr3.IsNotPrimePower); Assert.Null(mr.Factor); } }
internal static BigInteger ValidatedModulus(BigInteger modulus) { // if there is already a marker for this modulus it has already been validated, or we've already loaded it with a private key. // skip the tests if (!AsymmetricRsaKey.IsAlreadySeen(modulus)) { if ((modulus.IntValue & 1) == 0) { throw new ArgumentException("RSA modulus is even"); } // the value is the product of the 132 smallest primes from 3 to 751 if (!modulus.Gcd(new BigInteger("145188775577763990151158743208307020242261438098488931355057091965" + "931517706595657435907891265414916764399268423699130577757433083166" + "651158914570105971074227669275788291575622090199821297575654322355" + "049043101306108213104080801056529374892690144291505781966373045481" + "8359472391642885328171302299245556663073719855")).Equals(BigInteger.One)) { throw new ArgumentException("RSA modulus has a small prime factor"); } // Use the same iterations as if we were testing a candidate p or q value with error probability 2^-100 int bits = modulus.BitLength; int iterations = bits >= 1536 ? 3 : bits >= 1024 ? 4 : bits >= 512 ? 7 : 50; // SP 800-89 requires use of an approved DRBG - we construct directly from base to avoid context issues SecureRandom testRandom = new FipsDrbg.Base(FipsDrbg.Sha256).FromEntropySource(new SecureRandom(), false) .Build(Pack.UInt64_To_LE((ulong)DateTime.Now.Ticks), false, Strings.ToByteArray(Thread.CurrentThread.ToString())); Primes.MROutput mr = Primes.EnhancedMRProbablePrimeTest(modulus, testRandom, iterations); if (!mr.IsProvablyComposite) { throw new ArgumentException("RSA modulus is not composite"); } if (!mr.IsNotPrimePower) { throw new ArgumentException("RSA modulus is a power of a prime"); } } // FSM_TRANS:5.10, "FIPS 186-3/SP 800-89 ASSURANCES CHECK", "CONDITIONAL TEST", "FIPS 186-3/SP 800-89 Assurances test successful" return(modulus); }