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

AbstractF2mCurve

public abstract class AbstractF2mCurve : ECCurve
using Org.BouncyCastle.Math.Field; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Math.EC { public abstract class AbstractF2mCurve : ECCurve { public virtual bool IsKoblitz { get { if (m_order != null && m_cofactor != null && m_b.IsOne) { if (!m_a.IsZero) return m_a.IsOne; return true; } return false; } } public static BigInteger Inverse(int m, int[] ks, BigInteger x) { LongArray longArray = new LongArray(x); longArray = longArray.ModInverse(m, ks); return longArray.ToBigInteger(); } private static IFiniteField BuildField(int m, int k1, int k2, int k3) { int num = ECCurve.ImplGetInteger("Org.BouncyCastle.EC.F2m_MaxSize", 1142); if (m > num) throw new ArgumentException("F2m m value out of range"); return FiniteFields.GetBinaryExtensionField(((k2 | k3) != 0) ? new int[5] { 0, k1, k2, k3, m } : new int[3] { 0, k1, m }); } protected AbstractF2mCurve(int m, int k1, int k2, int k3) : base(BuildField(m, k1, k2, k3)) { } public override ECPoint CreatePoint(BigInteger x, BigInteger y) { ECFieldElement eCFieldElement = FromBigInteger(x); ECFieldElement eCFieldElement2 = FromBigInteger(y); int coordinateSystem = CoordinateSystem; if ((uint)(coordinateSystem - 5) <= 1) { if (eCFieldElement.IsZero) { if (!eCFieldElement2.Square().Equals(B)) throw new ArgumentException(); } else eCFieldElement2 = eCFieldElement2.Divide(eCFieldElement).Add(eCFieldElement); } return CreateRawPoint(eCFieldElement, eCFieldElement2); } public override bool IsValidFieldElement(BigInteger x) { if (x != null && x.SignValue >= 0) return x.BitLength <= FieldSize; return false; } public override ECFieldElement RandomFieldElement(SecureRandom r) { int fieldSize = FieldSize; return FromBigInteger(BigIntegers.CreateRandomBigInteger(fieldSize, r)); } public override ECFieldElement RandomFieldElementMult(SecureRandom r) { int fieldSize = FieldSize; ECFieldElement eCFieldElement = FromBigInteger(ImplRandomFieldElementMult(r, fieldSize)); ECFieldElement b = FromBigInteger(ImplRandomFieldElementMult(r, fieldSize)); return eCFieldElement.Multiply(b); } protected override ECPoint DecompressPoint(int yTilde, BigInteger X1) { ECFieldElement eCFieldElement = FromBigInteger(X1); ECFieldElement eCFieldElement2 = null; if (eCFieldElement.IsZero) eCFieldElement2 = B.Sqrt(); else { ECFieldElement beta = eCFieldElement.Square().Invert().Multiply(B) .Add(A) .Add(eCFieldElement); ECFieldElement eCFieldElement3 = SolveQuadraticEquation(beta); if (eCFieldElement3 != null) { if (eCFieldElement3.TestBitZero() != (yTilde == 1)) eCFieldElement3 = eCFieldElement3.AddOne(); int coordinateSystem = CoordinateSystem; eCFieldElement2 = (((uint)(coordinateSystem - 5) > 1) ? eCFieldElement3.Multiply(eCFieldElement) : eCFieldElement3.Add(eCFieldElement)); } } if (eCFieldElement2 == null) throw new ArgumentException("Invalid point compression"); return CreateRawPoint(eCFieldElement, eCFieldElement2); } internal ECFieldElement SolveQuadraticEquation(ECFieldElement beta) { AbstractF2mFieldElement abstractF2mFieldElement = (AbstractF2mFieldElement)beta; bool hasFastTrace = abstractF2mFieldElement.HasFastTrace; if (hasFastTrace && abstractF2mFieldElement.Trace() != 0) return null; int fieldSize = FieldSize; if ((fieldSize & 1) != 0) { ECFieldElement eCFieldElement = abstractF2mFieldElement.HalfTrace(); if (hasFastTrace || eCFieldElement.Square().Add(eCFieldElement).Add(beta) .IsZero) return eCFieldElement; return null; } if (beta.IsZero) return beta; ECFieldElement eCFieldElement2 = FromBigInteger(BigInteger.Zero); ECFieldElement eCFieldElement3; ECFieldElement eCFieldElement6; do { ECFieldElement b = FromBigInteger(BigInteger.Arbitrary(fieldSize)); eCFieldElement3 = eCFieldElement2; ECFieldElement eCFieldElement4 = beta; for (int i = 1; i < fieldSize; i++) { ECFieldElement eCFieldElement5 = eCFieldElement4.Square(); eCFieldElement3 = eCFieldElement3.Square().Add(eCFieldElement5.Multiply(b)); eCFieldElement4 = eCFieldElement5.Add(beta); } if (!eCFieldElement4.IsZero) return null; eCFieldElement6 = eCFieldElement3.Square().Add(eCFieldElement3); } while (eCFieldElement6.IsZero); return eCFieldElement3; } private static BigInteger ImplRandomFieldElementMult(SecureRandom r, int m) { BigInteger bigInteger; do { bigInteger = BigIntegers.CreateRandomBigInteger(m, r); } while (bigInteger.SignValue <= 0); return bigInteger; } } }