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

F2mFieldElement

using Renci.SshNet.Security.Org.BouncyCastle.Utilities; using System; namespace Renci.SshNet.Security.Org.BouncyCastle.Math.EC { internal class F2mFieldElement : AbstractF2mFieldElement { public const int Gnb = 1; public const int Tpb = 2; public const int Ppb = 3; private int representation; private int m; private int[] ks; internal LongArray x; public override int BitLength => x.Degree(); public override bool IsOne => x.IsOne(); public override bool IsZero => x.IsZero(); public override string FieldName => "F2m"; public override int FieldSize => m; public int Representation => representation; public int M => m; public int K1 => ks[0]; public int K2 { get { if (ks.Length < 2) return 0; return ks[1]; } } public int K3 { get { if (ks.Length < 3) return 0; return ks[2]; } } public F2mFieldElement(int m, int k1, int k2, int k3, BigInteger x) { if (x == null || x.SignValue < 0 || x.BitLength > m) throw new ArgumentException("value invalid in F2m field element", "x"); if (k2 == 0 && k3 == 0) { representation = 2; ks = new int[1] { k1 }; } else { if (k2 >= k3) throw new ArgumentException("k2 must be smaller than k3"); if (k2 <= 0) throw new ArgumentException("k2 must be larger than 0"); representation = 3; ks = new int[3] { k1, k2, k3 }; } this.m = m; this.x = new LongArray(x); } public F2mFieldElement(int m, int k, BigInteger x) : this(m, k, 0, 0, x) { } internal F2mFieldElement(int m, int[] ks, LongArray x) { this.m = m; representation = ((ks.Length == 1) ? 2 : 3); this.ks = ks; this.x = x; } public override bool TestBitZero() { return x.TestBitZero(); } public override BigInteger ToBigInteger() { return x.ToBigInteger(); } public static void CheckFieldElements(ECFieldElement a, ECFieldElement b) { if (!(a is F2mFieldElement) || !(b is F2mFieldElement)) throw new ArgumentException("Field elements are not both instances of F2mFieldElement"); F2mFieldElement f2mFieldElement = (F2mFieldElement)a; F2mFieldElement f2mFieldElement2 = (F2mFieldElement)b; if (f2mFieldElement.representation != f2mFieldElement2.representation) throw new ArgumentException("One of the F2m field elements has incorrect representation"); if (f2mFieldElement.m != f2mFieldElement2.m || !Arrays.AreEqual(f2mFieldElement.ks, f2mFieldElement2.ks)) throw new ArgumentException("Field elements are not elements of the same field F2m"); } public override ECFieldElement Add(ECFieldElement b) { LongArray longArray = x.Copy(); F2mFieldElement f2mFieldElement = (F2mFieldElement)b; longArray.AddShiftedByWords(f2mFieldElement.x, 0); return new F2mFieldElement(m, ks, longArray); } public override ECFieldElement AddOne() { return new F2mFieldElement(m, ks, x.AddOne()); } public override ECFieldElement Subtract(ECFieldElement b) { return Add(b); } public override ECFieldElement Multiply(ECFieldElement b) { return new F2mFieldElement(m, ks, x.ModMultiply(((F2mFieldElement)b).x, m, ks)); } public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) { return MultiplyPlusProduct(b, x, y); } public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y) { LongArray longArray = this.x; LongArray longArray2 = ((F2mFieldElement)b).x; LongArray longArray3 = ((F2mFieldElement)x).x; LongArray other = ((F2mFieldElement)y).x; LongArray longArray4 = longArray.Multiply(longArray2, m, ks); LongArray other2 = longArray3.Multiply(other, m, ks); if (longArray4 == longArray || longArray4 == longArray2) longArray4 = longArray4.Copy(); longArray4.AddShiftedByWords(other2, 0); longArray4.Reduce(m, ks); return new F2mFieldElement(m, ks, longArray4); } public override ECFieldElement Divide(ECFieldElement b) { ECFieldElement b2 = b.Invert(); return Multiply(b2); } public override ECFieldElement Negate() { return this; } public override ECFieldElement Square() { return new F2mFieldElement(m, ks, x.ModSquare(m, ks)); } public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y) { return SquarePlusProduct(x, y); } public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y) { LongArray longArray = this.x; LongArray longArray2 = ((F2mFieldElement)x).x; LongArray other = ((F2mFieldElement)y).x; LongArray longArray3 = longArray.Square(m, ks); LongArray other2 = longArray2.Multiply(other, m, ks); if (longArray3 == longArray) longArray3 = longArray3.Copy(); longArray3.AddShiftedByWords(other2, 0); longArray3.Reduce(m, ks); return new F2mFieldElement(m, ks, longArray3); } public override ECFieldElement SquarePow(int pow) { if (pow >= 1) return new F2mFieldElement(m, ks, x.ModSquareN(pow, m, ks)); return this; } public override ECFieldElement Invert() { return new F2mFieldElement(m, ks, x.ModInverse(m, ks)); } public override ECFieldElement Sqrt() { if (!x.IsZero() && !x.IsOne()) return SquarePow(m - 1); return this; } public override bool Equals(object obj) { if (obj == this) return true; F2mFieldElement f2mFieldElement = obj as F2mFieldElement; if (f2mFieldElement == null) return false; return Equals(f2mFieldElement); } public virtual bool Equals(F2mFieldElement other) { if (m == other.m && representation == other.representation && Arrays.AreEqual(ks, other.ks)) return x.Equals(other.x); return false; } public override int GetHashCode() { return x.GetHashCode() ^ m ^ Arrays.GetHashCode(ks); } } }