FixedPointCombMultiplier.cs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. namespace Org.BouncyCastle.Math.EC.Multiplier
  4. {
  5. public class FixedPointCombMultiplier
  6. : AbstractECMultiplier
  7. {
  8. protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
  9. {
  10. ECCurve c = p.Curve;
  11. int size = FixedPointUtilities.GetCombSize(c);
  12. if (k.BitLength > size)
  13. {
  14. /*
  15. * TODO The comb works best when the scalars are less than the (possibly unknown) order.
  16. * Still, if we want to handle larger scalars, we could allow customization of the comb
  17. * size, or alternatively we could deal with the 'extra' bits either by running the comb
  18. * multiple times as necessary, or by using an alternative multiplier as prelude.
  19. */
  20. throw new InvalidOperationException("fixed-point comb doesn't support scalars larger than the curve order");
  21. }
  22. int minWidth = GetWidthForCombSize(size);
  23. FixedPointPreCompInfo info = FixedPointUtilities.Precompute(p, minWidth);
  24. ECPoint[] lookupTable = info.PreComp;
  25. int width = info.Width;
  26. int d = (size + width - 1) / width;
  27. ECPoint R = c.Infinity;
  28. int top = d * width - 1;
  29. for (int i = 0; i < d; ++i)
  30. {
  31. int index = 0;
  32. for (int j = top - i; j >= 0; j -= d)
  33. {
  34. index <<= 1;
  35. if (k.TestBit(j))
  36. {
  37. index |= 1;
  38. }
  39. }
  40. R = R.TwicePlus(lookupTable[index]);
  41. }
  42. return R;
  43. }
  44. protected virtual int GetWidthForCombSize(int combSize)
  45. {
  46. return combSize > 257 ? 6 : 5;
  47. }
  48. }
  49. }
  50. #endif