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)); }
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)); }
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); }
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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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); }
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); }
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); }