Files
SuperVPN/output/Libraries/BouncyCastle.Crypto/Org/BouncyCastle/Math/EC/F2mFieldElement.cs
2025-10-09 09:57:24 +09:00

265 lines
5.7 KiB
C#

using System;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Math.EC;
public 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];
}
}
[Obsolete("Use ECCurve.FromBigInteger to construct field elements")]
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);
}
[Obsolete("Use ECCurve.FromBigInteger to construct field elements")]
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;
}
if (!(obj is F2mFieldElement other))
{
return false;
}
return Equals(other);
}
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);
}
}