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 BigInteger GeneratePrimeBigInteger(int bitSize) { if (bitSize <= 1) { throw new ArgumentException("Error: num of bit can't be 1 or less."); } if (bitSize <= 20) { BigInteger tempResult; bool isPrime; do { tempResult = GenerateBigInteger(BigInteger.One << bitSize) - 1; isPrime = IsPrimeClass.BasicPrimaryTest(tempResult); } while (!isPrime || tempResult == 0); return(tempResult); } BigInteger N, R, F = 2; while (F == 2 || F < 0) { F = GeneratePrimeBigInteger(bitSize / 2 - 1); } while (true) { R = GenerateBigInteger(2 * F - 1) + 1; if (BigInteger.GreatestCommonDivisor(F, 2 * R) != 1) { continue; } N = 2 * R * F + 1; if (N < 0) { continue; } bool hasDivisors = false; for (int i = 2; i < 1000 && i * i <= N; i++) { if (N % i == 0) { hasDivisors = true; break; } } if (hasDivisors) { continue; } //a = (1, N - 1) //BigInteger a = GenerateBigInteger(N - 2) + 1; BigInteger a = 2; //a^(N-1) = 1 (mod N) if (BigInteger.ModPow(a, N - 1, N) != 1) { continue; } //a^((N-1)/F) (mod N) - 1 BigInteger temp = BigInteger.ModPow(a, (N - 1) / F, N) - 1; // GCD (temp, N) if (BigInteger.GreatestCommonDivisor(temp, N) != 1) { continue; } return(N); } }