public BigInteger modInverse(BigInteger modulus)
{
BigInteger[] p = { 0, 1 };
BigInteger[] q = new BigInteger[2]; // quotients
BigInteger[] r = { 0, 0 }; // remainders
int step = 0;
BigInteger a = modulus;
BigInteger b = this;
while(b.dataLength > 1 || (b.dataLength == 1 && b.data[0] != 0))
{
BigInteger quotient = new BigInteger();
BigInteger remainder = new BigInteger();
if(step > 1)
{
BigInteger pval = (p[0] - (p[1] * q[0])) % modulus;
p[0] = p[1];
p[1] = pval;
}
if(b.dataLength == 1)
singleByteDivide(a, b, quotient, remainder);
else
multiByteDivide(a, b, quotient, remainder);
/*
Console.WriteLine(quotient.dataLength);
Console.WriteLine("{0} = {1}({2}) + {3} p = {4}", a.ToString(10),
b.ToString(10), quotient.ToString(10), remainder.ToString(10),
p[1].ToString(10));
*/
q[0] = q[1];
r[0] = r[1];
q[1] = quotient; r[1] = remainder;
a = b;
b = remainder;
step++;
}
if(r[0].dataLength > 1 || (r[0].dataLength == 1 && r[0].data[0] != 1))
throw (new ArithmeticException("No inverse!"));
BigInteger result = ((p[0] - (p[1] * q[0])) % modulus);
if((result.data[maxLength - 1] & 0x80000000) != 0)
result += modulus; // get the least positive modulus
return result;
}