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);
                    }
                }
            }
        }
Пример #2
0
        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);
        }