//Тест Соловея-Штрассена. У тебя явно здесь проблемы. public static bool SolovayStrassenTest(BigInteger num, int secureParam) { bool isPrime = true; Parallel.For(0, secureParam, (i, pls) => { BigInteger a = BIGenerator.GenerateBigInteger(num - 3) + 2; if (BigInteger.GreatestCommonDivisor(a, num) <= 1) { BigInteger mod = BigInteger.ModPow(a, (num - 1) / 2, num), jacobi = JacobiSymbol(a, num); //a^((num - 1)/2) = jacobi(a, num) (mod num) if (jacobi < 0) { jacobi += num; } if (mod == jacobi % num) { return; } isPrime = false; pls.Break(); } }); return(isPrime); }
static void Main(string[] args) { int bitSize = 256; int secureParam = 100, amountOfTests; if (!int.TryParse(args[1], out amountOfTests)) { Console.WriteLine("Please, use a file name string as the first argument " + "and the uint amount of tests as the second."); return; } using (StreamWriter wstream = new StreamWriter(args[0], false)) { long wrong = 0; DateTime start = DateTime.Now; for (uint i = 0; i < amountOfTests; i++) { BigInteger bi = BIGenerator.GeneratePrimeBigInteger(bitSize); bool fermat = IsPrimeClass.FermatTest(bi, secureParam), soloveyStrassen = IsPrimeClass.SolovayStrassenTest(bi, secureParam), millerRabin = IsPrimeClass.MillerRabinTest(bi, secureParam); if (!(fermat && soloveyStrassen && millerRabin)) { wrong++; } StringBuilder report = new StringBuilder("\n" + (i + 1).ToString() + ". Generated integer:\t" + bi.ToString() + "\n\tFermat prime test result:\t" + fermat.ToString() + "\n\tSolovey-Strassen test result:\t" + soloveyStrassen.ToString() + "\n\tMiller-Rabin test result:\t" + millerRabin.ToString()); wstream.WriteLine(report.ToString()); Console.WriteLine(report.ToString()); } StringBuilder statistics = new StringBuilder("\nTest statistics:\n\tTotal:\t" + args[1] + "\n\tCrrct:\t" + (amountOfTests - wrong).ToString() + "\n\tWrong:\t" + wrong.ToString()); wstream.WriteLine(statistics.ToString()); Console.WriteLine(statistics.ToString()); Console.WriteLine(DateTime.Now - start); } Console.ReadKey(); }
//Тест Миллера-Рабина. public static bool MillerRabinTest(BigInteger num, int secureParam) { // num = 2^s * t BigInteger t = num - 1; long s = 0; while (t % 2 == 0) { t /= 2; s++; } bool isPrime = true; Parallel.For(0, secureParam, (i, pls) => { BigInteger a = BIGenerator.GenerateBigInteger(num - 4) + 2, x = BigInteger.ModPow(a, t, num); //a = (2, num - 2) //x = a^t (mod num) if (x == 1 || x == num - 1) { return; } for (long j = 1; j < s; j++) { //x = x^2 (mod num) x = BigInteger.ModPow(x, 2, num); if (x == num - 1) { return; } } isPrime = false; pls.Break(); }); return(isPrime); }
//Вероятностный тест Ферма, основанный на малой теореме Ферма. public static bool FermatTest(BigInteger num, int secureParam) { bool isPrime = true; Parallel.For(0, secureParam, (i, pls) => { BigInteger a = BIGenerator.GenerateBigInteger(num - 4) + 2; //a^(num - 1) = 1 (mod num) if (BigInteger.ModPow(a, num - 1, num) == 1) { return; } isPrime = false; pls.Break(); }); return(isPrime); }