diff options
Diffstat (limited to 'Crypto/src/asn1/x9/X9ECParameters.cs')
-rw-r--r-- | Crypto/src/asn1/x9/X9ECParameters.cs | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/Crypto/src/asn1/x9/X9ECParameters.cs b/Crypto/src/asn1/x9/X9ECParameters.cs new file mode 100644 index 000000000..d025b36ce --- /dev/null +++ b/Crypto/src/asn1/x9/X9ECParameters.cs @@ -0,0 +1,170 @@ +using System; + +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Asn1.X9 +{ + /** + * ASN.1 def for Elliptic-Curve ECParameters structure. See + * X9.62, for further details. + */ + public class X9ECParameters + : Asn1Encodable + { + private X9FieldID fieldID; + private ECCurve curve; + private ECPoint g; + private BigInteger n; + private BigInteger h; + private byte[] seed; + + public X9ECParameters( + Asn1Sequence seq) + { + if (!(seq[0] is DerInteger) + || !((DerInteger) seq[0]).Value.Equals(BigInteger.One)) + { + throw new ArgumentException("bad version in X9ECParameters"); + } + + X9Curve x9c = null; + if (seq[2] is X9Curve) + { + x9c = (X9Curve) seq[2]; + } + else + { + x9c = new X9Curve( + new X9FieldID( + (Asn1Sequence) seq[1]), + (Asn1Sequence) seq[2]); + } + + this.curve = x9c.Curve; + + if (seq[3] is X9ECPoint) + { + this.g = ((X9ECPoint) seq[3]).Point; + } + else + { + this.g = new X9ECPoint(curve, (Asn1OctetString) seq[3]).Point; + } + + this.n = ((DerInteger) seq[4]).Value; + this.seed = x9c.GetSeed(); + + if (seq.Count == 6) + { + this.h = ((DerInteger) seq[5]).Value; + } + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n) + : this(curve, g, n, BigInteger.One, null) + { + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h) + : this(curve, g, n, h, null) + { + } + + public X9ECParameters( + ECCurve curve, + ECPoint g, + BigInteger n, + BigInteger h, + byte[] seed) + { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + this.seed = seed; + + if (curve is FpCurve) + { + this.fieldID = new X9FieldID(((FpCurve) curve).Q); + } + else if (curve is F2mCurve) + { + F2mCurve curveF2m = (F2mCurve) curve; + this.fieldID = new X9FieldID(curveF2m.M, curveF2m.K1, + curveF2m.K2, curveF2m.K3); + } + } + + public ECCurve Curve + { + get { return curve; } + } + + public ECPoint G + { + get { return g; } + } + + public BigInteger N + { + get { return n; } + } + + public BigInteger H + { + get + { + if (h == null) + { + // TODO - this should be calculated, it will cause issues with custom curves. + return BigInteger.One; + } + + return h; + } + } + + public byte[] GetSeed() + { + return seed; + } + + /** + * Produce an object suitable for an Asn1OutputStream. + * <pre> + * ECParameters ::= Sequence { + * version Integer { ecpVer1(1) } (ecpVer1), + * fieldID FieldID {{FieldTypes}}, + * curve X9Curve, + * base X9ECPoint, + * order Integer, + * cofactor Integer OPTIONAL + * } + * </pre> + */ + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector( + new DerInteger(1), + fieldID, + new X9Curve(curve, seed), + new X9ECPoint(g), + new DerInteger(n)); + + if (h != null) + { + v.Add(new DerInteger(h)); + } + + return new DerSequence(v); + } + } +} |