# < Summary

Information

Class: | Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier.WNafUtilities
Assembly: | Renci.SshNet
File(s): | \home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafUtilities.cs

Line coverage
42%

Covered lines: | 159
Uncovered lines: | 218
Coverable lines: | 377
Total lines: | 579
Line coverage: | 42.1%

Branch coverage
34%

Covered branches: | 50
Total branches: | 146
Branch coverage: | 34.2%

Method coverage

Feature is only available for sponsors

Upgrade to PRO version

# Metrics

Method | Branch coverage | Cyclomatic complexity | Line coverage
--- | --- | --- | ---
.cctor() | 100% | 1 | 100%
GenerateCompactNaf(...) | 0% | 12 | 0%
GenerateCompactWindowNaf(...) | 77.27% | 22 | 88.37%
GenerateJsf(...) | 0% | 26 | 0%
GenerateNaf(...) | 0% | 8 | 0%
GenerateWindowNaf(...) | 0% | 20 | 0%
GetNafWeight(...) | 50% | 2 | 85.71%
GetWNafPreCompInfo(...) | 100% | 1 | 0%
GetWNafPreCompInfo(...) | 100% | 1 | 0%
GetWindowSize(...) | 100% | 1 | 100%
GetWindowSize(...) | 100% | 4 | 100%
MapPointWithPrecomp(...) | 100% | 1 | 0%
Precompute(...) | 100% | 1 | 100%
Trim(...) | 100% | 1 | 0%
Trim(...) | 100% | 1 | 100%
ResizeTable(...) | 100% | 1 | 100%
.ctor(...) | 100% | 1 | 0%
Precompute(...) | 0% | 8 | 0%
.ctor(...) | 100% | 1 | 100%
Precompute(...) | 72.22% | 36 | 77.31%
CheckExisting(...) | 33.33% | 6 | 100%
CheckTable(...) | 0% | 2 | 0%

# File(s)

## \home\appveyor\projects\ssh-net\src\Renci.SshNet\Security\BouncyCastle\math\ec\multiplier\WNafUtilities.cs

| # | Line |  | Line coverage
--- | --- | --- | --- | ---
|  | `1` |  | `using System;`
|  | `2` |  | ``
|  | `3` |  | `using Renci.SshNet.Security.Org.BouncyCastle.Utilities;`
|  | `4` |  | ``
|  | `5` |  | `namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier`
|  | `6` |  | `{`
|  | `7` |  | `internal abstract class WNafUtilities`
|  | `8` |  | `{`
| 1 | `9` |  | `public static readonly string PRECOMP_NAME = "bc_wnaf";`
|  | `10` |  | ``
| 1 | `11` |  | `private static readonly int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{ 13, 41, 121, 337, 897, 2305 };`
|  | `12` |  | ``
| 1 | `13` |  | `private static readonly ECPoint[] EMPTY_POINTS = new ECPoint[0];`
|  | `14` |  | ``
|  | `15` |  | `public static int[] GenerateCompactNaf(BigInteger k)`
| 0 | `16` |  | `{`
| 0 | `17` |  | `if ((k.BitLength >> 16) != 0)`
| 0 | `18` |  | `throw new ArgumentException("must have bitlength < 2^16", "k");`
| 0 | `19` |  | `if (k.SignValue == 0)`
| 0 | `20` |  | `return Arrays.EmptyInts;`
|  | `21` |  | ``
| 0 | `22` |  | `BigInteger _3k = k.ShiftLeft(1).Add(k);`
|  | `23` |  | ``
| 0 | `24` |  | `int bits = _3k.BitLength;`
| 0 | `25` |  | `int[] naf = new int[bits >> 1];`
|  | `26` |  | ``
| 0 | `27` |  | `BigInteger diff = _3k.Xor(k);`
|  | `28` |  | ``
| 0 | `29` |  | `int highBit = bits - 1, length = 0, zeroes = 0;`
| 0 | `30` |  | `for (int i = 1; i < highBit; ++i)`
| 0 | `31` |  | `{`
| 0 | `32` |  | `if (!diff.TestBit(i))`
| 0 | `33` |  | `{`
| 0 | `34` |  | `++zeroes;`
| 0 | `35` |  | `continue;`
|  | `36` |  | `}`
|  | `37` |  | ``
| 0 | `38` |  | `int digit = k.TestBit(i) ? -1 : 1;`
| 0 | `39` |  | `naf[length++] = (digit << 16) | zeroes;`
| 0 | `40` |  | `zeroes = 1;`
| 0 | `41` |  | `++i;`
| 0 | `42` |  | `}`
|  | `43` |  | ``
| 0 | `44` |  | `naf[length++] = (1 << 16) | zeroes;`
|  | `45` |  | ``
| 0 | `46` |  | `if (naf.Length > length)`
| 0 | `47` |  | `{`
| 0 | `48` |  | `naf = Trim(naf, length);`
| 0 | `49` |  | `}`
|  | `50` |  | ``
| 0 | `51` |  | `return naf;`
| 0 | `52` |  | `}`
|  | `53` |  | ``
|  | `54` |  | `public static int[] GenerateCompactWindowNaf(int width, BigInteger k)`
| 9 | `55` |  | `{`
| 9 | `56` |  | `if (width == 2)`
| 0 | `57` |  | `{`
| 0 | `58` |  | `return GenerateCompactNaf(k);`
|  | `59` |  | `}`
|  | `60` |  | ``
| 9 | `61` |  | `if (width < 2 || width > 16)`
| 0 | `62` |  | `throw new ArgumentException("must be in the range [2, 16]", "width");`
| 9 | `63` |  | `if ((k.BitLength >> 16) != 0)`
| 0 | `64` |  | `throw new ArgumentException("must have bitlength < 2^16", "k");`
| 9 | `65` |  | `if (k.SignValue == 0)`
| 0 | `66` |  | `return Arrays.EmptyInts;`
|  | `67` |  | ``
| 9 | `68` |  | `int[] wnaf = new int[k.BitLength / width + 1];`
|  | `69` |  | ``
|  | `70` |  | `// 2^width and a mask and sign bit set accordingly`
| 9 | `71` |  | `int pow2 = 1 << width;`
| 9 | `72` |  | `int mask = pow2 - 1;`
| 9 | `73` |  | `int sign = pow2 >> 1;`
|  | `74` |  | ``
| 9 | `75` |  | `bool carry = false;`
| 18 | `76` |  | `int length = 0, pos = 0;`
|  | `77` |  | ``
| 1035 | `78` |  | `while (pos <= k.BitLength)`
| 1026 | `79` |  | `{`
| 1026 | `80` |  | `if (k.TestBit(pos) == carry)`
| 505 | `81` |  | `{`
| 505 | `82` |  | `++pos;`
| 505 | `83` |  | `continue;`
|  | `84` |  | `}`
|  | `85` |  | ``
| 521 | `86` |  | `k = k.ShiftRight(pos);`
|  | `87` |  | ``
| 521 | `88` |  | `int digit = k.IntValue & mask;`
| 521 | `89` |  | `if (carry)`
| 264 | `90` |  | `{`
| 264 | `91` |  | `++digit;`
| 264 | `92` |  | `}`
|  | `93` |  | ``
| 521 | `94` |  | `carry = (digit & sign) != 0;`
| 521 | `95` |  | `if (carry)`
| 264 | `96` |  | `{`
| 264 | `97` |  | `digit -= pow2;`
| 264 | `98` |  | `}`
|  | `99` |  | ``
| 521 | `100` |  | `int zeroes = length > 0 ? pos - 1 : pos;`
| 521 | `101` |  | `wnaf[length++] = (digit << 16) | zeroes;`
| 521 | `102` |  | `pos = width;`
| 521 | `103` |  | `}`
|  | `104` |  | ``
|  | `105` |  | `// Reduce the WNAF array to its actual length`
| 9 | `106` |  | `if (wnaf.Length > length)`
| 9 | `107` |  | `{`
| 9 | `108` |  | `wnaf = Trim(wnaf, length);`
| 9 | `109` |  | `}`
|  | `110` |  | ``
| 9 | `111` |  | `return wnaf;`
| 9 | `112` |  | `}`
|  | `113` |  | ``
|  | `114` |  | `public static byte[] GenerateJsf(BigInteger g, BigInteger h)`
| 0 | `115` |  | `{`
| 0 | `116` |  | `int digits = System.Math.Max(g.BitLength, h.BitLength) + 1;`
| 0 | `117` |  | `byte[] jsf = new byte[digits];`
|  | `118` |  | ``
| 0 | `119` |  | `BigInteger k0 = g, k1 = h;`
| 0 | `120` |  | `int j = 0, d0 = 0, d1 = 0;`
|  | `121` |  | ``
| 0 | `122` |  | `int offset = 0;`
| 0 | `123` |  | `while ((d0 | d1) != 0 || k0.BitLength > offset || k1.BitLength > offset)`
| 0 | `124` |  | `{`
| 0 | `125` |  | `int n0 = ((int)((uint)k0.IntValue >> offset) + d0) & 7;`
| 0 | `126` |  | `int n1 = ((int)((uint)k1.IntValue >> offset) + d1) & 7;`
|  | `127` |  | ``
| 0 | `128` |  | `int u0 = n0 & 1;`
| 0 | `129` |  | `if (u0 != 0)`
| 0 | `130` |  | `{`
| 0 | `131` |  | `u0 -= (n0 & 2);`
| 0 | `132` |  | `if ((n0 + u0) == 4 && (n1 & 3) == 2)`
| 0 | `133` |  | `{`
| 0 | `134` |  | `u0 = -u0;`
| 0 | `135` |  | `}`
| 0 | `136` |  | `}`
|  | `137` |  | ``
| 0 | `138` |  | `int u1 = n1 & 1;`
| 0 | `139` |  | `if (u1 != 0)`
| 0 | `140` |  | `{`
| 0 | `141` |  | `u1 -= (n1 & 2);`
| 0 | `142` |  | `if ((n1 + u1) == 4 && (n0 & 3) == 2)`
| 0 | `143` |  | `{`
| 0 | `144` |  | `u1 = -u1;`
| 0 | `145` |  | `}`
| 0 | `146` |  | `}`
|  | `147` |  | ``
| 0 | `148` |  | `if ((d0 << 1) == 1 + u0)`
| 0 | `149` |  | `{`
| 0 | `150` |  | `d0 ^= 1;`
| 0 | `151` |  | `}`
| 0 | `152` |  | `if ((d1 << 1) == 1 + u1)`
| 0 | `153` |  | `{`
| 0 | `154` |  | `d1 ^= 1;`
| 0 | `155` |  | `}`
|  | `156` |  | ``
| 0 | `157` |  | `if (++offset == 30)`
| 0 | `158` |  | `{`
| 0 | `159` |  | `offset = 0;`
| 0 | `160` |  | `k0 = k0.ShiftRight(30);`
| 0 | `161` |  | `k1 = k1.ShiftRight(30);`
| 0 | `162` |  | `}`
|  | `163` |  | ``
| 0 | `164` |  | `jsf[j++] = (byte)((u0 << 4) | (u1 & 0xF));`
| 0 | `165` |  | `}`
|  | `166` |  | ``
|  | `167` |  | `// Reduce the JSF array to its actual length`
| 0 | `168` |  | `if (jsf.Length > j)`
| 0 | `169` |  | `{`
| 0 | `170` |  | `jsf = Trim(jsf, j);`
| 0 | `171` |  | `}`
|  | `172` |  | ``
| 0 | `173` |  | `return jsf;`
| 0 | `174` |  | `}`
|  | `175` |  | ``
|  | `176` |  | `public static byte[] GenerateNaf(BigInteger k)`
| 0 | `177` |  | `{`
| 0 | `178` |  | `if (k.SignValue == 0)`
| 0 | `179` |  | `return Arrays.EmptyBytes;`
|  | `180` |  | ``
| 0 | `181` |  | `BigInteger _3k = k.ShiftLeft(1).Add(k);`
|  | `182` |  | ``
| 0 | `183` |  | `int digits = _3k.BitLength - 1;`
| 0 | `184` |  | `byte[] naf = new byte[digits];`
|  | `185` |  | ``
| 0 | `186` |  | `BigInteger diff = _3k.Xor(k);`
|  | `187` |  | ``
| 0 | `188` |  | `for (int i = 1; i < digits; ++i)`
| 0 | `189` |  | `{`
| 0 | `190` |  | `if (diff.TestBit(i))`
| 0 | `191` |  | `{`
| 0 | `192` |  | `naf[i - 1] = (byte)(k.TestBit(i) ? -1 : 1);`
| 0 | `193` |  | `++i;`
| 0 | `194` |  | `}`
| 0 | `195` |  | `}`
|  | `196` |  | ``
| 0 | `197` |  | `naf[digits - 1] = 1;`
|  | `198` |  | ``
| 0 | `199` |  | `return naf;`
| 0 | `200` |  | `}`
|  | `201` |  | ``
|  | `202` |  | `/**`
|  | `203` |  | `* Computes the Window NAF (non-adjacent Form) of an integer.`
|  | `204` |  | `* @param width The width <code>w</code> of the Window NAF. The width is`
|  | `205` |  | `* defined as the minimal number <code>w</code>, such that for any`
|  | `206` |  | `* <code>w</code> consecutive digits in the resulting representation, at`
|  | `207` |  | `* most one is non-zero.`
|  | `208` |  | `* @param k The integer of which the Window NAF is computed.`
|  | `209` |  | `* @return The Window NAF of the given width, such that the following holds:`
|  | `210` |  | `* <code>k = &amp;sum;<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup>`
|  | `211` |  | `* </code>, where the <code>k<sub>i</sub></code> denote the elements of the`
|  | `212` |  | `* returned <code>byte[]</code>.`
|  | `213` |  | `*/`
|  | `214` |  | `public static byte[] GenerateWindowNaf(int width, BigInteger k)`
| 0 | `215` |  | `{`
| 0 | `216` |  | `if (width == 2)`
| 0 | `217` |  | `{`
| 0 | `218` |  | `return GenerateNaf(k);`
|  | `219` |  | `}`
|  | `220` |  | ``
| 0 | `221` |  | `if (width < 2 || width > 8)`
| 0 | `222` |  | `throw new ArgumentException("must be in the range [2, 8]", "width");`
| 0 | `223` |  | `if (k.SignValue == 0)`
| 0 | `224` |  | `return Arrays.EmptyBytes;`
|  | `225` |  | ``
| 0 | `226` |  | `byte[] wnaf = new byte[k.BitLength + 1];`
|  | `227` |  | ``
|  | `228` |  | `// 2^width and a mask and sign bit set accordingly`
| 0 | `229` |  | `int pow2 = 1 << width;`
| 0 | `230` |  | `int mask = pow2 - 1;`
| 0 | `231` |  | `int sign = pow2 >> 1;`
|  | `232` |  | ``
| 0 | `233` |  | `bool carry = false;`
| 0 | `234` |  | `int length = 0, pos = 0;`
|  | `235` |  | ``
| 0 | `236` |  | `while (pos <= k.BitLength)`
| 0 | `237` |  | `{`
| 0 | `238` |  | `if (k.TestBit(pos) == carry)`
| 0 | `239` |  | `{`
| 0 | `240` |  | `++pos;`
| 0 | `241` |  | `continue;`
|  | `242` |  | `}`
|  | `243` |  | ``
| 0 | `244` |  | `k = k.ShiftRight(pos);`
|  | `245` |  | ``
| 0 | `246` |  | `int digit = k.IntValue & mask;`
| 0 | `247` |  | `if (carry)`
| 0 | `248` |  | `{`
| 0 | `249` |  | `++digit;`
| 0 | `250` |  | `}`
|  | `251` |  | ``
| 0 | `252` |  | `carry = (digit & sign) != 0;`
| 0 | `253` |  | `if (carry)`
| 0 | `254` |  | `{`
| 0 | `255` |  | `digit -= pow2;`
| 0 | `256` |  | `}`
|  | `257` |  | ``
| 0 | `258` |  | `length += (length > 0) ? pos - 1 : pos;`
| 0 | `259` |  | `wnaf[length++] = (byte)digit;`
| 0 | `260` |  | `pos = width;`
| 0 | `261` |  | `}`
|  | `262` |  | ``
|  | `263` |  | `// Reduce the WNAF array to its actual length`
| 0 | `264` |  | `if (wnaf.Length > length)`
| 0 | `265` |  | `{`
| 0 | `266` |  | `wnaf = Trim(wnaf, length);`
| 0 | `267` |  | `}`
|  | `268` |  | ``
| 0 | `269` |  | `return wnaf;`
| 0 | `270` |  | `}`
|  | `271` |  | ``
|  | `272` |  | `public static int GetNafWeight(BigInteger k)`
| 9 | `273` |  | `{`
| 9 | `274` |  | `if (k.SignValue == 0)`
| 0 | `275` |  | `return 0;`
|  | `276` |  | ``
| 9 | `277` |  | `BigInteger _3k = k.ShiftLeft(1).Add(k);`
| 9 | `278` |  | `BigInteger diff = _3k.Xor(k);`
|  | `279` |  | ``
| 9 | `280` |  | `return diff.BitCount;`
| 9 | `281` |  | `}`
|  | `282` |  | ``
|  | `283` |  | `public static WNafPreCompInfo GetWNafPreCompInfo(ECPoint p)`
| 0 | `284` |  | `{`
| 0 | `285` |  | `return GetWNafPreCompInfo(p.Curve.GetPreCompInfo(p, PRECOMP_NAME));`
| 0 | `286` |  | `}`
|  | `287` |  | ``
|  | `288` |  | `public static WNafPreCompInfo GetWNafPreCompInfo(PreCompInfo preCompInfo)`
| 0 | `289` |  | `{`
| 0 | `290` |  | `return preCompInfo as WNafPreCompInfo;`
| 0 | `291` |  | `}`
|  | `292` |  | ``
|  | `293` |  | `/**`
|  | `294` |  | `* Determine window width to use for a scalar multiplication of the given size.`
|  | `295` |  | `*`
|  | `296` |  | `* @param bits the bit-length of the scalar to multiply by`
|  | `297` |  | `* @return the window size to use`
|  | `298` |  | `*/`
|  | `299` |  | `public static int GetWindowSize(int bits)`
| 9 | `300` |  | `{`
| 9 | `301` |  | `return GetWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS);`
| 9 | `302` |  | `}`
|  | `303` |  | ``
|  | `304` |  | `/**`
|  | `305` |  | `* Determine window width to use for a scalar multiplication of the given size.`
|  | `306` |  | `*`
|  | `307` |  | `* @param bits the bit-length of the scalar to multiply by`
|  | `308` |  | `* @param windowSizeCutoffs a monotonically increasing list of bit sizes at which to increment the window width`
|  | `309` |  | `* @return the window size to use`
|  | `310` |  | `*/`
|  | `311` |  | `public static int GetWindowSize(int bits, int[] windowSizeCutoffs)`
| 9 | `312` |  | `{`
| 9 | `313` |  | `int w = 0;`
| 75 | `314` |  | `for (; w < windowSizeCutoffs.Length; ++w)`
| 42 | `315` |  | `{`
| 42 | `316` |  | `if (bits < windowSizeCutoffs[w])`
| 9 | `317` |  | `{`
| 9 | `318` |  | `break;`
|  | `319` |  | `}`
| 33 | `320` |  | `}`
| 9 | `321` |  | `return w + 2;`
| 9 | `322` |  | `}`
|  | `323` |  | ``
|  | `324` |  | `public static ECPoint MapPointWithPrecomp(ECPoint p, int width, bool includeNegated,`
|  | `325` |  | `ECPointMap pointMap)`
| 0 | `326` |  | `{`
| 0 | `327` |  | `ECCurve c = p.Curve;`
| 0 | `328` |  | `WNafPreCompInfo wnafPreCompP = Precompute(p, width, includeNegated);`
|  | `329` |  | ``
| 0 | `330` |  | `ECPoint q = pointMap.Map(p);`
| 0 | `331` |  | `c.Precompute(q, PRECOMP_NAME, new MapPointCallback(wnafPreCompP, includeNegated, pointMap));`
| 0 | `332` |  | `return q;`
| 0 | `333` |  | `}`
|  | `334` |  | ``
|  | `335` |  | `public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated)`
| 9 | `336` |  | `{`
| 9 | `337` |  | `return (WNafPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, new WNafCallback(p, width, includeNegated));`
| 9 | `338` |  | `}`
|  | `339` |  | ``
|  | `340` |  | `private static byte[] Trim(byte[] a, int length)`
| 0 | `341` |  | `{`
| 0 | `342` |  | `byte[] result = new byte[length];`
| 0 | `343` |  | `Array.Copy(a, 0, result, 0, result.Length);`
| 0 | `344` |  | `return result;`
| 0 | `345` |  | `}`
|  | `346` |  | ``
|  | `347` |  | `private static int[] Trim(int[] a, int length)`
| 9 | `348` |  | `{`
| 9 | `349` |  | `int[] result = new int[length];`
| 9 | `350` |  | `Array.Copy(a, 0, result, 0, result.Length);`
| 9 | `351` |  | `return result;`
| 9 | `352` |  | `}`
|  | `353` |  | ``
|  | `354` |  | `private static ECPoint[] ResizeTable(ECPoint[] a, int length)`
| 9 | `355` |  | `{`
| 9 | `356` |  | `ECPoint[] result = new ECPoint[length];`
| 9 | `357` |  | `Array.Copy(a, 0, result, 0, a.Length);`
| 9 | `358` |  | `return result;`
| 9 | `359` |  | `}`
|  | `360` |  | ``
|  | `361` |  | `private class MapPointCallback`
|  | `362` |  | `: IPreCompCallback`
|  | `363` |  | `{`
|  | `364` |  | `private readonly WNafPreCompInfo m_wnafPreCompP;`
|  | `365` |  | `private readonly bool m_includeNegated;`
|  | `366` |  | `private readonly ECPointMap m_pointMap;`
|  | `367` |  | ``
| 0 | `368` |  | `internal MapPointCallback(WNafPreCompInfo wnafPreCompP, bool includeNegated, ECPointMap pointMap)`
| 0 | `369` |  | `{`
| 0 | `370` |  | `this.m_wnafPreCompP = wnafPreCompP;`
| 0 | `371` |  | `this.m_includeNegated = includeNegated;`
| 0 | `372` |  | `this.m_pointMap = pointMap;`
| 0 | `373` |  | `}`
|  | `374` |  | ``
|  | `375` |  | `public PreCompInfo Precompute(PreCompInfo existing)`
| 0 | `376` |  | `{`
| 0 | `377` |  | `WNafPreCompInfo result = new WNafPreCompInfo();`
|  | `378` |  | ``
| 0 | `379` |  | `ECPoint twiceP = m_wnafPreCompP.Twice;`
| 0 | `380` |  | `if (twiceP != null)`
| 0 | `381` |  | `{`
| 0 | `382` |  | `ECPoint twiceQ = m_pointMap.Map(twiceP);`
| 0 | `383` |  | `result.Twice = twiceQ;`
| 0 | `384` |  | `}`
|  | `385` |  | ``
| 0 | `386` |  | `ECPoint[] preCompP = m_wnafPreCompP.PreComp;`
| 0 | `387` |  | `ECPoint[] preCompQ = new ECPoint[preCompP.Length];`
| 0 | `388` |  | `for (int i = 0; i < preCompP.Length; ++i)`
| 0 | `389` |  | `{`
| 0 | `390` |  | `preCompQ[i] = m_pointMap.Map(preCompP[i]);`
| 0 | `391` |  | `}`
| 0 | `392` |  | `result.PreComp = preCompQ;`
|  | `393` |  | ``
| 0 | `394` |  | `if (m_includeNegated)`
| 0 | `395` |  | `{`
| 0 | `396` |  | `ECPoint[] preCompNegQ = new ECPoint[preCompQ.Length];`
| 0 | `397` |  | `for (int i = 0; i < preCompNegQ.Length; ++i)`
| 0 | `398` |  | `{`
| 0 | `399` |  | `preCompNegQ[i] = preCompQ[i].Negate();`
| 0 | `400` |  | `}`
| 0 | `401` |  | `result.PreCompNeg = preCompNegQ;`
| 0 | `402` |  | `}`
|  | `403` |  | ``
| 0 | `404` |  | `return result;`
| 0 | `405` |  | `}`
|  | `406` |  | `}`
|  | `407` |  | ``
|  | `408` |  | `private class WNafCallback`
|  | `409` |  | `: IPreCompCallback`
|  | `410` |  | `{`
|  | `411` |  | `private readonly ECPoint m_p;`
|  | `412` |  | `private readonly int m_width;`
|  | `413` |  | `private readonly bool m_includeNegated;`
|  | `414` |  | ``
| 9 | `415` |  | `internal WNafCallback(ECPoint p, int width, bool includeNegated)`
| 9 | `416` |  | `{`
| 9 | `417` |  | `this.m_p = p;`
| 9 | `418` |  | `this.m_width = width;`
| 9 | `419` |  | `this.m_includeNegated = includeNegated;`
| 9 | `420` |  | `}`
|  | `421` |  | ``
|  | `422` |  | `public PreCompInfo Precompute(PreCompInfo existing)`
| 9 | `423` |  | `{`
| 9 | `424` |  | `WNafPreCompInfo existingWNaf = existing as WNafPreCompInfo;`
|  | `425` |  | ``
| 9 | `426` |  | `int reqPreCompLen = 1 << System.Math.Max(0, m_width - 2);`
|  | `427` |  | ``
| 9 | `428` |  | `if (CheckExisting(existingWNaf, reqPreCompLen, m_includeNegated))`
| 0 | `429` |  | `return existingWNaf;`
|  | `430` |  | ``
| 9 | `431` |  | `ECCurve c = m_p.Curve;`
| 18 | `432` |  | `ECPoint[] preComp = null, preCompNeg = null;`
| 9 | `433` |  | `ECPoint twiceP = null;`
|  | `434` |  | ``
| 9 | `435` |  | `if (existingWNaf != null)`
| 0 | `436` |  | `{`
| 0 | `437` |  | `preComp = existingWNaf.PreComp;`
| 0 | `438` |  | `preCompNeg = existingWNaf.PreCompNeg;`
| 0 | `439` |  | `twiceP = existingWNaf.Twice;`
| 0 | `440` |  | `}`
|  | `441` |  | ``
| 9 | `442` |  | `int iniPreCompLen = 0;`
| 9 | `443` |  | `if (preComp == null)`
| 9 | `444` |  | `{`
| 9 | `445` |  | `preComp = EMPTY_POINTS;`
| 9 | `446` |  | `}`
|  | `447` |  | `else`
| 0 | `448` |  | `{`
| 0 | `449` |  | `iniPreCompLen = preComp.Length;`
| 0 | `450` |  | `}`
|  | `451` |  | ``
| 9 | `452` |  | `if (iniPreCompLen < reqPreCompLen)`
| 9 | `453` |  | `{`
| 9 | `454` |  | `preComp = WNafUtilities.ResizeTable(preComp, reqPreCompLen);`
|  | `455` |  | ``
| 9 | `456` |  | `if (reqPreCompLen == 1)`
| 0 | `457` |  | `{`
| 0 | `458` |  | `preComp[0] = m_p.Normalize();`
| 0 | `459` |  | `}`
|  | `460` |  | `else`
| 9 | `461` |  | `{`
| 9 | `462` |  | `int curPreCompLen = iniPreCompLen;`
| 9 | `463` |  | `if (curPreCompLen == 0)`
| 9 | `464` |  | `{`
| 9 | `465` |  | `preComp[0] = m_p;`
| 9 | `466` |  | `curPreCompLen = 1;`
| 9 | `467` |  | `}`
|  | `468` |  | ``
| 9 | `469` |  | `ECFieldElement iso = null;`
|  | `470` |  | ``
| 9 | `471` |  | `if (reqPreCompLen == 2)`
| 0 | `472` |  | `{`
| 0 | `473` |  | `preComp[1] = m_p.ThreeTimes();`
| 0 | `474` |  | `}`
|  | `475` |  | `else`
| 9 | `476` |  | `{`
| 18 | `477` |  | `ECPoint isoTwiceP = twiceP, last = preComp[curPreCompLen - 1];`
| 9 | `478` |  | `if (isoTwiceP == null)`
| 9 | `479` |  | `{`
| 9 | `480` |  | `isoTwiceP = preComp[0].Twice();`
| 9 | `481` |  | `twiceP = isoTwiceP;`
|  | `482` |  | ``
|  | `483` |  | `/*`
|  | `484` |  | `* For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism`
|  | `485` |  | `* where 'twiceP' is "affine", so that the subsequent additions are cheaper. This`
|  | `486` |  | `* also requires scaling the initial point's X, Y coordinates, and reversing the`
|  | `487` |  | `* isomorphism as part of the subsequent normalization.`
|  | `488` |  | `*`
|  | `489` |  | `* NOTE: The correctness of this optimization depends on:`
|  | `490` |  | `* 1) additions do not use the curve's A, B coefficients.`
|  | `491` |  | `* 2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ...`
|  | `492` |  | `*/`
| 9 | `493` |  | `if (!twiceP.IsInfinity && ECAlgorithms.IsFpCurve(c) && c.FieldSize >= 64)`
| 9 | `494` |  | `{`
| 9 | `495` |  | `switch (c.CoordinateSystem)`
|  | `496` |  | `{`
|  | `497` |  | `case ECCurve.COORD_JACOBIAN:`
|  | `498` |  | `case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:`
|  | `499` |  | `case ECCurve.COORD_JACOBIAN_MODIFIED:`
| 9 | `500` |  | `{`
| 9 | `501` |  | `iso = twiceP.GetZCoord(0);`
| 9 | `502` |  | `isoTwiceP = c.CreatePoint(twiceP.XCoord.ToBigInteger(),`
| 9 | `503` |  | `twiceP.YCoord.ToBigInteger());`
|  | `504` |  | ``
| 18 | `505` |  | `ECFieldElement iso2 = iso.Square(), iso3 = iso2.Multiply(iso);`
| 9 | `506` |  | `last = last.ScaleX(iso2).ScaleY(iso3);`
|  | `507` |  | ``
| 9 | `508` |  | `if (iniPreCompLen == 0)`
| 9 | `509` |  | `{`
| 9 | `510` |  | `preComp[0] = last;`
| 9 | `511` |  | `}`
| 9 | `512` |  | `break;`
|  | `513` |  | `}`
|  | `514` |  | `}`
| 9 | `515` |  | `}`
| 9 | `516` |  | `}`
|  | `517` |  | ``
| 120 | `518` |  | `while (curPreCompLen < reqPreCompLen)`
| 111 | `519` |  | `{`
|  | `520` |  | `/*`
|  | `521` |  | `* Compute the new ECPoints for the precomputation array. The values 1, 3,`
|  | `522` |  | `* 5, ..., 2^(width-1)-1 times p are computed`
|  | `523` |  | `*/`
| 111 | `524` |  | `preComp[curPreCompLen++] = last = last.Add(isoTwiceP);`
| 111 | `525` |  | `}`
| 9 | `526` |  | `}`
|  | `527` |  | ``
|  | `528` |  | `/*`
|  | `529` |  | `* Having oft-used operands in affine form makes operations faster.`
|  | `530` |  | `*/`
| 9 | `531` |  | `c.NormalizeAll(preComp, iniPreCompLen, reqPreCompLen - iniPreCompLen, iso);`
| 9 | `532` |  | `}`
| 9 | `533` |  | `}`
|  | `534` |  | ``
| 9 | `535` |  | `if (m_includeNegated)`
| 9 | `536` |  | `{`
|  | `537` |  | `int pos;`
| 9 | `538` |  | `if (preCompNeg == null)`
| 9 | `539` |  | `{`
| 9 | `540` |  | `pos = 0;`
| 9 | `541` |  | `preCompNeg = new ECPoint[reqPreCompLen];`
| 9 | `542` |  | `}`
|  | `543` |  | `else`
| 0 | `544` |  | `{`
| 0 | `545` |  | `pos = preCompNeg.Length;`
| 0 | `546` |  | `if (pos < reqPreCompLen)`
| 0 | `547` |  | `{`
| 0 | `548` |  | `preCompNeg = WNafUtilities.ResizeTable(preCompNeg, reqPreCompLen);`
| 0 | `549` |  | `}`
| 0 | `550` |  | `}`
|  | `551` |  | ``
| 129 | `552` |  | `while (pos < reqPreCompLen)`
| 120 | `553` |  | `{`
| 120 | `554` |  | `preCompNeg[pos] = preComp[pos].Negate();`
| 120 | `555` |  | `++pos;`
| 120 | `556` |  | `}`
| 9 | `557` |  | `}`
|  | `558` |  | ``
| 9 | `559` |  | `WNafPreCompInfo result = new WNafPreCompInfo();`
| 9 | `560` |  | `result.PreComp = preComp;`
| 9 | `561` |  | `result.PreCompNeg = preCompNeg;`
| 9 | `562` |  | `result.Twice = twiceP;`
| 9 | `563` |  | `return result;`
| 9 | `564` |  | `}`
|  | `565` |  | ``
|  | `566` |  | `private bool CheckExisting(WNafPreCompInfo existingWNaf, int reqPreCompLen, bool includeNegated)`
| 9 | `567` |  | `{`
| 9 | `568` |  | `return existingWNaf != null`
| 9 | `569` |  | `&& CheckTable(existingWNaf.PreComp, reqPreCompLen)`
| 9 | `570` |  | `&& (!includeNegated || CheckTable(existingWNaf.PreCompNeg, reqPreCompLen));`
| 9 | `571` |  | `}`
|  | `572` |  | ``
|  | `573` |  | `private bool CheckTable(ECPoint[] table, int reqLen)`
| 0 | `574` |  | `{`
| 0 | `575` |  | `return table != null && table.Length >= reqLen;`
| 0 | `576` |  | `}`
|  | `577` |  | `}`
|  | `578` |  | `}`
|  | `579` |  | `}`

# Methods/Properties

.cctor()
GenerateCompactNaf(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
GenerateCompactWindowNaf(System.Int32,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
GenerateJsf(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
GenerateNaf(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
GenerateWindowNaf(System.Int32,Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
GetNafWeight(Renci.SshNet.Security.Org.BouncyCastle.Math.BigInteger)
GetWNafPreCompInfo(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECPoint)
GetWNafPreCompInfo(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier.PreCompInfo)
GetWindowSize(System.Int32)
GetWindowSize(System.Int32,System.Int32[])
MapPointWithPrecomp(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECPoint,System.Int32,System.Boolean,Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECPointMap)
Precompute(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECPoint,System.Int32,System.Boolean)
Trim(System.Byte[],System.Int32)
Trim(System.Int32[],System.Int32)
ResizeTable(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECPoint[],System.Int32)
.ctor(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier.WNafPreCompInfo,System.Boolean,Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECPointMap)
Precompute(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier.PreCompInfo)
.ctor(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECPoint,System.Int32,System.Boolean)
Precompute(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier.PreCompInfo)
CheckExisting(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier.WNafPreCompInfo,System.Int32,System.Boolean)
CheckTable(Renci.SshNet.Security.Org.BouncyCastle.Math.EC.ECPoint[],System.Int32)