private static BigInteger Pow2ModPow(BigInteger X, BigInteger Y, int N) { // PRE: (base > 0), (exponent > 0) and (j > 0) BigInteger res = BigInteger.One; BigInteger e = Y.Copy(); BigInteger baseMod2toN = X.Copy(); BigInteger res2; // If 'base' is odd then it's coprime with 2^j and phi(2^j) = 2^(j-1); // so we can reduce reduce the exponent (mod 2^(j-1)). if (X.TestBit(0)) { InplaceModPow2(e, N - 1); } InplaceModPow2(baseMod2toN, N); for (int i = e.BitLength - 1; i >= 0; i--) { res2 = res.Copy(); InplaceModPow2(res2, N); res = res.Multiply(res2); if (BitLevel.TestBit(e, i)) { res = res.Multiply(baseMod2toN); InplaceModPow2(res, N); } } InplaceModPow2(res, N); return(res); }
private static BigInteger SlidingWindow(BigInteger X2, BigInteger A2, BigInteger Exponent, BigInteger Modulus, int N2) { // Implements the Montgomery modular exponentiation based in The sliding windows algorithm and the Mongomery Reduction // ar.org.fitc.ref "A. Menezes,P. van Oorschot, S. Vanstone - Handbook of Applied Cryptography" BigInteger[] pows = new BigInteger[8]; BigInteger res = X2; int lowexp; BigInteger x3; int acc3; // fill odd low pows of a2 pows[0] = A2; x3 = MonPro(A2, A2, Modulus, N2); for (int i = 1; i <= 7; i++) { pows[i] = MonPro(pows[i - 1], x3, Modulus, N2); } for (int i = Exponent.BitLength - 1; i >= 0; i--) { if (BitLevel.TestBit(Exponent, i)) { lowexp = 1; acc3 = i; for (int j = System.Math.Max(i - 3, 0); j <= i - 1; j++) { if (BitLevel.TestBit(Exponent, j)) { if (j < acc3) { acc3 = j; lowexp = (lowexp << (i - j)) ^ 1; } else { lowexp = lowexp ^ (1 << (j - acc3)); } } } for (int j = acc3; j <= i; j++) { res = MonPro(res, res, Modulus, N2); } res = MonPro(pows[(lowexp - 1) >> 1], res, Modulus, N2); i = acc3; } else { res = MonPro(res, res, Modulus, N2); } } return(res); }
private static BigInteger SquareAndMultiply(BigInteger X2, BigInteger A2, BigInteger Exponent, BigInteger Modulus, int N2) { BigInteger res = X2; for (int i = Exponent.BitLength - 1; i >= 0; i--) { res = MonPro(res, res, Modulus, N2); if (BitLevel.TestBit(Exponent, i)) { res = MonPro(res, A2, Modulus, N2); } } return(res); }
private static BigInteger ModPow2Inverse(BigInteger X, int N) { // PRE: (x > 0), (x is odd), and (n > 0) BigInteger y = new BigInteger(1, new int[1 << N]); y._numberLength = 1; y._digits[0] = 1; y._sign = 1; for (int i = 1; i < N; i++) { if (BitLevel.TestBit(X.Multiply(y), i)) { // Adding 2^i to y (setting the i-th bit) y._digits[i >> 5] |= (1 << (i & 31)); } } return(y); }