예제 #1
0
        internal static ECPoint ImplSumOfMultiplies(ECEndomorphism endomorphism, ECPoint[] ps, BigInteger[] ks)
        {
            int halfCount = ps.Length, fullCount = halfCount << 1;

            bool[]            negs  = new bool[fullCount];
            WNafPreCompInfo[] infos = new WNafPreCompInfo[fullCount];
            byte[][]          wnafs = new byte[fullCount][];

            ECPointMap pointMap = endomorphism.PointMap;

            for (int i = 0; i < halfCount; ++i)
            {
                int j0 = i << 1, j1 = j0 + 1;

                BigInteger kj0 = ks[j0]; negs[j0] = kj0.SignValue < 0; kj0 = kj0.Abs();
                BigInteger kj1 = ks[j1]; negs[j1] = kj1.SignValue < 0; kj1 = kj1.Abs();

                int minWidth = WNafUtilities.GetWindowSize(System.Math.Max(kj0.BitLength, kj1.BitLength), 8);

                ECPoint         P     = ps[i];
                WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidth, true);
                ECPoint         Q     = EndoUtilities.MapPoint(endomorphism, P);
                WNafPreCompInfo infoQ = WNafUtilities.PrecomputeWithPointMap(Q, pointMap, infoP, true);

                int widthP = System.Math.Min(8, infoP.Width);
                int widthQ = System.Math.Min(8, infoQ.Width);

                infos[j0] = infoP;
                infos[j1] = infoQ;
                wnafs[j0] = WNafUtilities.GenerateWindowNaf(widthP, kj0);
                wnafs[j1] = WNafUtilities.GenerateWindowNaf(widthQ, kj1);
            }

            return(ImplSumOfMultiplies(negs, infos, wnafs));
        }
예제 #2
0
        internal static ECPoint ImplShamirsTrickWNaf(ECEndomorphism endomorphism, ECPoint P, BigInteger k, BigInteger l)
        {
            bool negK = k.SignValue < 0, negL = l.SignValue < 0;

            k = k.Abs();
            l = l.Abs();

            int minWidth = WNafUtilities.GetWindowSize(System.Math.Max(k.BitLength, l.BitLength), 8);

            WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidth, true);
            ECPoint         Q     = EndoUtilities.MapPoint(endomorphism, P);
            WNafPreCompInfo infoQ = WNafUtilities.PrecomputeWithPointMap(Q, endomorphism.PointMap, infoP, true);

            int widthP = System.Math.Min(8, infoP.Width);
            int widthQ = System.Math.Min(8, infoQ.Width);

            ECPoint[] preCompP    = negK ? infoP.PreCompNeg : infoP.PreComp;
            ECPoint[] preCompQ    = negL ? infoQ.PreCompNeg : infoQ.PreComp;
            ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg;
            ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg;

            byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, k);
            byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, l);

            return(ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ));
        }
예제 #3
0
    protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
    {
        int             num             = Math.Max(2, Math.Min(16, GetWindowSize(k.BitLength)));
        WNafPreCompInfo wNafPreCompInfo = WNafUtilities.Precompute(p, num, includeNegated: true);

        ECPoint[] preComp    = wNafPreCompInfo.PreComp;
        ECPoint[] preCompNeg = wNafPreCompInfo.PreCompNeg;
        int[]     array      = WNafUtilities.GenerateCompactWindowNaf(num, k);
        ECPoint   eCPoint    = p.Curve.Infinity;
        int       num2       = array.Length;

        if (num2 > 1)
        {
            int       num3   = array[--num2];
            int       num4   = num3 >> 16;
            int       num5   = num3 & 0xFFFF;
            int       num6   = Math.Abs(num4);
            ECPoint[] array2 = (num4 < 0) ? preCompNeg : preComp;
            if (num6 << 2 < 1 << num)
            {
                int num7  = LongArray.BitLengths[num6];
                int num8  = num - num7;
                int num9  = num6 ^ (1 << num7 - 1);
                int num10 = (1 << num - 1) - 1;
                int num11 = (num9 << num8) + 1;
                eCPoint = array2[num10 >> 1].Add(array2[num11 >> 1]);
                num5   -= num8;
            }
            else
            {
                eCPoint = array2[num6 >> 1];
            }
            eCPoint = eCPoint.TimesPow2(num5);
        }
        while (num2 > 0)
        {
            int       num12  = array[--num2];
            int       num13  = num12 >> 16;
            int       e      = num12 & 0xFFFF;
            int       num14  = Math.Abs(num13);
            ECPoint[] array3 = (num13 < 0) ? preCompNeg : preComp;
            ECPoint   b      = array3[num14 >> 1];
            eCPoint = eCPoint.TwicePlus(b);
            eCPoint = eCPoint.TimesPow2(e);
        }
        return(eCPoint);
    }
예제 #4
0
        internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
        {
            int length = ps.Length;

            bool[]            negs  = new bool[length];
            WNafPreCompInfo[] infos = new WNafPreCompInfo[length];
            byte[][]          wnafs = new byte[length][];
            for (int i = 0; i < length; i++)
            {
                BigInteger k = ks[i];
                negs[i] = k.SignValue < 0;
                k       = k.Abs();
                int width = Math.Max(2, Math.Min(0x10, WNafUtilities.GetWindowSize(k.BitLength)));
                infos[i] = WNafUtilities.Precompute(ps[i], width, true);
                wnafs[i] = WNafUtilities.GenerateWindowNaf(width, k);
            }
            return(ImplSumOfMultiplies(negs, infos, wnafs));
        }
예제 #5
0
    internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
    {
        int num = ps.Length;

        bool[]            array  = new bool[num];
        WNafPreCompInfo[] array2 = new WNafPreCompInfo[num];
        byte[][]          array3 = new byte[num][];
        for (int i = 0; i < num; i++)
        {
            BigInteger bigInteger = ks[i];
            array[i]   = (bigInteger.SignValue < 0);
            bigInteger = bigInteger.Abs();
            int width = Math.Max(2, Math.Min(16, WNafUtilities.GetWindowSize(bigInteger.BitLength)));
            array2[i] = WNafUtilities.Precompute(ps[i], width, includeNegated: true);
            array3[i] = WNafUtilities.GenerateWindowNaf(width, bigInteger);
        }
        return(ImplSumOfMultiplies(array, array2, array3));
    }
예제 #6
0
        internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
        {
            int count = ps.Length;

            bool[]            negs  = new bool[count];
            WNafPreCompInfo[] infos = new WNafPreCompInfo[count];
            byte[][]          wnafs = new byte[count][];

            for (int i = 0; i < count; ++i)
            {
                BigInteger ki = ks[i]; negs[i] = ki.SignValue < 0; ki = ki.Abs();

                int width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(ki.BitLength)));
                infos[i] = WNafUtilities.Precompute(ps[i], width, true);
                wnafs[i] = WNafUtilities.GenerateWindowNaf(width, ki);
            }

            return(ImplSumOfMultiplies(negs, infos, wnafs));
        }
예제 #7
0
        internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l)
        {
            bool flag  = k.SignValue < 0;
            bool flag2 = l.SignValue < 0;

            k = k.Abs();
            l = l.Abs();
            int             width = Math.Max(2, Math.Min(0x10, WNafUtilities.GetWindowSize(k.BitLength)));
            int             num2  = Math.Max(2, Math.Min(0x10, WNafUtilities.GetWindowSize(l.BitLength)));
            WNafPreCompInfo info  = WNafUtilities.Precompute(P, width, true);
            WNafPreCompInfo info2 = WNafUtilities.Precompute(Q, num2, true);

            ECPoint[] preCompP    = !flag ? info.PreComp : info.PreCompNeg;
            ECPoint[] preCompQ    = !flag2 ? info2.PreComp : info2.PreCompNeg;
            ECPoint[] preCompNegP = !flag ? info.PreCompNeg : info.PreComp;
            ECPoint[] preCompNegQ = !flag2 ? info2.PreCompNeg : info2.PreComp;
            byte[]    wnafP       = WNafUtilities.GenerateWindowNaf(width, k);
            byte[]    wnafQ       = WNafUtilities.GenerateWindowNaf(num2, l);
            return(ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ));
        }
예제 #8
0
        internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l)
        {
            bool flag  = k.SignValue < 0;
            bool flag2 = l.SignValue < 0;

            k = k.Abs();
            l = l.Abs();
            int             width            = Math.Max(2, Math.Min(16, WNafUtilities.GetWindowSize(k.BitLength)));
            int             width2           = Math.Max(2, Math.Min(16, WNafUtilities.GetWindowSize(l.BitLength)));
            WNafPreCompInfo wNafPreCompInfo  = WNafUtilities.Precompute(P, width, includeNegated: true);
            WNafPreCompInfo wNafPreCompInfo2 = WNafUtilities.Precompute(Q, width2, includeNegated: true);

            ECPoint[] preCompP    = (flag ? wNafPreCompInfo.PreCompNeg : wNafPreCompInfo.PreComp);
            ECPoint[] preCompQ    = (flag2 ? wNafPreCompInfo2.PreCompNeg : wNafPreCompInfo2.PreComp);
            ECPoint[] preCompNegP = (flag ? wNafPreCompInfo.PreComp : wNafPreCompInfo.PreCompNeg);
            ECPoint[] preCompNegQ = (flag2 ? wNafPreCompInfo2.PreComp : wNafPreCompInfo2.PreCompNeg);
            byte[]    wnafP       = WNafUtilities.GenerateWindowNaf(width, k);
            byte[]    wnafQ       = WNafUtilities.GenerateWindowNaf(width2, l);
            return(ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ));
        }
예제 #9
0
        internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k,
                                                     ECPoint Q, BigInteger l)
        {
            bool negK = k.SignValue < 0, negL = l.SignValue < 0;

            BigInteger kAbs = k.Abs(), lAbs = l.Abs();

            int minWidthP = WNafUtilities.GetWindowSize(kAbs.BitLength, 8);
            int minWidthQ = WNafUtilities.GetWindowSize(lAbs.BitLength, 8);

            WNafPreCompInfo infoP = WNafUtilities.Precompute(P, minWidthP, true);
            WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, minWidthQ, true);

            // When P, Q are 'promoted' (i.e. reused several times), switch to fixed-point algorithm
            {
                ECCurve c        = P.Curve;
                int     combSize = FixedPointUtilities.GetCombSize(c);
                if (!negK && !negL &&
                    k.BitLength <= combSize && l.BitLength <= combSize &&
                    infoP.IsPromoted && infoQ.IsPromoted)
                {
                    return(ImplShamirsTrickFixedPoint(P, k, Q, l));
                }
            }

            int widthP = System.Math.Min(8, infoP.Width);
            int widthQ = System.Math.Min(8, infoQ.Width);

            ECPoint[] preCompP    = negK ? infoP.PreCompNeg : infoP.PreComp;
            ECPoint[] preCompQ    = negL ? infoQ.PreCompNeg : infoQ.PreComp;
            ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg;
            ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg;

            byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, kAbs);
            byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, lAbs);

            return(ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ));
        }
예제 #10
0
        internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k,
                                                     ECPoint Q, BigInteger l)
        {
            bool negK = k.SignValue < 0, negL = l.SignValue < 0;

            k = k.Abs();
            l = l.Abs();

            int widthP = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(k.BitLength)));
            int widthQ = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(l.BitLength)));

            WNafPreCompInfo infoP = WNafUtilities.Precompute(P, widthP, true);
            WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, widthQ, true);

            ECPoint[] preCompP    = negK ? infoP.PreCompNeg : infoP.PreComp;
            ECPoint[] preCompQ    = negL ? infoQ.PreCompNeg : infoQ.PreComp;
            ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg;
            ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg;

            byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, k);
            byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, l);

            return(ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ));
        }
        /**
         * Multiplies <code>this</code> by an integer <code>k</code> using the
         * Window NAF method.
         * @param k The integer by which <code>this</code> is multiplied.
         * @return A new <code>ECPoint</code> which equals <code>this</code>
         * multiplied by <code>k</code>.
         */
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            // Clamp the window width in the range [2, 16]
            int width = System.Math.Max(2, System.Math.Min(16, GetWindowSize(k.BitLength)));

            WNafPreCompInfo wnafPreCompInfo = WNafUtilities.Precompute(p, width, true);

            ECPoint[] preComp    = wnafPreCompInfo.PreComp;
            ECPoint[] preCompNeg = wnafPreCompInfo.PreCompNeg;

            int[] wnaf = WNafUtilities.GenerateCompactWindowNaf(width, k);

            ECPoint R = p.Curve.Infinity;

            int i = wnaf.Length;

            /*
             * NOTE: We try to optimize the first window using the precomputed points to substitute an
             * addition for 2 or more doublings.
             */
            if (i > 1)
            {
                int wi = wnaf[--i];
                int digit = wi >> 16, zeroes = wi & 0xFFFF;

                int       n     = System.Math.Abs(digit);
                ECPoint[] table = digit < 0 ? preCompNeg : preComp;

                // Optimization can only be used for values in the lower half of the table
                if ((n << 2) < (1 << width))
                {
                    int highest = LongArray.BitLengths[n];

                    // TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting?
                    int scale   = width - highest;
                    int lowBits = n ^ (1 << (highest - 1));

                    int i1 = ((1 << (width - 1)) - 1);
                    int i2 = (lowBits << scale) + 1;
                    R = table[i1 >> 1].Add(table[i2 >> 1]);

                    zeroes -= scale;
                }
                else
                {
                    R = table[n >> 1];
                }

                R = R.TimesPow2(zeroes);
            }

            while (i > 0)
            {
                int wi = wnaf[--i];
                int digit = wi >> 16, zeroes = wi & 0xFFFF;

                int       n     = System.Math.Abs(digit);
                ECPoint[] table = digit < 0 ? preCompNeg : preComp;
                ECPoint   r     = table[n >> 1];

                R = R.TwicePlus(r);
                R = R.TimesPow2(zeroes);
            }

            return(R);
        }
예제 #12
0
        internal static ECPoint ImplSumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
        {
            int count = ps.Length;

            int[]             widths = new int[count];
            WNafPreCompInfo[] infos  = new WNafPreCompInfo[count];
            byte[][]          wnafs  = new byte[count][];

            int len = 0;

            for (int i = 0; i < count; ++i)
            {
                widths[i] = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(ks[i].BitLength)));
                infos[i]  = WNafUtilities.Precompute(ps[i], widths[i], true);
                wnafs[i]  = WNafUtilities.GenerateWindowNaf(widths[i], ks[i]);
                len       = System.Math.Max(len, wnafs[i].Length);
            }

            ECCurve curve    = ps[0].Curve;
            ECPoint infinity = curve.Infinity;

            ECPoint R      = infinity;
            int     zeroes = 0;

            for (int i = len - 1; i >= 0; --i)
            {
                ECPoint r = infinity;

                for (int j = 0; j < count; ++j)
                {
                    byte[] wnaf = wnafs[j];
                    int    wi   = i < wnaf.Length ? (int)(sbyte)wnaf[i] : 0;
                    if (wi != 0)
                    {
                        int             n     = System.Math.Abs(wi);
                        WNafPreCompInfo info  = infos[j];
                        ECPoint[]       table = wi < 0 ? info.PreCompNeg : info.PreComp;
                        r = r.Add(table[n >> 1]);
                    }
                }

                if (r == infinity)
                {
                    ++zeroes;
                    continue;
                }

                if (zeroes > 0)
                {
                    R      = R.TimesPow2(zeroes);
                    zeroes = 0;
                }

                R = R.TwicePlus(r);
            }

            if (zeroes > 0)
            {
                R = R.TimesPow2(zeroes);
            }

            return(R);
        }
예제 #13
0
        internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l)
        {
            int widthP = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(k.BitLength)));
            int widthQ = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(l.BitLength)));

            WNafPreCompInfo infoP = WNafUtilities.Precompute(P, widthP, true);
            WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, widthQ, true);

            ECPoint[] preCompP    = infoP.PreComp;
            ECPoint[] preCompQ    = infoQ.PreComp;
            ECPoint[] preCompNegP = infoP.PreCompNeg;
            ECPoint[] preCompNegQ = infoQ.PreCompNeg;

            byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, k);
            byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, l);

            int len = System.Math.Max(wnafP.Length, wnafQ.Length);

            ECCurve curve    = P.Curve;
            ECPoint infinity = curve.Infinity;

            ECPoint R      = infinity;
            int     zeroes = 0;

            for (int i = len - 1; i >= 0; --i)
            {
                int wiP = i < wnafP.Length ? (int)(sbyte)wnafP[i] : 0;
                int wiQ = i < wnafQ.Length ? (int)(sbyte)wnafQ[i] : 0;

                if ((wiP | wiQ) == 0)
                {
                    ++zeroes;
                    continue;
                }

                ECPoint r = infinity;
                if (wiP != 0)
                {
                    int       nP     = System.Math.Abs(wiP);
                    ECPoint[] tableP = wiP < 0 ? preCompNegP : preCompP;
                    r = r.Add(tableP[nP >> 1]);
                }
                if (wiQ != 0)
                {
                    int       nQ     = System.Math.Abs(wiQ);
                    ECPoint[] tableQ = wiQ < 0 ? preCompNegQ : preCompQ;
                    r = r.Add(tableQ[nQ >> 1]);
                }

                if (zeroes > 0)
                {
                    R      = R.TimesPow2(zeroes);
                    zeroes = 0;
                }

                R = R.TwicePlus(r);
            }

            if (zeroes > 0)
            {
                R = R.TimesPow2(zeroes);
            }

            return(R);
        }