summary refs log tree commit diff
path: root/Crypto/src/asn1/x9/X9Curve.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/asn1/x9/X9Curve.cs')
-rw-r--r--Crypto/src/asn1/x9/X9Curve.cs147
1 files changed, 147 insertions, 0 deletions
diff --git a/Crypto/src/asn1/x9/X9Curve.cs b/Crypto/src/asn1/x9/X9Curve.cs
new file mode 100644
index 000000000..b92e7b3b5
--- /dev/null
+++ b/Crypto/src/asn1/x9/X9Curve.cs
@@ -0,0 +1,147 @@
+using System;
+
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Asn1.X9
+{
+    /**
+     * ASN.1 def for Elliptic-Curve Curve structure. See
+     * X9.62, for further details.
+     */
+    public class X9Curve
+        : Asn1Encodable
+    {
+        private readonly ECCurve curve;
+        private readonly byte[] seed;
+		private readonly DerObjectIdentifier fieldIdentifier;
+
+		public X9Curve(
+            ECCurve curve)
+			: this(curve, null)
+        {
+            this.curve = curve;
+        }
+
+		public X9Curve(
+            ECCurve	curve,
+            byte[]	seed)
+        {
+			if (curve == null)
+				throw new ArgumentNullException("curve");
+
+			this.curve = curve;
+            this.seed = Arrays.Clone(seed);
+
+			if (curve is FpCurve)
+			{
+				this.fieldIdentifier = X9ObjectIdentifiers.PrimeField;
+			}
+			else if (curve is F2mCurve)
+			{
+				this.fieldIdentifier = X9ObjectIdentifiers.CharacteristicTwoField;
+			}
+			else
+			{
+				throw new ArgumentException("This type of ECCurve is not implemented");
+			}
+		}
+
+		public X9Curve(
+            X9FieldID		fieldID,
+            Asn1Sequence	seq)
+        {
+			if (fieldID == null)
+				throw new ArgumentNullException("fieldID");
+			if (seq == null)
+				throw new ArgumentNullException("seq");
+
+			this.fieldIdentifier = fieldID.Identifier;
+
+			if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField))
+            {
+                BigInteger q = ((DerInteger) fieldID.Parameters).Value;
+                X9FieldElement x9A = new X9FieldElement(q, (Asn1OctetString) seq[0]);
+                X9FieldElement x9B = new X9FieldElement(q, (Asn1OctetString) seq[1]);
+                curve = new FpCurve(q, x9A.Value.ToBigInteger(), x9B.Value.ToBigInteger());
+            }
+            else
+            {
+				if (fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField)) 
+				{
+					// Characteristic two field
+					DerSequence parameters = (DerSequence)fieldID.Parameters;
+					int m = ((DerInteger)parameters[0]).Value.IntValue;
+					DerObjectIdentifier representation
+						= (DerObjectIdentifier)parameters[1];
+
+					int k1 = 0;
+					int k2 = 0;
+					int k3 = 0;
+					if (representation.Equals(X9ObjectIdentifiers.TPBasis)) 
+					{
+						// Trinomial basis representation
+						k1 = ((DerInteger)parameters[2]).Value.IntValue;
+					}
+					else 
+					{
+						// Pentanomial basis representation
+						DerSequence pentanomial = (DerSequence) parameters[2];
+						k1 = ((DerInteger) pentanomial[0]).Value.IntValue;
+						k2 = ((DerInteger) pentanomial[1]).Value.IntValue;
+						k3 = ((DerInteger) pentanomial[2]).Value.IntValue;
+					}
+					X9FieldElement x9A = new X9FieldElement(m, k1, k2, k3, (Asn1OctetString)seq[0]);
+					X9FieldElement x9B = new X9FieldElement(m, k1, k2, k3, (Asn1OctetString)seq[1]);
+					// TODO Is it possible to get the order (n) and cofactor(h) too?
+					curve = new F2mCurve(m, k1, k2, k3, x9A.Value.ToBigInteger(), x9B.Value.ToBigInteger());
+				}
+			}
+
+			if (seq.Count == 3)
+            {
+                seed = ((DerBitString) seq[2]).GetBytes();
+            }
+        }
+
+		public ECCurve Curve
+        {
+			get { return curve; }
+        }
+
+		public byte[] GetSeed()
+        {
+            return Arrays.Clone(seed);
+        }
+
+		/**
+         * Produce an object suitable for an Asn1OutputStream.
+         * <pre>
+         *  Curve ::= Sequence {
+         *      a               FieldElement,
+         *      b               FieldElement,
+         *      seed            BIT STRING      OPTIONAL
+         *  }
+         * </pre>
+         */
+        public override Asn1Object ToAsn1Object()
+        {
+			Asn1EncodableVector v = new Asn1EncodableVector();
+
+			if (fieldIdentifier.Equals(X9ObjectIdentifiers.PrimeField)
+				|| fieldIdentifier.Equals(X9ObjectIdentifiers.CharacteristicTwoField)) 
+			{ 
+				v.Add(new X9FieldElement(curve.A).ToAsn1Object());
+				v.Add(new X9FieldElement(curve.B).ToAsn1Object());
+			} 
+
+			if (seed != null)
+			{
+				v.Add(new DerBitString(seed));
+			}
+
+			return new DerSequence(v);
+		}
+    }
+}