diff options
-rw-r--r-- | crypto/crypto.csproj | 55 | ||||
-rw-r--r-- | crypto/src/asn1/x9/ECNamedCurveTable.cs | 118 | ||||
-rw-r--r-- | crypto/src/crypto/ec/CustomNamedCurves.cs | 95 | ||||
-rw-r--r-- | crypto/src/math/field/FiniteFields.cs | 54 | ||||
-rw-r--r-- | crypto/src/math/field/GF2Polynomial.cs | 46 | ||||
-rw-r--r-- | crypto/src/math/field/GenericPolynomialExtensionField.cs | 63 | ||||
-rw-r--r-- | crypto/src/math/field/IExtensionField.cs | 12 | ||||
-rw-r--r-- | crypto/src/math/field/IFiniteField.cs | 11 | ||||
-rw-r--r-- | crypto/src/math/field/IPolynomial.cs | 15 | ||||
-rw-r--r-- | crypto/src/math/field/IPolynomialExtensionField.cs | 10 | ||||
-rw-r--r-- | crypto/src/math/field/PrimeField.cs | 44 | ||||
-rw-r--r-- | crypto/src/util/Integers.cs | 17 |
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); + } + } +} |