• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.ECAlgorithms;
13 import org.bouncycastle.math.ec.ECCurve;
14 import org.bouncycastle.math.ec.ECPoint;
15 import org.bouncycastle.math.field.PolynomialExtensionField;
16 
17 /**
18  * ASN.1 def for Elliptic-Curve ECParameters structure. See
19  * X9.62, for further details.
20  */
21 public class X9ECParameters
22     extends ASN1Object
23     implements X9ObjectIdentifiers
24 {
25     private static final BigInteger   ONE = BigInteger.valueOf(1);
26 
27     private X9FieldID           fieldID;
28     private ECCurve             curve;
29     private X9ECPoint           g;
30     private BigInteger          n;
31     private BigInteger          h;
32     private byte[]              seed;
33 
X9ECParameters( ASN1Sequence seq)34     private X9ECParameters(
35         ASN1Sequence  seq)
36     {
37         if (!(seq.getObjectAt(0) instanceof ASN1Integer)
38            || !((ASN1Integer)seq.getObjectAt(0)).getValue().equals(ONE))
39         {
40             throw new IllegalArgumentException("bad version in X9ECParameters");
41         }
42 
43         X9Curve     x9c = new X9Curve(
44                         X9FieldID.getInstance(seq.getObjectAt(1)),
45                         ASN1Sequence.getInstance(seq.getObjectAt(2)));
46 
47         this.curve = x9c.getCurve();
48         Object p = seq.getObjectAt(3);
49 
50         if (p instanceof X9ECPoint)
51         {
52             this.g = ((X9ECPoint)p);
53         }
54         else
55         {
56             this.g = new X9ECPoint(curve, (ASN1OctetString)p);
57         }
58 
59         this.n = ((ASN1Integer)seq.getObjectAt(4)).getValue();
60         this.seed = x9c.getSeed();
61 
62         if (seq.size() == 6)
63         {
64             this.h = ((ASN1Integer)seq.getObjectAt(5)).getValue();
65         }
66     }
67 
getInstance(Object obj)68     public static X9ECParameters getInstance(Object obj)
69     {
70         if (obj instanceof X9ECParameters)
71         {
72             return (X9ECParameters)obj;
73         }
74 
75         if (obj != null)
76         {
77             return new X9ECParameters(ASN1Sequence.getInstance(obj));
78         }
79 
80         return null;
81     }
82 
X9ECParameters( ECCurve curve, ECPoint g, BigInteger n)83     public X9ECParameters(
84         ECCurve     curve,
85         ECPoint     g,
86         BigInteger  n)
87     {
88         this(curve, g, n, null, null);
89     }
90 
X9ECParameters( ECCurve curve, X9ECPoint g, BigInteger n, BigInteger h)91     public X9ECParameters(
92         ECCurve     curve,
93         X9ECPoint     g,
94         BigInteger  n,
95         BigInteger  h)
96     {
97         this(curve, g, n, h, null);
98     }
99 
X9ECParameters( ECCurve curve, ECPoint g, BigInteger n, BigInteger h)100     public X9ECParameters(
101         ECCurve     curve,
102         ECPoint     g,
103         BigInteger  n,
104         BigInteger  h)
105     {
106         this(curve, g, n, h, null);
107     }
108 
X9ECParameters( ECCurve curve, ECPoint g, BigInteger n, BigInteger h, byte[] seed)109     public X9ECParameters(
110         ECCurve     curve,
111         ECPoint     g,
112         BigInteger  n,
113         BigInteger  h,
114         byte[]      seed)
115     {
116         this(curve, new X9ECPoint(g), n, h, seed);
117     }
118 
X9ECParameters( ECCurve curve, X9ECPoint g, BigInteger n, BigInteger h, byte[] seed)119     public X9ECParameters(
120         ECCurve     curve,
121         X9ECPoint   g,
122         BigInteger  n,
123         BigInteger  h,
124         byte[]      seed)
125     {
126         this.curve = curve;
127         this.g = g;
128         this.n = n;
129         this.h = h;
130         this.seed = seed;
131 
132         if (ECAlgorithms.isFpCurve(curve))
133         {
134             this.fieldID = new X9FieldID(curve.getField().getCharacteristic());
135         }
136         else if (ECAlgorithms.isF2mCurve(curve))
137         {
138             PolynomialExtensionField field = (PolynomialExtensionField)curve.getField();
139             int[] exponents = field.getMinimalPolynomial().getExponentsPresent();
140             if (exponents.length == 3)
141             {
142                 this.fieldID = new X9FieldID(exponents[2], exponents[1]);
143             }
144             else if (exponents.length == 5)
145             {
146                 this.fieldID = new X9FieldID(exponents[4], exponents[1], exponents[2], exponents[3]);
147             }
148             else
149             {
150                 throw new IllegalArgumentException("Only trinomial and pentomial curves are supported");
151             }
152         }
153         else
154         {
155             throw new IllegalArgumentException("'curve' is of an unsupported type");
156         }
157     }
158 
getCurve()159     public ECCurve getCurve()
160     {
161         return curve;
162     }
163 
getG()164     public ECPoint getG()
165     {
166         return g.getPoint();
167     }
168 
getN()169     public BigInteger getN()
170     {
171         return n;
172     }
173 
getH()174     public BigInteger getH()
175     {
176         return h;
177     }
178 
getSeed()179     public byte[] getSeed()
180     {
181         return seed;
182     }
183 
184     /**
185      * Return the ASN.1 entry representing the Curve.
186      *
187      * @return the X9Curve for the curve in these parameters.
188      */
getCurveEntry()189     public X9Curve getCurveEntry()
190     {
191         return new X9Curve(curve, seed);
192     }
193 
194     /**
195      * Return the ASN.1 entry representing the FieldID.
196      *
197      * @return the X9FieldID for the FieldID in these parameters.
198      */
getFieldIDEntry()199     public X9FieldID getFieldIDEntry()
200     {
201         return fieldID;
202     }
203 
204     /**
205      * Return the ASN.1 entry representing the base point G.
206      *
207      * @return the X9ECPoint for the base point in these parameters.
208      */
getBaseEntry()209     public X9ECPoint getBaseEntry()
210     {
211         return g;
212     }
213 
214     /**
215      * Produce an object suitable for an ASN1OutputStream.
216      * <pre>
217      *  ECParameters ::= SEQUENCE {
218      *      version         INTEGER { ecpVer1(1) } (ecpVer1),
219      *      fieldID         FieldID {{FieldTypes}},
220      *      curve           X9Curve,
221      *      base            X9ECPoint,
222      *      order           INTEGER,
223      *      cofactor        INTEGER OPTIONAL
224      *  }
225      * </pre>
226      */
toASN1Primitive()227     public ASN1Primitive toASN1Primitive()
228     {
229         ASN1EncodableVector v = new ASN1EncodableVector();
230 
231         v.add(new ASN1Integer(ONE));
232         v.add(fieldID);
233         v.add(new X9Curve(curve, seed));
234         v.add(g);
235         v.add(new ASN1Integer(n));
236 
237         if (h != null)
238         {
239             v.add(new ASN1Integer(h));
240         }
241 
242         return new DERSequence(v);
243     }
244 }
245