WTauNafMultiplier.cs 5.2 KB

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