WTauNafMultiplier.cs 4.7 KB

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