| | | 1 | | using System; |
| | | 2 | | |
| | | 3 | | namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier |
| | | 4 | | { |
| | | 5 | | internal class FixedPointUtilities |
| | | 6 | | { |
| | 1 | 7 | | public static readonly string PRECOMP_NAME = "bc_fixed_point"; |
| | | 8 | | |
| | | 9 | | public static int GetCombSize(ECCurve c) |
| | 18 | 10 | | { |
| | 18 | 11 | | BigInteger order = c.Order; |
| | 18 | 12 | | return order == null ? c.FieldSize + 1 : order.BitLength; |
| | 18 | 13 | | } |
| | | 14 | | |
| | | 15 | | public static FixedPointPreCompInfo GetFixedPointPreCompInfo(PreCompInfo preCompInfo) |
| | 0 | 16 | | { |
| | 0 | 17 | | return preCompInfo as FixedPointPreCompInfo; |
| | 0 | 18 | | } |
| | | 19 | | |
| | | 20 | | public static FixedPointPreCompInfo Precompute(ECPoint p) |
| | 9 | 21 | | { |
| | 9 | 22 | | return (FixedPointPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, new FixedPointCallback(p)); |
| | 9 | 23 | | } |
| | | 24 | | |
| | | 25 | | private class FixedPointCallback |
| | | 26 | | : IPreCompCallback |
| | | 27 | | { |
| | | 28 | | private readonly ECPoint m_p; |
| | | 29 | | |
| | 9 | 30 | | internal FixedPointCallback(ECPoint p) |
| | 9 | 31 | | { |
| | 9 | 32 | | this.m_p = p; |
| | 9 | 33 | | } |
| | | 34 | | |
| | | 35 | | public PreCompInfo Precompute(PreCompInfo existing) |
| | 9 | 36 | | { |
| | 9 | 37 | | FixedPointPreCompInfo existingFP = (existing is FixedPointPreCompInfo) ? (FixedPointPreCompInfo)existing |
| | | 38 | | |
| | 9 | 39 | | ECCurve c = m_p.Curve; |
| | 9 | 40 | | int bits = FixedPointUtilities.GetCombSize(c); |
| | 9 | 41 | | int minWidth = bits > 250 ? 6 : 5; |
| | 9 | 42 | | int n = 1 << minWidth; |
| | | 43 | | |
| | 9 | 44 | | if (CheckExisting(existingFP, n)) |
| | 6 | 45 | | return existingFP; |
| | | 46 | | |
| | 3 | 47 | | int d = (bits + minWidth - 1) / minWidth; |
| | | 48 | | |
| | 3 | 49 | | ECPoint[] pow2Table = new ECPoint[minWidth + 1]; |
| | 3 | 50 | | pow2Table[0] = m_p; |
| | 36 | 51 | | for (int i = 1; i < minWidth; ++i) |
| | 15 | 52 | | { |
| | 15 | 53 | | pow2Table[i] = pow2Table[i - 1].TimesPow2(d); |
| | 15 | 54 | | } |
| | | 55 | | |
| | | 56 | | // This will be the 'offset' value |
| | 3 | 57 | | pow2Table[minWidth] = pow2Table[0].Subtract(pow2Table[1]); |
| | | 58 | | |
| | 3 | 59 | | c.NormalizeAll(pow2Table); |
| | | 60 | | |
| | 3 | 61 | | ECPoint[] lookupTable = new ECPoint[n]; |
| | 3 | 62 | | lookupTable[0] = pow2Table[0]; |
| | | 63 | | |
| | 42 | 64 | | for (int bit = minWidth - 1; bit >= 0; --bit) |
| | 18 | 65 | | { |
| | 18 | 66 | | ECPoint pow2 = pow2Table[bit]; |
| | | 67 | | |
| | 18 | 68 | | int step = 1 << bit; |
| | 414 | 69 | | for (int i = step; i < n; i += (step << 1)) |
| | 189 | 70 | | { |
| | 189 | 71 | | lookupTable[i] = lookupTable[i - step].Add(pow2); |
| | 189 | 72 | | } |
| | 18 | 73 | | } |
| | | 74 | | |
| | 3 | 75 | | c.NormalizeAll(lookupTable); |
| | | 76 | | |
| | 3 | 77 | | FixedPointPreCompInfo result = new FixedPointPreCompInfo(); |
| | 3 | 78 | | result.LookupTable = c.CreateCacheSafeLookupTable(lookupTable, 0, lookupTable.Length); |
| | 3 | 79 | | result.Offset = pow2Table[minWidth]; |
| | 3 | 80 | | result.Width = minWidth; |
| | 3 | 81 | | return result; |
| | 9 | 82 | | } |
| | | 83 | | |
| | | 84 | | private bool CheckExisting(FixedPointPreCompInfo existingFP, int n) |
| | 9 | 85 | | { |
| | 9 | 86 | | return existingFP != null && CheckTable(existingFP.LookupTable, n); |
| | 9 | 87 | | } |
| | | 88 | | |
| | | 89 | | private bool CheckTable(ECLookupTable table, int n) |
| | 6 | 90 | | { |
| | 6 | 91 | | return table != null && table.Size >= n; |
| | 6 | 92 | | } |
| | | 93 | | } |
| | | 94 | | } |
| | | 95 | | } |