001: package org.bouncycastle.asn1.x9;
002:
003: import org.bouncycastle.asn1.ASN1Encodable;
004: import org.bouncycastle.asn1.ASN1EncodableVector;
005: import org.bouncycastle.asn1.ASN1OctetString;
006: import org.bouncycastle.asn1.ASN1Sequence;
007: import org.bouncycastle.asn1.DERInteger;
008: import org.bouncycastle.asn1.DERObject;
009: import org.bouncycastle.asn1.DERSequence;
010: import org.bouncycastle.math.ec.ECCurve;
011: import org.bouncycastle.math.ec.ECPoint;
012:
013: import java.math.BigInteger;
014:
015: /**
016: * ASN.1 def for Elliptic-Curve ECParameters structure. See
017: * X9.62, for further details.
018: */
019: public class X9ECParameters extends ASN1Encodable implements
020: X9ObjectIdentifiers {
021: private static final BigInteger ONE = BigInteger.valueOf(1);
022:
023: private X9FieldID fieldID;
024: private ECCurve curve;
025: private ECPoint g;
026: private BigInteger n;
027: private BigInteger h;
028: private byte[] seed;
029:
030: public X9ECParameters(ASN1Sequence seq) {
031: if (!(seq.getObjectAt(0) instanceof DERInteger)
032: || !((DERInteger) seq.getObjectAt(0)).getValue()
033: .equals(ONE)) {
034: throw new IllegalArgumentException(
035: "bad version in X9ECParameters");
036: }
037:
038: X9Curve x9c = new X9Curve(new X9FieldID((ASN1Sequence) seq
039: .getObjectAt(1)), (ASN1Sequence) seq.getObjectAt(2));
040:
041: this .curve = x9c.getCurve();
042: this .g = new X9ECPoint(curve, (ASN1OctetString) seq
043: .getObjectAt(3)).getPoint();
044: this .n = ((DERInteger) seq.getObjectAt(4)).getValue();
045: this .seed = x9c.getSeed();
046:
047: if (seq.size() == 6) {
048: this .h = ((DERInteger) seq.getObjectAt(5)).getValue();
049: } else {
050: this .h = ONE;
051: }
052: }
053:
054: public X9ECParameters(ECCurve curve, ECPoint g, BigInteger n) {
055: this (curve, g, n, ONE, null);
056: }
057:
058: public X9ECParameters(ECCurve curve, ECPoint g, BigInteger n,
059: BigInteger h) {
060: this (curve, g, n, h, null);
061: }
062:
063: public X9ECParameters(ECCurve curve, ECPoint g, BigInteger n,
064: BigInteger h, byte[] seed) {
065: this .curve = curve;
066: this .g = g;
067: this .n = n;
068: this .h = h;
069: this .seed = seed;
070:
071: if (curve instanceof ECCurve.Fp) {
072: this .fieldID = new X9FieldID(((ECCurve.Fp) curve).getQ());
073: } else {
074: if (curve instanceof ECCurve.F2m) {
075: ECCurve.F2m curveF2m = (ECCurve.F2m) curve;
076: this .fieldID = new X9FieldID(curveF2m.getM(), curveF2m
077: .getK1(), curveF2m.getK2(), curveF2m.getK3());
078: }
079: }
080: }
081:
082: public ECCurve getCurve() {
083: return curve;
084: }
085:
086: public ECPoint getG() {
087: return g;
088: }
089:
090: public BigInteger getN() {
091: return n;
092: }
093:
094: public BigInteger getH() {
095: return h;
096: }
097:
098: public byte[] getSeed() {
099: return seed;
100: }
101:
102: /**
103: * Produce an object suitable for an ASN1OutputStream.
104: * <pre>
105: * ECParameters ::= SEQUENCE {
106: * version INTEGER { ecpVer1(1) } (ecpVer1),
107: * fieldID FieldID {{FieldTypes}},
108: * curve X9Curve,
109: * base X9ECPoint,
110: * order INTEGER,
111: * cofactor INTEGER OPTIONAL
112: * }
113: * </pre>
114: */
115: public DERObject toASN1Object() {
116: ASN1EncodableVector v = new ASN1EncodableVector();
117:
118: v.add(new DERInteger(1));
119: v.add(fieldID);
120: v.add(new X9Curve(curve, seed));
121: v.add(new X9ECPoint(g));
122: v.add(new DERInteger(n));
123:
124: if (!h.equals(BigInteger.valueOf(1))) {
125: v.add(new DERInteger(h));
126: }
127:
128: return new DERSequence(v);
129: }
130: }
|