diff --git a/crypto/src/math/field/FiniteFields.cs b/crypto/src/math/field/FiniteFields.cs
new file mode 100644
index 000000000..7b84569fe
--- /dev/null
+++ b/crypto/src/math/field/FiniteFields.cs
@@ -0,0 +1,54 @@
+using System;
+
+namespace Org.BouncyCastle.Math.Field
+{
+ public abstract class FiniteFields
+ {
+ internal static readonly IFiniteField GF_2 = new PrimeField(BigInteger.ValueOf(2));
+ internal static readonly IFiniteField GF_3 = new PrimeField(BigInteger.ValueOf(3));
+
+ public static IPolynomialExtensionField GetBinaryExtensionField(int[] exponents)
+ {
+ if (exponents[0] != 0)
+ {
+ throw new ArgumentException("Irreducible polynomials in GF(2) must have constant term", "exponents");
+ }
+ for (int i = 1; i < exponents.Length; ++i)
+ {
+ if (exponents[i] <= exponents[i - 1])
+ {
+ throw new ArgumentException("Polynomial exponents must be montonically increasing", "exponents");
+ }
+ }
+
+ return new GenericPolynomialExtensionField(GF_2, new GF2Polynomial(exponents));
+ }
+
+ // public static IPolynomialExtensionField GetTernaryExtensionField(Term[] terms)
+ // {
+ // return new GenericPolynomialExtensionField(GF_3, new GF3Polynomial(terms));
+ // }
+
+ public static IFiniteField GetPrimeField(BigInteger characteristic)
+ {
+ int bitLength = characteristic.BitLength;
+ if (characteristic.SignValue <= 0 || bitLength < 2)
+ {
+ throw new ArgumentException("Must be >= 2", "characteristic");
+ }
+
+ if (bitLength < 3)
+ {
+ switch (characteristic.IntValue)
+ {
+ case 2:
+ return GF_2;
+ case 3:
+ return GF_3;
+ }
+ }
+
+ return new PrimeField(characteristic);
+ }
+ }
+}
diff --git a/crypto/src/math/field/GF2Polynomial.cs b/crypto/src/math/field/GF2Polynomial.cs
new file mode 100644
index 000000000..c062d508a
--- /dev/null
+++ b/crypto/src/math/field/GF2Polynomial.cs
@@ -0,0 +1,46 @@
+using System;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Math.Field
+{
+ internal class GF2Polynomial
+ : IPolynomial
+ {
+ protected readonly int[] exponents;
+
+ internal GF2Polynomial(int[] exponents)
+ {
+ this.exponents = Arrays.Clone(exponents);
+ }
+
+ public virtual int Degree
+ {
+ get { return exponents[exponents.Length - 1]; }
+ }
+
+ public virtual int[] GetExponentsPresent()
+ {
+ return Arrays.Clone(exponents);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ GF2Polynomial other = obj as GF2Polynomial;
+ if (null == other)
+ {
+ return false;
+ }
+ return Arrays.AreEqual(exponents, other.exponents);
+ }
+
+ public override int GetHashCode()
+ {
+ return Arrays.GetHashCode(exponents);
+ }
+ }
+}
diff --git a/crypto/src/math/field/GenericPolynomialExtensionField.cs b/crypto/src/math/field/GenericPolynomialExtensionField.cs
new file mode 100644
index 000000000..13ef57165
--- /dev/null
+++ b/crypto/src/math/field/GenericPolynomialExtensionField.cs
@@ -0,0 +1,63 @@
+using System;
+
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Math.Field
+{
+ internal class GenericPolynomialExtensionField
+ : IPolynomialExtensionField
+ {
+ protected readonly IFiniteField subfield;
+ protected readonly IPolynomial minimalPolynomial;
+
+ internal GenericPolynomialExtensionField(IFiniteField subfield, IPolynomial polynomial)
+ {
+ this.subfield = subfield;
+ this.minimalPolynomial = polynomial;
+ }
+
+ public virtual BigInteger Characteristic
+ {
+ get { return subfield.Characteristic; }
+ }
+
+ public virtual int Dimension
+ {
+ get { return subfield.Dimension * minimalPolynomial.Degree; }
+ }
+
+ public virtual IFiniteField Subfield
+ {
+ get { return subfield; }
+ }
+
+ public virtual int Degree
+ {
+ get { return minimalPolynomial.Degree; }
+ }
+
+ public virtual IPolynomial MinimalPolynomial
+ {
+ get { return minimalPolynomial; }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ GenericPolynomialExtensionField other = obj as GenericPolynomialExtensionField;
+ if (null == other)
+ {
+ return false;
+ }
+ return subfield.Equals(other.subfield) && minimalPolynomial.Equals(other.minimalPolynomial);
+ }
+
+ public override int GetHashCode()
+ {
+ return subfield.GetHashCode() ^ Integers.RotateLeft(minimalPolynomial.GetHashCode(), 16);
+ }
+ }
+}
diff --git a/crypto/src/math/field/IExtensionField.cs b/crypto/src/math/field/IExtensionField.cs
new file mode 100644
index 000000000..17f45c153
--- /dev/null
+++ b/crypto/src/math/field/IExtensionField.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Org.BouncyCastle.Math.Field
+{
+ public interface IExtensionField
+ : IFiniteField
+ {
+ IFiniteField Subfield { get; }
+
+ int Degree { get; }
+ }
+}
diff --git a/crypto/src/math/field/IFiniteField.cs b/crypto/src/math/field/IFiniteField.cs
new file mode 100644
index 000000000..b618be74b
--- /dev/null
+++ b/crypto/src/math/field/IFiniteField.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace Org.BouncyCastle.Math.Field
+{
+ public interface IFiniteField
+ {
+ BigInteger Characteristic { get; }
+
+ int Dimension { get; }
+ }
+}
diff --git a/crypto/src/math/field/IPolynomial.cs b/crypto/src/math/field/IPolynomial.cs
new file mode 100644
index 000000000..ad6dfb662
--- /dev/null
+++ b/crypto/src/math/field/IPolynomial.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Org.BouncyCastle.Math.Field
+{
+ public interface IPolynomial
+ {
+ int Degree { get; }
+
+ //BigInteger[] GetCoefficients();
+
+ int[] GetExponentsPresent();
+
+ //Term[] GetNonZeroTerms();
+ }
+}
diff --git a/crypto/src/math/field/IPolynomialExtensionField.cs b/crypto/src/math/field/IPolynomialExtensionField.cs
new file mode 100644
index 000000000..3818c1855
--- /dev/null
+++ b/crypto/src/math/field/IPolynomialExtensionField.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Org.BouncyCastle.Math.Field
+{
+ public interface IPolynomialExtensionField
+ : IExtensionField
+ {
+ IPolynomial MinimalPolynomial { get; }
+ }
+}
diff --git a/crypto/src/math/field/PrimeField.cs b/crypto/src/math/field/PrimeField.cs
new file mode 100644
index 000000000..f6ba629d5
--- /dev/null
+++ b/crypto/src/math/field/PrimeField.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace Org.BouncyCastle.Math.Field
+{
+ internal class PrimeField
+ : IFiniteField
+ {
+ protected readonly BigInteger characteristic;
+
+ internal PrimeField(BigInteger characteristic)
+ {
+ this.characteristic = characteristic;
+ }
+
+ public virtual BigInteger Characteristic
+ {
+ get { return characteristic; }
+ }
+
+ public virtual int Dimension
+ {
+ get { return 1; }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ PrimeField other = obj as PrimeField;
+ if (null == other)
+ {
+ return false;
+ }
+ return characteristic.Equals(other.characteristic);
+ }
+
+ public override int GetHashCode()
+ {
+ return characteristic.GetHashCode();
+ }
+ }
+}
|