summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2014-01-21 16:19:11 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2014-01-21 16:19:11 +0700
commit0d74a23f78cc18401b5f746a97faf1f43003655f (patch)
treea4aee2333d364a49b947f371924d2e5d3bc53bd6
parentUse ECCurve.CreatePoint (diff)
downloadBouncyCastle.NET-ed25519-0d74a23f78cc18401b5f746a97faf1f43003655f.tar.xz
Add new classes in Math.Field and some other EC-related stuff from Java
-rw-r--r--crypto/crypto.csproj55
-rw-r--r--crypto/src/asn1/x9/ECNamedCurveTable.cs118
-rw-r--r--crypto/src/crypto/ec/CustomNamedCurves.cs95
-rw-r--r--crypto/src/math/field/FiniteFields.cs54
-rw-r--r--crypto/src/math/field/GF2Polynomial.cs46
-rw-r--r--crypto/src/math/field/GenericPolynomialExtensionField.cs63
-rw-r--r--crypto/src/math/field/IExtensionField.cs12
-rw-r--r--crypto/src/math/field/IFiniteField.cs11
-rw-r--r--crypto/src/math/field/IPolynomial.cs15
-rw-r--r--crypto/src/math/field/IPolynomialExtensionField.cs10
-rw-r--r--crypto/src/math/field/PrimeField.cs44
-rw-r--r--crypto/src/util/Integers.cs17
12 files changed, 540 insertions, 0 deletions
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj
index 9ebe947e1..2a326e384 100644
--- a/crypto/crypto.csproj
+++ b/crypto/crypto.csproj
@@ -2199,6 +2199,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\asn1\x9\ECNamedCurveTable.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\asn1\x9\KeySpecificInfo.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -3259,6 +3264,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\crypto\ec\CustomNamedCurves.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\crypto\encodings\ISO9796d1Encoding.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -4669,6 +4679,46 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\math\field\FiniteFields.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "src\math\field\GF2Polynomial.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "src\math\field\GenericPolynomialExtensionField.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "src\math\field\IExtensionField.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "src\math\field\IFiniteField.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "src\math\field\IPolynomial.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "src\math\field\IPolynomialExtensionField.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "src\math\field\PrimeField.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\ocsp\BasicOCSPResp.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -5369,6 +5419,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "src\util\Integers.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "src\util\Platform.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
diff --git a/crypto/src/asn1/x9/ECNamedCurveTable.cs b/crypto/src/asn1/x9/ECNamedCurveTable.cs
new file mode 100644
index 000000000..0030d376b
--- /dev/null
+++ b/crypto/src/asn1/x9/ECNamedCurveTable.cs
@@ -0,0 +1,118 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Sec;
+using Org.BouncyCastle.Asn1.TeleTrust;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
+
+namespace Org.BouncyCastle.Asn1.X9
+{
+    /**
+     * A general class that reads all X9.62 style EC curve tables.
+     */
+    public class ECNamedCurveTable
+    {
+        /**
+         * return a X9ECParameters object representing the passed in named
+         * curve. The routine returns null if the curve is not present.
+         *
+         * @param name the name of the curve requested
+         * @return an X9ECParameters object or null if the curve is not available.
+         */
+        public static X9ECParameters GetByName(string name)
+        {
+            X9ECParameters ecP = X962NamedCurves.GetByName(name);
+
+            if (ecP == null)
+            {
+                ecP = SecNamedCurves.GetByName(name);
+            }
+
+            if (ecP == null)
+            {
+                ecP = TeleTrusTNamedCurves.GetByName(name);
+            }
+
+            if (ecP == null)
+            {
+                ecP = NistNamedCurves.GetByName(name);
+            }
+
+            return ecP;
+        }
+
+        /**
+         * return the object identifier signified by the passed in name. Null
+         * if there is no object identifier associated with name.
+         *
+         * @return the object identifier associated with name, if present.
+         */
+        public static DerObjectIdentifier GetOid(string name)
+        {
+            DerObjectIdentifier oid = X962NamedCurves.GetOid(name);
+
+            if (oid == null)
+            {
+                oid = SecNamedCurves.GetOid(name);
+            }
+
+            if (oid == null)
+            {
+                oid = TeleTrusTNamedCurves.GetOid(name);
+            }
+
+            if (oid == null)
+            {
+                oid = NistNamedCurves.GetOid(name);
+            }
+
+            return oid;
+        }
+
+        /**
+         * return a X9ECParameters object representing the passed in named
+         * curve.
+         *
+         * @param oid the object id of the curve requested
+         * @return an X9ECParameters object or null if the curve is not available.
+         */
+        public static X9ECParameters GetByOid(DerObjectIdentifier oid)
+        {
+            X9ECParameters ecP = X962NamedCurves.GetByOid(oid);
+
+            if (ecP == null)
+            {
+                ecP = SecNamedCurves.GetByOid(oid);
+            }
+
+            if (ecP == null)
+            {
+                ecP = TeleTrusTNamedCurves.GetByOid(oid);
+            }
+
+            // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
+
+            return ecP;
+        }
+
+        /**
+         * return an enumeration of the names of the available curves.
+         *
+         * @return an enumeration of the names of the available curves.
+         */
+        public static IEnumerable Names
+        {
+            get
+            {
+                IList v = Platform.CreateArrayList();
+                CollectionUtilities.AddRange(v, X962NamedCurves.Names);
+                CollectionUtilities.AddRange(v, SecNamedCurves.Names);
+                CollectionUtilities.AddRange(v, NistNamedCurves.Names);
+                CollectionUtilities.AddRange(v, TeleTrusTNamedCurves.Names);
+                return v;
+            }
+        }
+    }
+}
diff --git a/crypto/src/crypto/ec/CustomNamedCurves.cs b/crypto/src/crypto/ec/CustomNamedCurves.cs
new file mode 100644
index 000000000..ab609fdb9
--- /dev/null
+++ b/crypto/src/crypto/ec/CustomNamedCurves.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Collections;
+
+namespace Org.BouncyCastle.Crypto.EC
+{
+    public sealed class CustomNamedCurves
+    {
+        private CustomNamedCurves()
+        {
+        }
+
+        private static ECCurve ConfigureCurve(ECCurve curve)
+        {
+            return curve;
+        }
+
+        private static readonly IDictionary objIds = Platform.CreateHashtable();
+        private static readonly IDictionary curves = Platform.CreateHashtable();
+        private static readonly IDictionary names = Platform.CreateHashtable();
+
+        private static void DefineCurve(
+            string					name,
+            DerObjectIdentifier		oid,
+            X9ECParametersHolder	holder)
+        {
+            objIds.Add(name, oid);
+            names.Add(oid, name);
+            curves.Add(oid, holder);
+        }
+
+        static CustomNamedCurves()
+        {
+        }
+
+        public static X9ECParameters GetByName(
+            string name)
+        {
+            DerObjectIdentifier oid = (DerObjectIdentifier)
+                objIds[Platform.ToLowerInvariant(name)];
+
+            return oid == null ? null : GetByOid(oid);
+        }
+
+
+        /**
+         * return the X9ECParameters object for the named curve represented by
+         * the passed in object identifier. Null if the curve isn't present.
+         *
+         * @param oid an object identifier representing a named curve, if present.
+         */
+        public static X9ECParameters GetByOid(
+            DerObjectIdentifier oid)
+        {
+            X9ECParametersHolder holder = (X9ECParametersHolder)curves[oid];
+
+            return holder == null ? null : holder.Parameters;
+        }
+
+        /**
+         * return the object identifier signified by the passed in name. Null
+         * if there is no object identifier associated with name.
+         *
+         * @return the object identifier associated with name, if present.
+         */
+        public static DerObjectIdentifier GetOid(
+            string name)
+        {
+            return (DerObjectIdentifier)objIds[Platform.ToLowerInvariant(name)];
+        }
+
+        /**
+         * return the named curve name represented by the given object identifier.
+         */
+        public static string GetName(
+            DerObjectIdentifier oid)
+        {
+            return (string)names[oid];
+        }
+
+        /**
+         * returns an enumeration containing the name strings for curves
+         * contained in this structure.
+         */
+        public static IEnumerable Names
+        {
+            get { return new EnumerableProxy(objIds.Keys); }
+        }
+    }
+}
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();
+        }
+    }
+}
diff --git a/crypto/src/util/Integers.cs b/crypto/src/util/Integers.cs
new file mode 100644
index 000000000..ccbf872c4
--- /dev/null
+++ b/crypto/src/util/Integers.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace Org.BouncyCastle.Utilities
+{
+    public abstract class Integers
+    {
+        public static int RotateLeft(int i, int distance)
+        {
+            return (i << distance) ^ (int)((uint)i >> -distance);
+        }
+
+        public static int RotateRight(int i, int distance)
+        {
+            return (int)((uint)i >> distance) ^ (i << -distance);
+        }
+    }
+}