Пример #1
0
        /**
         * It requires that all parameters be positive.
         *
         * @return {@code base<sup>exponent</sup> mod (2<sup>j</sup>)}.
         * @see BigInteger#modPow(BigInteger, BigInteger)
         */

        private static BigInteger Pow2ModPow(BigInteger b, BigInteger exponent, int j)
        {
            // PRE: (base > 0), (exponent > 0) and (j > 0)
            BigInteger res         = BigInteger.One;
            BigInteger e           = exponent.Copy();
            BigInteger baseMod2toN = b.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 (BigInteger.TestBit(b, 0))
            {
                InplaceModPow2(e, j - 1);
            }
            InplaceModPow2(baseMod2toN, j);

            for (int i = e.BitLength - 1; i >= 0; i--)
            {
                res2 = res.Copy();
                InplaceModPow2(res2, j);
                res = res * res2;
                if (BitLevel.TestBit(e, i))
                {
                    res = res * baseMod2toN;
                    InplaceModPow2(res, j);
                }
            }
            InplaceModPow2(res, j);
            return(res);
        }
Пример #2
0
        /*Implements the Montgomery modular exponentiation based in <i>The sliding windows algorithm and the Mongomery
         * Reduction</i>.
         *@ar.org.fitc.ref "A. Menezes,P. van Oorschot, S. Vanstone - Handbook of Applied Cryptography";
         *@see #oddModPow(BigInteger, BigInteger,
         *                           BigInteger)
         */

        private static BigInteger SlidingWindow(BigInteger x2, BigInteger a2, BigInteger exponent, BigInteger modulus, int n2)
        {
            // fill odd low pows of a2
            BigInteger[] pows = new BigInteger[8];
            BigInteger   res  = x2;
            int          lowexp;
            BigInteger   x3;
            int          acc3;

            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
        /**
         * @param x an odd positive number.
         * @param n the exponent by which 2 is raised.
         * @return {@code x<sup>-1</sup> (mod 2<sup>n</sup>)}.
         */

        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 * y, i))
                {
                    // Adding 2^i to y (setting the i-th bit)
                    y.Digits[i >> 5] |= (1 << (i & 31));
                }
            }
            return(y);
        }