private (int, int) factoriseWithShors(int numberToFactorise)
        {
            int a = selectRandomALessThanNGreaterThanOne(numberToFactorise);

            Console.WriteLine($"1. Selected {a} as our random value a < {numberToFactorise}");

            int gcdOfAAndN = gcd.findGCD(a, numberToFactorise);

            Console.WriteLine($"2. GCD({a}, {numberToFactorise}) = {gcdOfAAndN}");
            if (gcdOfAAndN != 1)
            {
                Console.WriteLine($"3. As GCD({a}, {numberToFactorise}) != 1, we are done");
                Console.WriteLine();
                return(gcdOfAAndN, numberToFactorise / gcdOfAAndN);
            }
            else
            {
                Console.WriteLine($"3. As GCD({a}, {numberToFactorise}) = 1, we need to continue");
                Console.WriteLine($"4. Using Quantum Period Finding to find the period of {a} ^ x mod {numberToFactorise}");

                int r = findPeriod(a, numberToFactorise);
                Console.WriteLine($"     - The period of {a} ^ x mod {numberToFactorise} is {r}");

                if (r % 2 == 1)
                {
                    Console.WriteLine($"5. Unfortunately, {a} is odd so retrying for a new value of a");
                    Console.WriteLine();
                    return(factoriseWithShors(numberToFactorise));
                }
                else if (BigInteger.ModPow(a, r / 2, numberToFactorise).Equals(numberToFactorise - 1))
                {
                    Console.WriteLine($"5. As {r} mod 2 != 1 we can continue");
                    Console.WriteLine($"6. Unfortunately, {a} ^ ({r} / 2) mod {numberToFactorise} = -1 so retrying for a new value of a");
                    Console.WriteLine();
                    return(factoriseWithShors(numberToFactorise));
                }
                else
                {
                    Console.WriteLine($"5. As {r} is even we can continue");
                    Console.WriteLine($"6. As {a} ^ ({r} / 2) mod {numberToFactorise} != -1 we can continue");
                    Console.WriteLine($"7. The factors of {numberToFactorise} are therefore GCD({a} ^ ({r} / 2) + 1, {numberToFactorise}) and GCD({a} ^ ({r} / 2) - 1, {numberToFactorise})");
                    Console.WriteLine();
                    int factor1 = (int)BigInteger.GreatestCommonDivisor(BigInteger.Subtract(BigInteger.ModPow(a, r / 2, numberToFactorise), 1), numberToFactorise);
                    int factor2 = (int)BigInteger.GreatestCommonDivisor(BigInteger.Add(BigInteger.ModPow(a, r / 2, numberToFactorise), 1), numberToFactorise);
                    return(factor1, factor2);
                }
            }
        }
Exemple #2
0
        public void GCDIsCorrectForSampleTests(int firstNumber, int secondNumber, int expectedResult)
        {
            GreatestCommonDenominator gcd = new GreatestCommonDenominator();
            int value = gcd.findGCD(firstNumber, secondNumber);

            Assert.Equal(expectedResult, value);
        }
Exemple #3
0
        public void GCDIsOneWhenOneParameterIsOne(int firstNumber, int secondNumber)
        {
            GreatestCommonDenominator gcd = new GreatestCommonDenominator();
            int value = gcd.findGCD(firstNumber, secondNumber);

            Assert.Equal(1, value);
        }
Exemple #4
0
        public void GCDIsFirstParameterWhenSecondParameterIsZero(int nonZeroNumber)
        {
            GreatestCommonDenominator gcd = new GreatestCommonDenominator();
            int value = gcd.findGCD(nonZeroNumber, 0);

            Assert.Equal(nonZeroNumber, value);
        }
Exemple #5
0
        public void GCDThrowsErrorWhenGivenNonNaturalNumber(int firstNumber, int secondNumber)
        {
            GreatestCommonDenominator gcd = new GreatestCommonDenominator();
            Action act = () => gcd.findGCD(firstNumber, secondNumber);

            Assert.Throws <ArgumentException>(act);
        }