示例#1
0
        // this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
        private BigInteger Exponential(long e, IExponential z)
        {
            if (e > 0xffffffff || e < 1)
            {
                return(One);
            }
            var result  = new BigInteger();
            var result2 = new BigInteger();
            var g       = z.Convert(this);
            var i       = NumberOfBits((int)e) - 1;

            g.CopyTo(result);
            while (--i >= 0)
            {
                z.SquareTo(result, result2);
                if ((e & (1 << i)) > 0)
                {
                    z.MultiplyTo(result2, g, result);
                }
                else
                {
                    var temp = result;
                    result  = result2;
                    result2 = temp;
                }
            }
            return(z.Revert(result));
        }
示例#2
0
        // this^e % m (HAC 14.85)
        public BigInteger ModuloPower(BigInteger e, BigInteger m)
        {
            var          i      = e.BitLength;
            var          k      = 0;
            var          result = ValueOf(1);
            IExponential z      = null;

            if (i <= 0)
            {
                return(result);
            }
            if (i < 18)
            {
                k = 1;
            }
            else if (i < 48)
            {
                k = 3;
            }
            else if (i < 144)
            {
                k = 4;
            }
            else if (i < 768)
            {
                k = 5;
            }
            else
            {
                k = 6;
            }
            if (i < 8)
            {
                z = new ClassicExponential(m);
            }
            else if (m.IsEven)
            {
                z = new BarrettExponential(m);
            }
            else
            {
                z = new MontgomeryExponential(m);
            }

            // precomputation
            var g  = new BigInteger[2];
            var n  = 3;
            var k1 = k - 1;
            var km = (1 << k) - 1;

            g[1] = z.Convert(this);
            if (k > 1)
            {
                var g2 = new BigInteger();
                z.SquareTo(g[1], g2);
                while (n <= km)
                {
                    if (n + 1 > g.Length)
                    {
                        Array.Resize(ref g, n + 1);
                    }
                    g[n] = new BigInteger();
                    z.MultiplyTo(g2, g[n - 2], g[n]);
                    n += 2;
                }
            }
            var j = e.t - 1;
            var isFirstIteration = true;
            var result2          = new BigInteger();

            i = NumberOfBits(e[j]) - 1;
            while (j >= 0)
            {
                var w = 0;
                if (i >= k1)
                {
                    w = (e[j] >> (i - k1)) & km;
                }
                else
                {
                    w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
                    if (j > 0)
                    {
                        w |= e[j - 1] >> (DB + i - k1);
                    }
                }
                n = k;
                while ((w & 1) == 0)
                {
                    w = w >> 1;
                    n--;
                }
                if ((i -= n) < 0)
                {
                    i += DB;
                    j--;
                }
                if (isFirstIteration) // ret == 1, don't bother squaring or multiplying it
                {
                    g[w].CopyTo(result);
                    isFirstIteration = false;
                }
                else
                {
                    while (n > 1)
                    {
                        z.SquareTo(result, result2);
                        z.SquareTo(result2, result);
                        n -= 2;
                    }
                    if (n > 0)
                    {
                        z.SquareTo(result, result2);
                    }
                    else
                    {
                        var temp = result;
                        result  = result2;
                        result2 = temp;
                    }
                    z.MultiplyTo(result2, g[w], result);
                }
                while (j >= 0 && (e[j] & (1 << i)) == 0)
                {
                    z.SquareTo(result, result2);
                    var temp = result;
                    result  = result2;
                    result2 = temp;
                    if (--i < 0)
                    {
                        i = DB - 1;
                        j--;
                    }
                }
            }
            return(z.Revert(result));
        }