public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated) { ECCurve c = p.Curve; WNafPreCompInfo wnafPreCompInfo = GetWNafPreCompInfo(c.GetPreCompInfo(p)); ECPoint[] preComp = wnafPreCompInfo.PreComp; if (preComp == null) { preComp = new ECPoint[] { p }; } int preCompLen = preComp.Length; int reqPreCompLen = 1 << System.Math.Max(0, width - 2); if (preCompLen < reqPreCompLen) { ECPoint twiceP = wnafPreCompInfo.Twice; if (twiceP == null) { twiceP = preComp[0].Twice().Normalize(); wnafPreCompInfo.Twice = twiceP; } preComp = ResizeTable(preComp, reqPreCompLen); /* * TODO Okeya/Sakurai paper has precomputation trick and "Montgomery's Trick" to speed this up. * Also, co-Z arithmetic could avoid the subsequent normalization too. */ for (int i = preCompLen; i < reqPreCompLen; i++) { /* * Compute the new ECPoints for the precomputation array. The values 1, 3, 5, ..., * 2^(width-1)-1 times p are computed */ preComp[i] = twiceP.Add(preComp[i - 1]); } /* * Having oft-used operands in affine form makes operations faster. */ c.NormalizeAll(preComp); } wnafPreCompInfo.PreComp = preComp; if (includeNegated) { ECPoint[] preCompNeg = wnafPreCompInfo.PreCompNeg; int pos; if (preCompNeg == null) { pos = 0; preCompNeg = new ECPoint[reqPreCompLen]; } else { pos = preCompNeg.Length; if (pos < reqPreCompLen) { preCompNeg = ResizeTable(preCompNeg, reqPreCompLen); } } while (pos < reqPreCompLen) { preCompNeg[pos] = preComp[pos].Negate(); ++pos; } wnafPreCompInfo.PreCompNeg = preCompNeg; } c.SetPreCompInfo(p, wnafPreCompInfo); return(wnafPreCompInfo); }