public void PositiveModuloShouldAlwaysBePositive() { var rand = new Random800_90(); for (var i = 0; i < 100; i++) { var a = rand.GetRandomBigInteger(BigInteger.Pow(2, 1024)); var b = rand.GetRandomBigInteger(BigInteger.Pow(2, 1024) + 1, BigInteger.Pow(2, 2048)); var c = rand.GetRandomBigInteger(BigInteger.Pow(2, 2048)); // b is always greater than a var result = (a - b).PosMod(c); var negativeResult = (a - b) % c; Assert.GreaterOrEqual(result, BigInteger.Zero); // result - negativeResult should be a multiple of c. Assert.AreEqual(BigInteger.Zero, (result + BigInteger.Abs(negativeResult)) % c); } }
/// <summary> /// C.3.1 Probabilistic Primality Check, Miller-Rabin Algorithm /// </summary> /// <param name="n">Number</param> /// <param name="k">Iterations</param> /// <returns>True if probably prime. False if composite.</returns> public static bool MillerRabin(BigInteger n, int k) { if (n < 2) { return(false); } if (n.IsEven) { return(false); } var s = n - 1; while (s.IsEven) { s >>= 1; } var rand = new Random800_90(); for (var i = 0; i < k; i++) { var a = rand.GetRandomBigInteger(n - 1) + 1; var temp = s; var mod = BigInteger.ModPow(a, temp, n); while (temp != n - 1 && mod != 1 && mod != n - 1) { mod = (mod * mod) % n; temp = temp * 2; } if (mod != n - 1 && temp.IsEven) { return(false); } } return(true); }