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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
public static int GetWindowSize(int bits) { return(WNafUtilities.GetWindowSize(bits, WNafUtilities.DEFAULT_WINDOW_SIZE_CUTOFFS)); }
public static WNafPreCompInfo GetWNafPreCompInfo(ECPoint p) { return(WNafUtilities.GetWNafPreCompInfo(p.Curve.GetPreCompInfo(p, WNafUtilities.PRECOMP_NAME))); }
protected virtual int GetWindowSize(int bits) => WNafUtilities.GetWindowSize(bits);
protected virtual int GetWindowSize(int bits) { return(WNafUtilities.GetWindowSize(bits)); }
/** * 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); }
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); }