<PackageReference Include="SSH.NET" Version="2024.0.0" />

F2mCurve

using Renci.SshNet.Security.Org.BouncyCastle.Math.EC.Multiplier; using System; namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC { internal class F2mCurve : AbstractF2mCurve { private class DefaultF2mLookupTable : ECLookupTable { private readonly F2mCurve m_outer; private readonly long[] m_table; private readonly int m_size; public virtual int Size => m_size; internal DefaultF2mLookupTable(F2mCurve outer, long[] table, int size) { m_outer = outer; m_table = table; m_size = size; } public virtual ECPoint Lookup(int index) { int m = m_outer.m; int[] ks = (!m_outer.IsTrinomial()) ? new int[3] { m_outer.k1, m_outer.k2, m_outer.k3 } : new int[1] { m_outer.k1 }; int num = (m_outer.m + 63) / 64; long[] array = new long[num]; long[] array2 = new long[num]; int num2 = 0; for (int i = 0; i < m_size; i++) { long num3 = (i ^ index) - 1 >> 31; for (int j = 0; j < num; j++) { array[j] ^= (m_table[num2 + j] & num3); array2[j] ^= (m_table[num2 + num + j] & num3); } num2 += num * 2; } ECFieldElement x = new F2mFieldElement(m, ks, new LongArray(array)); ECFieldElement y = new F2mFieldElement(m, ks, new LongArray(array2)); return m_outer.CreateRawPoint(x, y, false); } } private const int F2M_DEFAULT_COORDS = 6; private readonly int m; private readonly int k1; private readonly int k2; private readonly int k3; protected readonly F2mPoint m_infinity; public override int FieldSize => m; public override ECPoint Infinity => m_infinity; public int M => m; public int K1 => k1; public int K2 => k2; public int K3 => k3; [Obsolete("Use constructor taking order/cofactor")] public F2mCurve(int m, int k, BigInteger a, BigInteger b) : this(m, k, 0, 0, a, b, null, null) { } public F2mCurve(int m, int k, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor) : this(m, k, 0, 0, a, b, order, cofactor) { } [Obsolete("Use constructor taking order/cofactor")] public F2mCurve(int m, int k1, int k2, int k3, BigInteger a, BigInteger b) : this(m, k1, k2, k3, a, b, null, null) { } public F2mCurve(int m, int k1, int k2, int k3, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor) : base(m, k1, k2, k3) { this.m = m; this.k1 = k1; this.k2 = k2; this.k3 = k3; m_order = order; m_cofactor = cofactor; m_infinity = new F2mPoint(this, null, null, false); if (k1 == 0) throw new ArgumentException("k1 must be > 0"); if (k2 == 0) { if (k3 != 0) throw new ArgumentException("k3 must be 0 if k2 == 0"); } else { if (k2 <= k1) throw new ArgumentException("k2 must be > k1"); if (k3 <= k2) throw new ArgumentException("k3 must be > k2"); } m_a = FromBigInteger(a); m_b = FromBigInteger(b); m_coord = 6; } protected F2mCurve(int m, int k1, int k2, int k3, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor) : base(m, k1, k2, k3) { this.m = m; this.k1 = k1; this.k2 = k2; this.k3 = k3; m_order = order; m_cofactor = cofactor; m_infinity = new F2mPoint(this, null, null, false); m_a = a; m_b = b; m_coord = 6; } protected override ECCurve CloneCurve() { return new F2mCurve(m, k1, k2, k3, m_a, m_b, m_order, m_cofactor); } public override bool SupportsCoordinateSystem(int coord) { if ((uint)coord <= 1 || coord == 6) return true; return false; } protected override ECMultiplier CreateDefaultMultiplier() { if (IsKoblitz) return new WTauNafMultiplier(); return base.CreateDefaultMultiplier(); } public override ECFieldElement FromBigInteger(BigInteger x) { return new F2mFieldElement(m, k1, k2, k3, x); } protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, bool withCompression) { return new F2mPoint(this, x, y, withCompression); } protected internal override ECPoint CreateRawPoint(ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) { return new F2mPoint(this, x, y, zs, withCompression); } public bool IsTrinomial() { if (k2 == 0) return k3 == 0; return false; } public override ECLookupTable CreateCacheSafeLookupTable(ECPoint[] points, int off, int len) { int num = (m + 63) / 64; long[] array = new long[len * num * 2]; int num2 = 0; for (int i = 0; i < len; i++) { ECPoint obj = points[off + i]; ((F2mFieldElement)obj.RawXCoord).x.CopyTo(array, num2); num2 += num; ((F2mFieldElement)obj.RawYCoord).x.CopyTo(array, num2); num2 += num; } return new DefaultF2mLookupTable(this, array, len); } } }