/*
* Performs modular exponentiation using the Montgomery Reduction. It
* requires that all parameters be positive and the modulus be odd. >
*
* @see BigInteger#modPow(BigInteger, BigInteger)
* @see #monPro(BigInteger, BigInteger, BigInteger, int)
* @see #slidingWindow(BigInteger, BigInteger, BigInteger, BigInteger,
* int)
* @see #squareAndMultiply(BigInteger, BigInteger, BigInteger, BigInteger,
* int)
*/
internal static BigInteger oddModPow(BigInteger baseJ, BigInteger exponent,
BigInteger modulus)
{
// PRE: (base > 0), (exponent > 0), (modulus > 0) and (odd modulus)
int k = (modulus.numberLength << 5); // r = 2^k
// n-residue of base [base * r (mod modulus)]
BigInteger a2 = baseJ.shiftLeft(k).mod(modulus);
// n-residue of base [1 * r (mod modulus)]
BigInteger x2 = BigInteger.getPowerOfTwo(k).mod(modulus);
BigInteger res;
// Compute (modulus[0]^(-1)) (mod 2^32) for odd modulus
int n2 = calcN(modulus);
if (modulus.numberLength == 1)
{
res = squareAndMultiply(x2, a2, exponent, modulus, n2);
}
else
{
res = slidingWindow(x2, a2, exponent, modulus, n2);
}
return(monPro(res, BigInteger.ONE, modulus, n2));
}