Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        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);
        }