| | | 1 | | using System; |
| | | 2 | | |
| | | 3 | | using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Abc; |
| | | 4 | | |
| | | 5 | | namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier |
| | | 6 | | { |
| | | 7 | | /** |
| | | 8 | | * Class implementing the WTNAF (Window |
| | | 9 | | * <code>τ</code>-adic Non-Adjacent Form) algorithm. |
| | | 10 | | */ |
| | | 11 | | internal class WTauNafMultiplier |
| | | 12 | | : AbstractECMultiplier |
| | | 13 | | { |
| | | 14 | | // TODO Create WTauNafUtilities class and move various functionality into it |
| | 0 | 15 | | internal static readonly string PRECOMP_NAME = "bc_wtnaf"; |
| | | 16 | | |
| | | 17 | | /** |
| | | 18 | | * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} |
| | | 19 | | * by <code>k</code> using the reduced <code>τ</code>-adic NAF (RTNAF) |
| | | 20 | | * method. |
| | | 21 | | * @param p The AbstractF2mPoint to multiply. |
| | | 22 | | * @param k The integer by which to multiply <code>k</code>. |
| | | 23 | | * @return <code>p</code> multiplied by <code>k</code>. |
| | | 24 | | */ |
| | | 25 | | protected override ECPoint MultiplyPositive(ECPoint point, BigInteger k) |
| | 0 | 26 | | { |
| | 0 | 27 | | if (!(point is AbstractF2mPoint)) |
| | 0 | 28 | | throw new ArgumentException("Only AbstractF2mPoint can be used in WTauNafMultiplier"); |
| | | 29 | | |
| | 0 | 30 | | AbstractF2mPoint p = (AbstractF2mPoint)point; |
| | 0 | 31 | | AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; |
| | 0 | 32 | | int m = curve.FieldSize; |
| | 0 | 33 | | sbyte a = (sbyte)curve.A.ToBigInteger().IntValue; |
| | 0 | 34 | | sbyte mu = Tnaf.GetMu(a); |
| | 0 | 35 | | BigInteger[] s = curve.GetSi(); |
| | | 36 | | |
| | 0 | 37 | | ZTauElement rho = Tnaf.PartModReduction(k, m, a, s, mu, (sbyte)10); |
| | | 38 | | |
| | 0 | 39 | | return MultiplyWTnaf(p, rho, a, mu); |
| | 0 | 40 | | } |
| | | 41 | | |
| | | 42 | | /** |
| | | 43 | | * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} |
| | | 44 | | * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> using |
| | | 45 | | * the <code>τ</code>-adic NAF (TNAF) method. |
| | | 46 | | * @param p The AbstractF2mPoint to multiply. |
| | | 47 | | * @param lambda The element <code>λ</code> of |
| | | 48 | | * <code><b>Z</b>[τ]</code> of which to compute the |
| | | 49 | | * <code>[τ]</code>-adic NAF. |
| | | 50 | | * @return <code>p</code> multiplied by <code>λ</code>. |
| | | 51 | | */ |
| | | 52 | | private AbstractF2mPoint MultiplyWTnaf(AbstractF2mPoint p, ZTauElement lambda, |
| | | 53 | | sbyte a, sbyte mu) |
| | 0 | 54 | | { |
| | 0 | 55 | | ZTauElement[] alpha = (a == 0) ? Tnaf.Alpha0 : Tnaf.Alpha1; |
| | | 56 | | |
| | 0 | 57 | | BigInteger tw = Tnaf.GetTw(mu, Tnaf.Width); |
| | | 58 | | |
| | 0 | 59 | | sbyte[]u = Tnaf.TauAdicWNaf(mu, lambda, Tnaf.Width, |
| | 0 | 60 | | BigInteger.ValueOf(Tnaf.Pow2Width), tw, alpha); |
| | | 61 | | |
| | 0 | 62 | | return MultiplyFromWTnaf(p, u); |
| | 0 | 63 | | } |
| | | 64 | | |
| | | 65 | | /** |
| | | 66 | | * Multiplies a {@link org.bouncycastle.math.ec.AbstractF2mPoint AbstractF2mPoint} |
| | | 67 | | * by an element <code>λ</code> of <code><b>Z</b>[τ]</code> |
| | | 68 | | * using the window <code>τ</code>-adic NAF (TNAF) method, given the |
| | | 69 | | * WTNAF of <code>λ</code>. |
| | | 70 | | * @param p The AbstractF2mPoint to multiply. |
| | | 71 | | * @param u The the WTNAF of <code>λ</code>.. |
| | | 72 | | * @return <code>λ * p</code> |
| | | 73 | | */ |
| | | 74 | | private static AbstractF2mPoint MultiplyFromWTnaf(AbstractF2mPoint p, sbyte[] u) |
| | 0 | 75 | | { |
| | 0 | 76 | | AbstractF2mCurve curve = (AbstractF2mCurve)p.Curve; |
| | 0 | 77 | | sbyte a = (sbyte)curve.A.ToBigInteger().IntValue; |
| | | 78 | | |
| | 0 | 79 | | WTauNafCallback callback = new WTauNafCallback(p, a); |
| | 0 | 80 | | WTauNafPreCompInfo preCompInfo = (WTauNafPreCompInfo)curve.Precompute(p, PRECOMP_NAME, callback); |
| | 0 | 81 | | AbstractF2mPoint[] pu = preCompInfo.PreComp; |
| | | 82 | | |
| | | 83 | | // TODO Include negations in precomp (optionally) and use from here |
| | 0 | 84 | | AbstractF2mPoint[] puNeg = new AbstractF2mPoint[pu.Length]; |
| | 0 | 85 | | for (int i = 0; i < pu.Length; ++i) |
| | 0 | 86 | | { |
| | 0 | 87 | | puNeg[i] = (AbstractF2mPoint)pu[i].Negate(); |
| | 0 | 88 | | } |
| | | 89 | | |
| | | 90 | | |
| | | 91 | | // q = infinity |
| | 0 | 92 | | AbstractF2mPoint q = (AbstractF2mPoint) p.Curve.Infinity; |
| | | 93 | | |
| | 0 | 94 | | int tauCount = 0; |
| | 0 | 95 | | for (int i = u.Length - 1; i >= 0; i--) |
| | 0 | 96 | | { |
| | 0 | 97 | | ++tauCount; |
| | 0 | 98 | | int ui = u[i]; |
| | 0 | 99 | | if (ui != 0) |
| | 0 | 100 | | { |
| | 0 | 101 | | q = q.TauPow(tauCount); |
| | 0 | 102 | | tauCount = 0; |
| | | 103 | | |
| | 0 | 104 | | ECPoint x = ui > 0 ? pu[ui >> 1] : puNeg[(-ui) >> 1]; |
| | 0 | 105 | | q = (AbstractF2mPoint)q.Add(x); |
| | 0 | 106 | | } |
| | 0 | 107 | | } |
| | 0 | 108 | | if (tauCount > 0) |
| | 0 | 109 | | { |
| | 0 | 110 | | q = q.TauPow(tauCount); |
| | 0 | 111 | | } |
| | 0 | 112 | | return q; |
| | 0 | 113 | | } |
| | | 114 | | |
| | | 115 | | private class WTauNafCallback |
| | | 116 | | : IPreCompCallback |
| | | 117 | | { |
| | | 118 | | private readonly AbstractF2mPoint m_p; |
| | | 119 | | private readonly sbyte m_a; |
| | | 120 | | |
| | 0 | 121 | | internal WTauNafCallback(AbstractF2mPoint p, sbyte a) |
| | 0 | 122 | | { |
| | 0 | 123 | | this.m_p = p; |
| | 0 | 124 | | this.m_a = a; |
| | 0 | 125 | | } |
| | | 126 | | |
| | | 127 | | public PreCompInfo Precompute(PreCompInfo existing) |
| | 0 | 128 | | { |
| | 0 | 129 | | if (existing is WTauNafPreCompInfo) |
| | 0 | 130 | | return existing; |
| | | 131 | | |
| | 0 | 132 | | WTauNafPreCompInfo result = new WTauNafPreCompInfo(); |
| | 0 | 133 | | result.PreComp = Tnaf.GetPreComp(m_p, m_a); |
| | 0 | 134 | | return result; |
| | 0 | 135 | | } |
| | | 136 | | } |
| | | 137 | | } |
| | | 138 | | } |