コード例 #1
0
        public static byte[] GenerateJsf(BigInteger g, BigInteger h)
        {
            int num = Math.Max(g.BitLength, h.BitLength) + 1;

            byte[]     array       = new byte[num];
            BigInteger bigInteger  = g;
            BigInteger bigInteger2 = h;
            int        num2        = 0;
            int        num3        = 0;
            int        num4        = 0;
            int        num5        = 0;

            while ((num3 | num4) != 0 || bigInteger.BitLength > num5 || bigInteger2.BitLength > num5)
            {
                int num6 = (int)(((uint)bigInteger.IntValue >> num5) + (uint)num3 & 7u);
                int num7 = (int)(((uint)bigInteger2.IntValue >> num5) + (uint)num4 & 7u);
                int num8 = num6 & 1;
                if (num8 != 0)
                {
                    num8 -= (num6 & 2);
                    if (num6 + num8 == 4 && (num7 & 3) == 2)
                    {
                        num8 = -num8;
                    }
                }
                int num9 = num7 & 1;
                if (num9 != 0)
                {
                    num9 -= (num7 & 2);
                    if (num7 + num9 == 4 && (num6 & 3) == 2)
                    {
                        num9 = -num9;
                    }
                }
                if (num3 << 1 == 1 + num8)
                {
                    num3 ^= 1;
                }
                if (num4 << 1 == 1 + num9)
                {
                    num4 ^= 1;
                }
                if (++num5 == 30)
                {
                    num5        = 0;
                    bigInteger  = bigInteger.ShiftRight(30);
                    bigInteger2 = bigInteger2.ShiftRight(30);
                }
                array[num2++] = (byte)(num8 << 4 | (num9 & 15));
            }
            if (array.Length > num2)
            {
                array = WNafUtilities.Trim(array, num2);
            }
            return(array);
        }
コード例 #2
0
        public static int[] GenerateCompactWindowNaf(int width, BigInteger k)
        {
            if (width == 2)
            {
                return(WNafUtilities.GenerateCompactNaf(k));
            }
            if (width < 2 || width > 16)
            {
                throw new ArgumentException("must be in the range [2, 16]", "width");
            }
            if (k.BitLength >> 16 != 0)
            {
                throw new ArgumentException("must have bitlength < 2^16", "k");
            }
            if (k.SignValue == 0)
            {
                return(WNafUtilities.EMPTY_INTS);
            }
            int[] array = new int[k.BitLength / width + 1];
            int   num   = 1 << width;
            int   num2  = num - 1;
            int   num3  = num >> 1;
            bool  flag  = false;
            int   num4  = 0;
            int   i     = 0;

            while (i <= k.BitLength)
            {
                if (k.TestBit(i) == flag)
                {
                    i++;
                }
                else
                {
                    k = k.ShiftRight(i);
                    int num5 = k.IntValue & num2;
                    if (flag)
                    {
                        num5++;
                    }
                    flag = ((num5 & num3) != 0);
                    if (flag)
                    {
                        num5 -= num;
                    }
                    int num6 = (num4 > 0) ? (i - 1) : i;
                    array[num4++] = (num5 << 16 | num6);
                    i             = width;
                }
            }
            if (array.Length > num4)
            {
                array = WNafUtilities.Trim(array, num4);
            }
            return(array);
        }
コード例 #3
0
        public static byte[] GenerateWindowNaf(int width, BigInteger k)
        {
            if (width == 2)
            {
                return(WNafUtilities.GenerateNaf(k));
            }
            if (width < 2 || width > 8)
            {
                throw new ArgumentException("must be in the range [2, 8]", "width");
            }
            if (k.SignValue == 0)
            {
                return(WNafUtilities.EMPTY_BYTES);
            }
            byte[] array = new byte[k.BitLength + 1];
            int    num   = 1 << width;
            int    num2  = num - 1;
            int    num3  = num >> 1;
            bool   flag  = false;
            int    num4  = 0;
            int    i     = 0;

            while (i <= k.BitLength)
            {
                if (k.TestBit(i) == flag)
                {
                    i++;
                }
                else
                {
                    k = k.ShiftRight(i);
                    int num5 = k.IntValue & num2;
                    if (flag)
                    {
                        num5++;
                    }
                    flag = ((num5 & num3) != 0);
                    if (flag)
                    {
                        num5 -= num;
                    }
                    num4         += ((num4 > 0) ? (i - 1) : i);
                    array[num4++] = (byte)num5;
                    i             = width;
                }
            }
            if (array.Length > num4)
            {
                array = WNafUtilities.Trim(array, num4);
            }
            return(array);
        }
コード例 #4
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int             num             = Math.Max(2, Math.Min(16, this.GetWindowSize(k.BitLength)));
            WNafPreCompInfo wNafPreCompInfo = WNafUtilities.Precompute(p, num, true);

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

            if (i > 1)
            {
                int       num2   = array[--i];
                int       num3   = num2 >> 16;
                int       num4   = num2 & 65535;
                int       num5   = Math.Abs(num3);
                ECPoint[] array2 = (num3 < 0) ? preCompNeg : preComp;
                if (num5 << 2 < 1 << num)
                {
                    int num6  = (int)LongArray.BitLengths[num5];
                    int num7  = num - num6;
                    int num8  = num5 ^ 1 << num6 - 1;
                    int num9  = (1 << num - 1) - 1;
                    int num10 = (num8 << num7) + 1;
                    eCPoint = array2[num9 >> 1].Add(array2[num10 >> 1]);
                    num4   -= num7;
                }
                else
                {
                    eCPoint = array2[num5 >> 1];
                }
                eCPoint = eCPoint.TimesPow2(num4);
            }
            while (i > 0)
            {
                int       num11  = array[--i];
                int       num12  = num11 >> 16;
                int       e      = num11 & 65535;
                int       num13  = Math.Abs(num12);
                ECPoint[] array3 = (num12 < 0) ? preCompNeg : preComp;
                ECPoint   b      = array3[num13 >> 1];
                eCPoint = eCPoint.TwicePlus(b);
                eCPoint = eCPoint.TimesPow2(e);
            }
            return(eCPoint);
        }
コード例 #5
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int             num             = System.Math.Max(2, System.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   = System.Math.Abs(num4);
                ECPoint[] array2 = (num4 >= 0) ? preComp : preCompNeg;
                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  = System.Math.Abs(num13);
                ECPoint[] array3 = (num13 >= 0) ? preComp : preCompNeg;
                ECPoint   b      = array3[num14 >> 1];
                eCPoint = eCPoint.TwicePlus(b);
                eCPoint = eCPoint.TimesPow2(e);
            }
            return(eCPoint);
        }
コード例 #6
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int             width = Math.Max(2, Math.Min(0x10, this.GetWindowSize(k.BitLength)));
            WNafPreCompInfo info  = WNafUtilities.Precompute(p, width, true);

            ECPoint[] preComp    = info.PreComp;
            ECPoint[] preCompNeg = info.PreCompNeg;
            int[]     numArray   = WNafUtilities.GenerateCompactWindowNaf(width, k);
            ECPoint   infinity   = p.Curve.Infinity;
            int       length     = numArray.Length;

            if (length > 1)
            {
                int       num3        = numArray[--length];
                int       num4        = num3 >> 0x10;
                int       e           = num3 & 0xffff;
                int       index       = Math.Abs(num4);
                ECPoint[] pointArray3 = (num4 >= 0) ? preComp : preCompNeg;
                if ((index << 2) < (((int)1) << width))
                {
                    int num7  = LongArray.BitLengths[index];
                    int num8  = width - num7;
                    int num9  = index ^ (((int)1) << (num7 - 1));
                    int num10 = (((int)1) << (width - 1)) - 1;
                    int num11 = (num9 << num8) + 1;
                    infinity = pointArray3[num10 >> 1].Add(pointArray3[num11 >> 1]);
                    e       -= num8;
                }
                else
                {
                    infinity = pointArray3[index >> 1];
                }
                infinity = infinity.TimesPow2(e);
            }
            while (length > 0)
            {
                int       num12       = numArray[--length];
                int       num13       = num12 >> 0x10;
                int       e           = num12 & 0xffff;
                int       num15       = Math.Abs(num13);
                ECPoint[] pointArray4 = (num13 >= 0) ? preComp : preCompNeg;
                ECPoint   b           = pointArray4[num15 >> 1];
                infinity = infinity.TwicePlus(b).TimesPow2(e);
            }
            return(infinity);
        }
コード例 #7
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int[]   array    = WNafUtilities.GenerateCompactNaf(k);
            ECPoint eCPoint  = p.Normalize();
            ECPoint eCPoint2 = eCPoint.Negate();
            ECPoint eCPoint3 = p.Curve.Infinity;
            int     num      = array.Length;

            while (--num >= 0)
            {
                int num2 = array[num];
                int num3 = num2 >> 16;
                int e    = num2 & 65535;
                eCPoint3 = eCPoint3.TwicePlus((num3 < 0) ? eCPoint2 : eCPoint);
                eCPoint3 = eCPoint3.TimesPow2(e);
            }
            return(eCPoint3);
        }
コード例 #8
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int[]   array    = WNafUtilities.GenerateCompactNaf(k);
            ECPoint eCPoint  = p.Curve.Infinity;
            ECPoint eCPoint2 = p;
            int     num      = 0;

            for (int i = 0; i < array.Length; i++)
            {
                int num2 = array[i];
                int num3 = num2 >> 16;
                num     += (num2 & 65535);
                eCPoint2 = eCPoint2.TimesPow2(num);
                eCPoint  = eCPoint.Add((num3 < 0) ? eCPoint2.Negate() : eCPoint2);
                num      = 1;
            }
            return(eCPoint);
        }
コード例 #9
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int[] naf = WNafUtilities.GenerateCompactNaf(k);

            ECPoint addP = p.Normalize(), subP = addP.Negate();

            ECPoint R = p.Curve.Infinity;

            int i = naf.Length;

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

                R = R.TwicePlus(digit < 0 ? subP : addP);
                R = R.TimesPow2(zeroes);
            }

            return(R);
        }
コード例 #10
0
        public static int[] GenerateCompactNaf(BigInteger k)
        {
            if (k.BitLength >> 16 != 0)
            {
                throw new ArgumentException("must have bitlength < 2^16", "k");
            }
            if (k.SignValue == 0)
            {
                return(WNafUtilities.EMPTY_INTS);
            }
            BigInteger bigInteger = k.ShiftLeft(1).Add(k);
            int        bitLength  = bigInteger.BitLength;

            int[]      array       = new int[bitLength >> 1];
            BigInteger bigInteger2 = bigInteger.Xor(k);
            int        num         = bitLength - 1;
            int        num2        = 0;
            int        num3        = 0;

            for (int i = 1; i < num; i++)
            {
                if (!bigInteger2.TestBit(i))
                {
                    num3++;
                }
                else
                {
                    int num4 = k.TestBit(i) ? -1 : 1;
                    array[num2++] = (num4 << 16 | num3);
                    num3          = 1;
                    i++;
                }
            }
            array[num2++] = (65536 | num3);
            if (array.Length > num2)
            {
                array = WNafUtilities.Trim(array, num2);
            }
            return(array);
        }
コード例 #11
0
        protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
        {
            int[] naf = WNafUtilities.GenerateCompactNaf(k);

            ECPoint R0 = p.Curve.Infinity, R1 = p;

            int zeroes = 0;

            for (int i = 0; i < naf.Length; ++i)
            {
                int ni    = naf[i];
                int digit = ni >> 16;
                zeroes += ni & 0xFFFF;

                R1 = R1.TimesPow2(zeroes);
                R0 = R0.Add(digit < 0 ? R1.Negate() : R1);

                zeroes = 1;
            }

            return(R0);
        }
コード例 #12
0
        public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated)
        {
            ECCurve         curve           = p.Curve;
            WNafPreCompInfo wNafPreCompInfo = WNafUtilities.GetWNafPreCompInfo(curve.GetPreCompInfo(p, WNafUtilities.PRECOMP_NAME));
            int             num             = 0;
            int             num2            = 1 << Math.Max(0, width - 2);

            ECPoint[] array = wNafPreCompInfo.PreComp;
            if (array == null)
            {
                array = WNafUtilities.EMPTY_POINTS;
            }
            else
            {
                num = array.Length;
            }
            if (num < num2)
            {
                array = WNafUtilities.ResizeTable(array, num2);
                if (num2 == 1)
                {
                    array[0] = p.Normalize();
                }
                else
                {
                    int i = num;
                    if (i == 0)
                    {
                        array[0] = p;
                        i        = 1;
                    }
                    ECFieldElement eCFieldElement = null;
                    if (num2 == 2)
                    {
                        array[1] = p.ThreeTimes();
                    }
                    else
                    {
                        ECPoint eCPoint  = wNafPreCompInfo.Twice;
                        ECPoint eCPoint2 = array[i - 1];
                        if (eCPoint == null)
                        {
                            eCPoint = array[0].Twice();
                            wNafPreCompInfo.Twice = eCPoint;
                            if (ECAlgorithms.IsFpCurve(curve) && curve.FieldSize >= 64)
                            {
                                switch (curve.CoordinateSystem)
                                {
                                case 2:
                                case 3:
                                case 4:
                                {
                                    eCFieldElement = eCPoint.GetZCoord(0);
                                    eCPoint        = curve.CreatePoint(eCPoint.XCoord.ToBigInteger(), eCPoint.YCoord.ToBigInteger());
                                    ECFieldElement eCFieldElement2 = eCFieldElement.Square();
                                    ECFieldElement scale           = eCFieldElement2.Multiply(eCFieldElement);
                                    eCPoint2 = eCPoint2.ScaleX(eCFieldElement2).ScaleY(scale);
                                    if (num == 0)
                                    {
                                        array[0] = eCPoint2;
                                    }
                                    break;
                                }
                                }
                            }
                        }
                        while (i < num2)
                        {
                            eCPoint2 = (array[i++] = eCPoint2.Add(eCPoint));
                        }
                    }
                    curve.NormalizeAll(array, num, num2 - num, eCFieldElement);
                }
            }
            wNafPreCompInfo.PreComp = array;
            if (includeNegated)
            {
                ECPoint[] array2 = wNafPreCompInfo.PreCompNeg;
                int       j;
                if (array2 == null)
                {
                    j      = 0;
                    array2 = new ECPoint[num2];
                }
                else
                {
                    j = array2.Length;
                    if (j < num2)
                    {
                        array2 = WNafUtilities.ResizeTable(array2, num2);
                    }
                }
                while (j < num2)
                {
                    array2[j] = array[j].Negate();
                    j++;
                }
                wNafPreCompInfo.PreCompNeg = array2;
            }
            curve.SetPreCompInfo(p, WNafUtilities.PRECOMP_NAME, wNafPreCompInfo);
            return(wNafPreCompInfo);
        }
コード例 #13
0
 public static int GetWindowSize(int bits)
 {
     return(WNafUtilities.GetWindowSize(bits, WNafUtilities.DEFAULT_WINDOW_SIZE_CUTOFFS));
 }
コード例 #14
0
 public static WNafPreCompInfo GetWNafPreCompInfo(ECPoint p)
 {
     return(WNafUtilities.GetWNafPreCompInfo(p.Curve.GetPreCompInfo(p, WNafUtilities.PRECOMP_NAME)));
 }
コード例 #15
0
 protected virtual int GetWindowSize(int bits) =>
 WNafUtilities.GetWindowSize(bits);
コード例 #16
0
 protected virtual int GetWindowSize(int bits)
 {
     return(WNafUtilities.GetWindowSize(bits));
 }
コード例 #17
0
        /**
         * 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;

                    //Console.WriteLine("Optimized: 2^" + scale + " * " + n + " = " + i1 + " + " + i2);
                }
                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);
        }
コード例 #18
0
ファイル: WNafUtilities.cs プロジェクト: zyj0021/bc-csharp
            public PreCompInfo Precompute(PreCompInfo existing)
            {
                WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo;

                int reqPreCompLen = 1 << System.Math.Max(0, m_width - 2);

                if (CheckExisting(existingWNaf, reqPreCompLen, m_includeNegated))
                {
                    return(existingWNaf);
                }

                ECCurve c = m_p.Curve;

                ECPoint[] preComp = null, preCompNeg = null;
                ECPoint   twiceP  = null;

                if (existingWNaf != null)
                {
                    preComp    = existingWNaf.PreComp;
                    preCompNeg = existingWNaf.PreCompNeg;
                    twiceP     = existingWNaf.Twice;
                }

                int iniPreCompLen = 0;

                if (preComp == null)
                {
                    preComp = EMPTY_POINTS;
                }
                else
                {
                    iniPreCompLen = preComp.Length;
                }

                if (iniPreCompLen < reqPreCompLen)
                {
                    preComp = WNafUtilities.ResizeTable(preComp, reqPreCompLen);

                    if (reqPreCompLen == 1)
                    {
                        preComp[0] = m_p.Normalize();
                    }
                    else
                    {
                        int curPreCompLen = iniPreCompLen;
                        if (curPreCompLen == 0)
                        {
                            preComp[0]    = m_p;
                            curPreCompLen = 1;
                        }

                        ECFieldElement iso = null;

                        if (reqPreCompLen == 2)
                        {
                            preComp[1] = m_p.ThreeTimes();
                        }
                        else
                        {
                            ECPoint isoTwiceP = twiceP, last = preComp[curPreCompLen - 1];
                            if (isoTwiceP == null)
                            {
                                isoTwiceP = preComp[0].Twice();
                                twiceP    = isoTwiceP;

                                /*
                                 * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism
                                 * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This
                                 * also requires scaling the initial point's X, Y coordinates, and reversing the
                                 * isomorphism as part of the subsequent normalization.
                                 *
                                 *  NOTE: The correctness of this optimization depends on:
                                 *      1) additions do not use the curve's A, B coefficients.
                                 *      2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ...
                                 */
                                if (!twiceP.IsInfinity && ECAlgorithms.IsFpCurve(c) && c.FieldSize >= 64)
                                {
                                    switch (c.CoordinateSystem)
                                    {
                                    case ECCurve.COORD_JACOBIAN:
                                    case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
                                    case ECCurve.COORD_JACOBIAN_MODIFIED:
                                    {
                                        iso       = twiceP.GetZCoord(0);
                                        isoTwiceP = c.CreatePoint(twiceP.XCoord.ToBigInteger(),
                                                                  twiceP.YCoord.ToBigInteger());

                                        ECFieldElement iso2 = iso.Square(), iso3 = iso2.Multiply(iso);
                                        last = last.ScaleX(iso2).ScaleY(iso3);

                                        if (iniPreCompLen == 0)
                                        {
                                            preComp[0] = last;
                                        }
                                        break;
                                    }
                                    }
                                }
                            }

                            while (curPreCompLen < reqPreCompLen)
                            {
                                /*
                                 * Compute the new ECPoints for the precomputation array. The values 1, 3,
                                 * 5, ..., 2^(width-1)-1 times p are computed
                                 */
                                preComp[curPreCompLen++] = last = last.Add(isoTwiceP);
                            }
                        }

                        /*
                         * Having oft-used operands in affine form makes operations faster.
                         */
                        c.NormalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso);
                    }
                }

                if (m_includeNegated)
                {
                    int pos;
                    if (preCompNeg == null)
                    {
                        pos        = 0;
                        preCompNeg = new ECPoint[reqPreCompLen];
                    }
                    else
                    {
                        pos = preCompNeg.Length;
                        if (pos < reqPreCompLen)
                        {
                            preCompNeg = WNafUtilities.ResizeTable(preCompNeg, reqPreCompLen);
                        }
                    }

                    while (pos < reqPreCompLen)
                    {
                        preCompNeg[pos] = preComp[pos].Negate();
                        ++pos;
                    }
                }

                WNafPreCompInfo result = new WNafPreCompInfo();

                result.PreComp    = preComp;
                result.PreCompNeg = preCompNeg;
                result.Twice      = twiceP;
                return(result);
            }