FixedPointCombMultiplier.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
  5. namespace Best.HTTP.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. int fullComb = d * width;
  29. ECPoint R = c.Infinity;
  30. #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
  31. int KLen = Nat.GetLengthForBits(fullComb);
  32. Span<uint> K = KLen <= 32
  33. ? stackalloc uint[KLen]
  34. : new uint[KLen];
  35. Nat.FromBigInteger(fullComb, k, K);
  36. #else
  37. uint[] K = Nat.FromBigInteger(fullComb, k);
  38. #endif
  39. for (int i = 1; i <= d; ++i)
  40. {
  41. uint secretIndex = 0;
  42. for (int j = fullComb - i; j >= 0; j -= d)
  43. {
  44. uint secretBit = K[j >> 5] >> (j & 0x1F);
  45. secretIndex ^= secretBit >> 1;
  46. secretIndex <<= 1;
  47. secretIndex ^= secretBit;
  48. }
  49. ECPoint add = lookupTable.Lookup((int)secretIndex);
  50. R = R.TwicePlus(add);
  51. }
  52. return R.Add(info.Offset);
  53. }
  54. }
  55. }
  56. #pragma warning restore
  57. #endif