Exemplo n.º 1
0
        public static bool SmallPrimeSppTest(BigInteger bi, ConfidenceFactor confidence)
        {
            int Rounds = GetSPPRounds(bi, confidence);

            // calculate values of s and t
            BigInteger p_sub1 = bi - 1;
            int s = p_sub1.LowestSetBit();

            BigInteger t = p_sub1 >> s;


            var mr = new BigInteger.ModulusRing(bi);

            for (int round = 0; round < Rounds; round++)
            {
                BigInteger b = mr.Pow(BigInteger.smallPrimes[round], t);

                if (b == 1) continue; // a^t mod p = 1

                bool result = false;
                for (int j = 0; j < s; j++)
                {
                    if (b == p_sub1)
                    {
                        // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1
                        result = true;
                        break;
                    }

                    b = (b*b)%bi;
                }

                if (result == false)
                    return false;
            }
            return true;
        }
Exemplo n.º 2
0
        /// <summary>
        ///     Probabilistic prime test based on Rabin-Miller's test
        /// </summary>
        /// <param name="n" type="BigInteger.BigInteger">
        ///     <para>
        ///         The number to test.
        ///     </para>
        /// </param>
        /// <param name="confidence" type="int">
        ///     <para>
        ///         The number of chosen bases. The test has at least a
        ///         1/4^confidence chance of falsely returning True.
        ///     </para>
        /// </param>
        /// <returns>
        ///     <para>
        ///         True if "this" is a strong pseudoprime to randomly chosen bases.
        ///     </para>
        ///     <para>
        ///         False if "this" is definitely NOT prime.
        ///     </para>
        /// </returns>
        public static bool RabinMillerTest(BigInteger n, ConfidenceFactor confidence)
        {
            int bits = n.BitCount();
            int t = GetSPPRounds(bits, confidence);

            // n - 1 == 2^s * r, r is odd
            BigInteger n_minus_1 = n - 1;
            int s = n_minus_1.LowestSetBit();
            BigInteger r = n_minus_1 >> s;

            var mr = new BigInteger.ModulusRing(n);

            // Applying optimization from HAC section 4.50 (base == 2)
            // not a really random base but an interesting (and speedy) one
            BigInteger y = null;
            // FIXME - optimization disable for small primes due to bug #81857
            if (n.BitCount() > 100)
                y = mr.Pow(2, r);

            // still here ? start at round 1 (round 0 was a == 2)
            for (int round = 0; round < t; round++)
            {
                if ((round > 0) || (y == null))
                {
                    BigInteger a = null;

                    // check for 2 <= a <= n - 2
                    // ...but we already did a == 2 previously as an optimization
                    do
                    {
                        a = BigInteger.GenerateRandom(bits);
                    } while ((a <= 2) && (a >= n_minus_1));

                    y = mr.Pow(a, r);
                }

                if (y == 1)
                    continue;

                for (int j = 0; ((j < s) && (y != n_minus_1)); j++)
                {
                    y = mr.Pow(y, 2);
                    if (y == 1)
                        return false;
                }

                if (y != n_minus_1)
                    return false;
            }
            return true;
        }