public static BigInteger modInverse (BigInteger bi, BigInteger modulus)
{
if (modulus.length == 1) return modInverse (bi, modulus.data [0]);
BigInteger [] p = { 0, 1 };
BigInteger [] q = new BigInteger [2]; // quotients
BigInteger [] r = { 0, 0 }; // remainders
int step = 0;
BigInteger a = modulus;
BigInteger b = bi;
ModulusRing mr = new ModulusRing (modulus);
while (b != 0) {
if (step > 1) {
BigInteger pval = mr.Difference (p [0], p [1] * q [0]);
p [0] = p [1]; p [1] = pval;
}
BigInteger [] divret = multiByteDivide (a, b);
q [0] = q [1]; q [1] = divret [0];
r [0] = r [1]; r [1] = divret [1];
a = b;
b = divret [1];
step++;
}
if (r [0] != 1)
throw (new ArithmeticException ("No inverse!"));
return mr.Difference (p [0], p [1] * q [0]);
}
#endregion