示例#1
0
        public static bool SmallPrimeSppTest( BigInteger bi, ConfidenceFactor confidence )
        {
            int Rounds = GetSPPRounds(bi, confidence);

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

            BigInteger t = p_sub1 >> s;


            BigInteger.ModulusRing 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^thread mod p = 1

                bool result = false;
                for ( int j = 0; j < s; j++ )
                {

                    if ( b == p_sub1 )
                    {         // a^((2^k)*thread) mod p = p-1 for some 0 <= k <= s-1
                        result = true;
                        break;
                    }

                    b = ( b * b ) % bi;
                }

                if ( result == false )
                    return false;
            }
            return true;
        }
示例#2
0
        /// <summary>
        ///     Probabilistic prime test based on Rabin-Miller's test
        /// </summary>
        /// <param name="bi" 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 bi, ConfidenceFactor confidence )
        {
            int Rounds = GetSPPRounds(bi, confidence);

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

            BigInteger t = p_sub1 >> s;

            int bits = bi.BitCount();
            BigInteger a = null;
            BigInteger.ModulusRing mr = new BigInteger.ModulusRing(bi);

            // Applying optimization from HAC section 4.50 (base == 2)
            // not a really random base but an interesting (and speedy) one
            BigInteger b = mr.Pow(2, t);
            if ( b != 1 )
            {
                bool result = false;
                for ( int j = 0; j < s; j++ )
                {
                    if ( b == p_sub1 )
                    {         // a^((2^k)*thread) mod p = p-1 for some 0 <= k <= s-1
                        result = true;
                        break;
                    }

                    b = ( b * b ) % bi;
                }
                if ( !result )
                    return false;
            }

            // still here ? start at round 1 (round 0 was a == 2)
            for ( int round = 1; round < Rounds; round++ )
            {
                while ( true )
                {                   // generate a < n
                    a = BigInteger.GenerateRandom(bits);

                    // make sure "a" is not 0 (and not 2 as we have already tested that)
                    if ( a > 2 && a < bi )
                        break;
                }

                if ( a.GCD(bi) != 1 )
                    return false;

                b = mr.Pow(a, t);

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

                bool result = false;
                for ( int j = 0; j < s; j++ )
                {

                    if ( b == p_sub1 )
                    {         // a^((2^k)*thread) mod p = p-1 for some 0 <= k <= s-1
                        result = true;
                        break;
                    }

                    b = ( b * b ) % bi;
                }

                if ( !result )
                    return false;
            }
            return true;
        }