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

WTauNafMultiplier

using Org.BouncyCastle.Math.EC.Abc; using System; namespace Org.BouncyCastle.Math.EC.Multiplier { public class WTauNafMultiplier : AbstractECMultiplier { private class WTauNafCallback : IPreCompCallback { private readonly AbstractF2mPoint m_p; private readonly sbyte m_a; internal WTauNafCallback(AbstractF2mPoint p, sbyte a) { m_p = p; m_a = a; } public PreCompInfo Precompute(PreCompInfo existing) { if (existing is WTauNafPreCompInfo) return existing; return new WTauNafPreCompInfo { PreComp = Tnaf.GetPreComp(m_p, m_a) }; } } internal static readonly string PRECOMP_NAME = "bc_wtnaf"; protected override ECPoint MultiplyPositive(ECPoint point, BigInteger k) { AbstractF2mPoint abstractF2mPoint = point as AbstractF2mPoint; if (abstractF2mPoint == null) throw new ArgumentException("Only AbstractF2mPoint can be used in WTauNafMultiplier"); AbstractF2mCurve obj = (AbstractF2mCurve)abstractF2mPoint.Curve; sbyte b = (sbyte)obj.A.ToBigInteger().IntValue; sbyte mu = Tnaf.GetMu(b); ZTauElement lambda = Tnaf.PartModReduction(obj, k, b, mu, 10); return MultiplyWTnaf(abstractF2mPoint, lambda, b, mu); } private AbstractF2mPoint MultiplyWTnaf(AbstractF2mPoint p, ZTauElement lambda, sbyte a, sbyte mu) { ZTauElement[] alpha = (a == 0) ? Tnaf.Alpha0 : Tnaf.Alpha1; BigInteger tw = Tnaf.GetTw(mu, 4); sbyte[] u = Tnaf.TauAdicWNaf(mu, lambda, 4, tw.IntValue, alpha); return MultiplyFromWTnaf(p, u); } private static AbstractF2mPoint MultiplyFromWTnaf(AbstractF2mPoint p, sbyte[] u) { AbstractF2mCurve obj = (AbstractF2mCurve)p.Curve; sbyte a = (sbyte)obj.A.ToBigInteger().IntValue; AbstractF2mPoint[] preComp = ((WTauNafPreCompInfo)obj.Precompute(callback: new WTauNafCallback(p, a), point: p, name: PRECOMP_NAME)).PreComp; AbstractF2mPoint[] array = new AbstractF2mPoint[preComp.Length]; for (int i = 0; i < preComp.Length; i++) { array[i] = (AbstractF2mPoint)preComp[i].Negate(); } AbstractF2mPoint abstractF2mPoint = (AbstractF2mPoint)p.Curve.Infinity; int num = 0; for (int num2 = u.Length - 1; num2 >= 0; num2--) { num++; int num3 = u[num2]; if (num3 != 0) { abstractF2mPoint = abstractF2mPoint.TauPow(num); num = 0; ECPoint b = (num3 > 0) ? preComp[num3 >> 1] : array[-num3 >> 1]; abstractF2mPoint = (AbstractF2mPoint)abstractF2mPoint.Add(b); } } if (num > 0) abstractF2mPoint = abstractF2mPoint.TauPow(num); return abstractF2mPoint; } } }