<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />

FixedPointCombMultiplier

using Org.BouncyCastle.Math.Raw; using System; namespace Org.BouncyCastle.Math.EC.Multiplier { public class FixedPointCombMultiplier : AbstractECMultiplier { protected unsafe override ECPoint MultiplyPositive(ECPoint p, BigInteger k) { ECCurve curve = p.Curve; int combSize = FixedPointUtilities.GetCombSize(curve); if (k.BitLength > combSize) throw new InvalidOperationException("fixed-point comb doesn't support scalars larger than the curve order"); FixedPointPreCompInfo fixedPointPreCompInfo = FixedPointUtilities.Precompute(p); ECLookupTable lookupTable = fixedPointPreCompInfo.LookupTable; int width = fixedPointPreCompInfo.Width; int num = (combSize + width - 1) / width; int num2 = num * width; int lengthForBits = Nat.GetLengthForBits(num2); Span<uint> span; if (lengthForBits <= 64) { int num3 = lengthForBits; span = new Span<uint>(stackalloc byte[(int)checked(unchecked((ulong)(uint)num3) * 4)], num3); } else span = new uint[lengthForBits]; Span<uint> z = span; Nat.FromBigInteger(num2, k, z); ECPoint eCPoint = curve.Infinity; for (int i = 1; i <= num; i++) { uint num4 = 0; for (int num5 = num2 - i; num5 >= 0; num5 -= num) { uint num6 = z[num5 >> 5] >> num5; num4 ^= num6 >> 1; num4 <<= 1; num4 ^= num6; } ECPoint b = lookupTable.Lookup((int)num4); eCPoint = eCPoint.TwicePlus(b); } return eCPoint.Add(fixedPointPreCompInfo.Offset); } } }