WNafL2RMultiplier.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  5. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier
  6. {
  7. /**
  8. * Class implementing the WNAF (Window Non-Adjacent Form) multiplication
  9. * algorithm.
  10. */
  11. public class WNafL2RMultiplier
  12. : AbstractECMultiplier
  13. {
  14. /**
  15. * Multiplies <code>this</code> by an integer <code>k</code> using the
  16. * Window NAF method.
  17. * @param k The integer by which <code>this</code> is multiplied.
  18. * @return A new <code>ECPoint</code> which equals <code>this</code>
  19. * multiplied by <code>k</code>.
  20. */
  21. protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
  22. {
  23. int minWidth = WNafUtilities.GetWindowSize(k.BitLength);
  24. WNafPreCompInfo info = WNafUtilities.Precompute(p, minWidth, true);
  25. ECPoint[] preComp = info.PreComp;
  26. ECPoint[] preCompNeg = info.PreCompNeg;
  27. int width = info.Width;
  28. int[] wnaf = WNafUtilities.GenerateCompactWindowNaf(width, k);
  29. ECPoint R = p.Curve.Infinity;
  30. int i = wnaf.Length;
  31. /*
  32. * NOTE: We try to optimize the first window using the precomputed points to substitute an
  33. * addition for 2 or more doublings.
  34. */
  35. if (i > 1)
  36. {
  37. int wi = wnaf[--i];
  38. int digit = wi >> 16, zeroes = wi & 0xFFFF;
  39. int n = System.Math.Abs(digit);
  40. ECPoint[] table = digit < 0 ? preCompNeg : preComp;
  41. // Optimization can only be used for values in the lower half of the table
  42. if ((n << 2) < (1 << width))
  43. {
  44. int highest = 32 - Integers.NumberOfLeadingZeros(n);
  45. // TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting?
  46. int scale = width - highest;
  47. int lowBits = n ^ (1 << (highest - 1));
  48. int i1 = ((1 << (width - 1)) - 1);
  49. int i2 = (lowBits << scale) + 1;
  50. R = table[i1 >> 1].Add(table[i2 >> 1]);
  51. zeroes -= scale;
  52. //Console.WriteLine("Optimized: 2^" + scale + " * " + n + " = " + i1 + " + " + i2);
  53. }
  54. else
  55. {
  56. R = table[n >> 1];
  57. }
  58. R = R.TimesPow2(zeroes);
  59. }
  60. while (i > 0)
  61. {
  62. int wi = wnaf[--i];
  63. int digit = wi >> 16, zeroes = wi & 0xFFFF;
  64. int n = System.Math.Abs(digit);
  65. ECPoint[] table = digit < 0 ? preCompNeg : preComp;
  66. ECPoint r = table[n >> 1];
  67. R = R.TwicePlus(r);
  68. R = R.TimesPow2(zeroes);
  69. }
  70. return R;
  71. }
  72. }
  73. }
  74. #pragma warning restore
  75. #endif