コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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.m_numberLength = 1;
            y.m_digits[0]    = 1;
            y.m_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.m_digits[i >> 5] |= (1 << (i & 31));
                }
            }
            return(y);
        }