示例#1
0
        /**
         * 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());
        }
示例#2
0
        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());
        }