Home | History | Annotate | Download | only in x9
      1 package org.bouncycastle.asn1.x9;
      2 
      3 import java.math.BigInteger;
      4 
      5 import org.bouncycastle.asn1.ASN1EncodableVector;
      6 import org.bouncycastle.asn1.ASN1Integer;
      7 import org.bouncycastle.asn1.ASN1Object;
      8 import org.bouncycastle.asn1.ASN1OctetString;
      9 import org.bouncycastle.asn1.ASN1Primitive;
     10 import org.bouncycastle.asn1.ASN1Sequence;
     11 import org.bouncycastle.asn1.DERSequence;
     12 import org.bouncycastle.math.ec.ECCurve;
     13 import org.bouncycastle.math.ec.ECPoint;
     14 
     15 /**
     16  * ASN.1 def for Elliptic-Curve ECParameters structure. See
     17  * X9.62, for further details.
     18  */
     19 public class X9ECParameters
     20     extends ASN1Object
     21     implements X9ObjectIdentifiers
     22 {
     23     private static final BigInteger   ONE = BigInteger.valueOf(1);
     24 
     25     private X9FieldID           fieldID;
     26     private ECCurve             curve;
     27     private ECPoint             g;
     28     private BigInteger          n;
     29     private BigInteger          h;
     30     private byte[]              seed;
     31 
     32     private X9ECParameters(
     33         ASN1Sequence  seq)
     34     {
     35         if (!(seq.getObjectAt(0) instanceof ASN1Integer)
     36            || !((ASN1Integer)seq.getObjectAt(0)).getValue().equals(ONE))
     37         {
     38             throw new IllegalArgumentException("bad version in X9ECParameters");
     39         }
     40 
     41         X9Curve     x9c = new X9Curve(
     42                         new X9FieldID((ASN1Sequence)seq.getObjectAt(1)),
     43                         (ASN1Sequence)seq.getObjectAt(2));
     44 
     45         this.curve = x9c.getCurve();
     46         this.g = new X9ECPoint(curve, (ASN1OctetString)seq.getObjectAt(3)).getPoint();
     47         this.n = ((ASN1Integer)seq.getObjectAt(4)).getValue();
     48         this.seed = x9c.getSeed();
     49 
     50         if (seq.size() == 6)
     51         {
     52             this.h = ((ASN1Integer)seq.getObjectAt(5)).getValue();
     53         }
     54     }
     55 
     56     public static X9ECParameters getInstance(Object obj)
     57     {
     58         if (obj instanceof X9ECParameters)
     59         {
     60             return (X9ECParameters)obj;
     61         }
     62 
     63         if (obj != null)
     64         {
     65             return new X9ECParameters(ASN1Sequence.getInstance(obj));
     66         }
     67 
     68         return null;
     69     }
     70 
     71     public X9ECParameters(
     72         ECCurve     curve,
     73         ECPoint     g,
     74         BigInteger  n)
     75     {
     76         this(curve, g, n, ONE, null);
     77     }
     78 
     79     public X9ECParameters(
     80         ECCurve     curve,
     81         ECPoint     g,
     82         BigInteger  n,
     83         BigInteger  h)
     84     {
     85         this(curve, g, n, h, null);
     86     }
     87 
     88     public X9ECParameters(
     89         ECCurve     curve,
     90         ECPoint     g,
     91         BigInteger  n,
     92         BigInteger  h,
     93         byte[]      seed)
     94     {
     95         this.curve = curve;
     96         this.g = g;
     97         this.n = n;
     98         this.h = h;
     99         this.seed = seed;
    100 
    101         if (curve instanceof ECCurve.Fp)
    102         {
    103             this.fieldID = new X9FieldID(((ECCurve.Fp)curve).getQ());
    104         }
    105         else
    106         {
    107             if (curve instanceof ECCurve.F2m)
    108             {
    109                 ECCurve.F2m curveF2m = (ECCurve.F2m)curve;
    110                 this.fieldID = new X9FieldID(curveF2m.getM(), curveF2m.getK1(),
    111                     curveF2m.getK2(), curveF2m.getK3());
    112             }
    113         }
    114     }
    115 
    116     public ECCurve getCurve()
    117     {
    118         return curve;
    119     }
    120 
    121     public ECPoint getG()
    122     {
    123         return g;
    124     }
    125 
    126     public BigInteger getN()
    127     {
    128         return n;
    129     }
    130 
    131     public BigInteger getH()
    132     {
    133         if (h == null)
    134         {
    135             return ONE;        // TODO - this should be calculated, it will cause issues with custom curves.
    136         }
    137 
    138         return h;
    139     }
    140 
    141     public byte[] getSeed()
    142     {
    143         return seed;
    144     }
    145 
    146     /**
    147      * Produce an object suitable for an ASN1OutputStream.
    148      * <pre>
    149      *  ECParameters ::= SEQUENCE {
    150      *      version         INTEGER { ecpVer1(1) } (ecpVer1),
    151      *      fieldID         FieldID {{FieldTypes}},
    152      *      curve           X9Curve,
    153      *      base            X9ECPoint,
    154      *      order           INTEGER,
    155      *      cofactor        INTEGER OPTIONAL
    156      *  }
    157      * </pre>
    158      */
    159     public ASN1Primitive toASN1Primitive()
    160     {
    161         ASN1EncodableVector v = new ASN1EncodableVector();
    162 
    163         v.add(new ASN1Integer(1));
    164         v.add(fieldID);
    165         v.add(new X9Curve(curve, seed));
    166         v.add(new X9ECPoint(g));
    167         v.add(new ASN1Integer(n));
    168 
    169         if (h != null)
    170         {
    171             v.add(new ASN1Integer(h));
    172         }
    173 
    174         return new DERSequence(v);
    175     }
    176 }
    177