FixedPointCombMultiplier.cs 2.1 KB

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