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); } } }
public void GCDIsCorrectForSampleTests(int firstNumber, int secondNumber, int expectedResult) { GreatestCommonDenominator gcd = new GreatestCommonDenominator(); int value = gcd.findGCD(firstNumber, secondNumber); Assert.Equal(expectedResult, value); }
public void GCDIsOneWhenOneParameterIsOne(int firstNumber, int secondNumber) { GreatestCommonDenominator gcd = new GreatestCommonDenominator(); int value = gcd.findGCD(firstNumber, secondNumber); Assert.Equal(1, value); }
public void GCDIsFirstParameterWhenSecondParameterIsZero(int nonZeroNumber) { GreatestCommonDenominator gcd = new GreatestCommonDenominator(); int value = gcd.findGCD(nonZeroNumber, 0); Assert.Equal(nonZeroNumber, value); }
public void GCDThrowsErrorWhenGivenNonNaturalNumber(int firstNumber, int secondNumber) { GreatestCommonDenominator gcd = new GreatestCommonDenominator(); Action act = () => gcd.findGCD(firstNumber, secondNumber); Assert.Throws <ArgumentException>(act); }