• Home
  • History
  • Annotate
  • 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