public void MmodInverseBigInteger() { BigInteger a = zero, mod, inv; for (int j = 3; j < 50; j++) { mod = BigInteger.FromInt64(j); for (int i = -j + 1; i < j; i++) { try { a = BigInteger.FromInt64(i); inv = BigMath.ModInverse(a, mod); Assert.True(one.Equals(((a * inv) % mod)), "bad inverse: " + a + " inv mod " + mod + " equals " + inv); Assert.True(inv.CompareTo(mod) < 0, "inverse greater than modulo: " + a + " inv mod " + mod + " equals " + inv); Assert.True(inv.CompareTo(BigInteger.Zero) >= 0, "inverse less than zero: " + a + " inv mod " + mod + " equals " + inv); } catch (ArithmeticException) { Assert.True(!one.Equals(BigMath.Gcd(a, mod)), "should have found inverse for " + a + " mod " + mod); } } } for (int j = 1; j < 10; j++) { mod = bi2 + BigInteger.FromInt64(j); for (int i = 0; i < 20; i++) { try { a = bi3 + (BigInteger.FromInt64(i)); inv = BigMath.ModInverse(a, mod); Assert.True(one.Equals((a * inv) % mod), "bad inverse: " + a + " inv mod " + mod + " equals " + inv); Assert.True(inv.CompareTo(mod) < 0, "inverse greater than modulo: " + a + " inv mod " + mod + " equals " + inv); Assert.True(inv.CompareTo(BigInteger.Zero) >= 0, "inverse less than zero: " + a + " inv mod " + mod + " equals " + inv); } catch (ArithmeticException) { Assert.True(!one.Equals(BigMath.Gcd(a, mod)), "should have found inverse for " + a + " mod " + mod); } } } }
public static BigInteger ModPow(BigInteger value, BigInteger exponent, BigInteger m) { if (m.Sign <= 0) { // math.18=BigInteger: modulus not positive throw new ArithmeticException(Messages.math18); //$NON-NLS-1$ } BigInteger b = value; if (m.IsOne | (exponent.Sign > 0 & b.Sign == 0)) { return(BigInteger.Zero); } if (b.Sign == 0 && exponent.Sign == 0) { return(BigInteger.One); } if (exponent.Sign < 0) { b = BigMath.ModInverse(value, m); exponent = -exponent; } // From now on: (m > 0) and (exponent >= 0) BigInteger res = (BigInteger.TestBit(m, 0)) ? Division.OddModPow(Abs(b), exponent, m) : Division.EvenModPow(Abs(b), exponent, m); if ((b.Sign < 0) && BigInteger.TestBit(exponent, 0)) { // -b^e mod m == ((-1 mod m) * (b^e mod m)) mod m res = ((m - BigInteger.One) * res) % m; } // else exponent is even, so base^exp is positive return(res); }