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);
}
}
}