| | | 1 | | using System; |
| | | 2 | | |
| | | 3 | | using Renci.SshNet.Security.Org.BouncyCastle.Math.Raw; |
| | | 4 | | |
| | | 5 | | namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier |
| | | 6 | | { |
| | | 7 | | internal class FixedPointCombMultiplier |
| | | 8 | | : AbstractECMultiplier |
| | | 9 | | { |
| | | 10 | | protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k) |
| | 9 | 11 | | { |
| | 9 | 12 | | ECCurve c = p.Curve; |
| | 9 | 13 | | int size = FixedPointUtilities.GetCombSize(c); |
| | | 14 | | |
| | 9 | 15 | | if (k.BitLength > size) |
| | 0 | 16 | | { |
| | | 17 | | /* |
| | | 18 | | * TODO The comb works best when the scalars are less than the (possibly unknown) order. |
| | | 19 | | * Still, if we want to handle larger scalars, we could allow customization of the comb |
| | | 20 | | * size, or alternatively we could deal with the 'extra' bits either by running the comb |
| | | 21 | | * multiple times as necessary, or by using an alternative multiplier as prelude. |
| | | 22 | | */ |
| | 0 | 23 | | throw new InvalidOperationException("fixed-point comb doesn't support scalars larger than the curve orde |
| | | 24 | | } |
| | | 25 | | |
| | 9 | 26 | | FixedPointPreCompInfo info = FixedPointUtilities.Precompute(p); |
| | 9 | 27 | | ECLookupTable lookupTable = info.LookupTable; |
| | 9 | 28 | | int width = info.Width; |
| | | 29 | | |
| | 9 | 30 | | int d = (size + width - 1) / width; |
| | | 31 | | |
| | 9 | 32 | | ECPoint R = c.Infinity; |
| | | 33 | | |
| | 9 | 34 | | int fullComb = d * width; |
| | 9 | 35 | | uint[] K = Nat.FromBigInteger(fullComb, k); |
| | | 36 | | |
| | 9 | 37 | | int top = fullComb - 1; |
| | 1182 | 38 | | for (int i = 0; i < d; ++i) |
| | 582 | 39 | | { |
| | 582 | 40 | | uint secretIndex = 0; |
| | | 41 | | |
| | 8148 | 42 | | for (int j = top - i; j >= 0; j -= d) |
| | 3492 | 43 | | { |
| | 3492 | 44 | | uint secretBit = K[j >> 5] >> (j & 0x1F); |
| | 3492 | 45 | | secretIndex ^= secretBit >> 1; |
| | 3492 | 46 | | secretIndex <<= 1; |
| | 3492 | 47 | | secretIndex ^= secretBit; |
| | 3492 | 48 | | } |
| | | 49 | | |
| | 582 | 50 | | ECPoint add = lookupTable.Lookup((int)secretIndex); |
| | | 51 | | |
| | 582 | 52 | | R = R.TwicePlus(add); |
| | 582 | 53 | | } |
| | | 54 | | |
| | 9 | 55 | | return R.Add(info.Offset); |
| | 9 | 56 | | } |
| | | 57 | | } |
| | | 58 | | } |