private static ResizeTable ( ECPoint a, int length ) : ECPoint[] | ||
a | ECPoint | |
length | int | |
return | ECPoint[] |
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 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); }