BigInteger.RabinMillerTest C# (CSharp) Method

RabinMillerTest() public method

public RabinMillerTest ( int confidence ) : bool
confidence int
return bool
        public bool RabinMillerTest(int confidence)
        {
                BigInteger thisVal;
                if((this.data[maxLength-1] & 0x80000000) != 0)        // negative
                        thisVal = -this;
                else
                        thisVal = this;

                if(thisVal.dataLength == 1)
                {
                        // test small numbers
                        if(thisVal.data[0] == 0 || thisVal.data[0] == 1)
                                return false;
                        else if(thisVal.data[0] == 2 || thisVal.data[0] == 3)
                                return true;
                }

                if((thisVal.data[0] & 0x1) == 0)     // even numbers
                        return false;


                // calculate values of s and t
                BigInteger p_sub1 = thisVal - (new BigInteger(1));
                int s = 0;

                for(int index = 0; index < p_sub1.dataLength; index++)
                {
                        uint mask = 0x01;

                        for(int i = 0; i < 32; i++)
                        {
                                if((p_sub1.data[index] & mask) != 0)
                                {
                                        index = p_sub1.dataLength;      // to break the outer loop
                                        break;
                                }
                                mask <<= 1;
                                s++;
                        }
                }

                BigInteger t = p_sub1 >> s;

	        int bits = thisVal.bitCount();
	        BigInteger a = new BigInteger();
	        Random rand = new Random();

	        for(int round = 0; round < confidence; round++)
	        {
		        bool done = false;

		        while(!done)		// generate a < n
		        {
			        int testBits = 0;

			        // make sure "a" has at least 2 bits
			        while(testBits < 2)
				        testBits = (int)(rand.NextDouble() * bits);

			        a.genRandomBits(testBits, rand);

			        int byteLen = a.dataLength;

                                // make sure "a" is not 0
			        if(byteLen > 1 || (byteLen == 1 && a.data[0] != 1))
				        done = true;
		        }

                        // check whether a factor exists (fix for version 1.03)
		        BigInteger gcdTest = a.gcd(thisVal);
                        if(gcdTest.dataLength == 1 && gcdTest.data[0] != 1)
                                return false;

                        BigInteger b = a.modPow(t, thisVal);

                        /*
                        Console.WriteLine("a = " + a.ToString(10));
                        Console.WriteLine("b = " + b.ToString(10));
                        Console.WriteLine("t = " + t.ToString(10));
                        Console.WriteLine("s = " + s);
                        */

                        bool result = false;

                        if(b.dataLength == 1 && b.data[0] == 1)         // a^t mod p = 1
                                result = true;

                        for(int j = 0; result == false && 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) % thisVal;
                        }

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

Usage Example

        internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random)
        {
            BigInteger integer;
            BigInteger integer2;
            int        num3;
            int        bitLength = size - 1;
            int        num2      = size >> 2;

            if (size <= 0x20)
            {
                while (true)
                {
                    integer2 = new BigInteger(bitLength, 2, random);
                    integer  = integer2.ShiftLeft(1).Add(BigInteger.One);
                    if (integer.IsProbablePrime(certainty, true) && ((certainty <= 2) || integer2.IsProbablePrime(certainty, true)))
                    {
                        goto Label_01B9;
                    }
                }
            }
Label_006F:
            integer2 = new BigInteger(bitLength, 0, random);
Label_0078:
            num3 = 0;
            while (num3 < primeLists.Length)
            {
                int intValue = integer2.Remainder(BigPrimeProducts[num3]).IntValue;
                if (num3 == 0)
                {
                    int num5 = intValue % 3;
                    if (num5 != 2)
                    {
                        int num6 = (2 * num5) + 2;
                        integer2 = integer2.Add(BigInteger.ValueOf((long)num6));
                        intValue = (intValue + num6) % primeProducts[num3];
                    }
                }
                foreach (int num8 in primeLists[num3])
                {
                    int num9 = intValue % num8;
                    if ((num9 == 0) || (num9 == (num8 >> 1)))
                    {
                        integer2 = integer2.Add(Six);
                        goto Label_0078;
                    }
                }
                num3++;
            }
            if ((integer2.BitLength != bitLength) || !integer2.RabinMillerTest(2, random, true))
            {
                goto Label_006F;
            }
            integer = integer2.ShiftLeft(1).Add(BigInteger.One);
            if ((!integer.RabinMillerTest(certainty, random, true) || ((certainty > 2) && !integer2.RabinMillerTest(certainty - 2, random, true))) || (WNafUtilities.GetNafWeight(integer) < num2))
            {
                goto Label_006F;
            }
Label_01B9:
            return(new BigInteger[] { integer, integer2 });
        }
All Usage Examples Of BigInteger::RabinMillerTest