1package org.bouncycastle.jce.spec;
2
3import java.math.BigInteger;
4import java.security.spec.ECField;
5import java.security.spec.ECFieldF2m;
6import java.security.spec.ECFieldFp;
7import java.security.spec.ECPoint;
8import java.security.spec.EllipticCurve;
9
10import org.bouncycastle.math.ec.ECAlgorithms;
11import org.bouncycastle.math.ec.ECCurve;
12import org.bouncycastle.math.field.FiniteField;
13import org.bouncycastle.math.field.Polynomial;
14import org.bouncycastle.math.field.PolynomialExtensionField;
15import org.bouncycastle.util.Arrays;
16
17/**
18 * specification signifying that the curve parameters can also be
19 * referred to by name.
20 */
21public class ECNamedCurveSpec
22    extends java.security.spec.ECParameterSpec
23{
24    private String  name;
25
26    private static EllipticCurve convertCurve(
27        ECCurve  curve,
28        byte[]   seed)
29    {
30        ECField field = convertField(curve.getField());
31        BigInteger a = curve.getA().toBigInteger(), b = curve.getB().toBigInteger();
32        return new EllipticCurve(field, a, b, seed);
33    }
34
35    private static ECField convertField(FiniteField field)
36    {
37        if (ECAlgorithms.isFpField(field))
38        {
39            return new ECFieldFp(field.getCharacteristic());
40        }
41        else //if (ECAlgorithms.isF2mField(curveField))
42        {
43            Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
44            int[] exponents = poly.getExponentsPresent();
45            int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
46            return new ECFieldF2m(poly.getDegree(), ks);
47        }
48    }
49
50    private static ECPoint convertPoint(
51        org.bouncycastle.math.ec.ECPoint  g)
52    {
53        g = g.normalize();
54        return new ECPoint(g.getAffineXCoord().toBigInteger(), g.getAffineYCoord().toBigInteger());
55    }
56
57    public ECNamedCurveSpec(
58        String                              name,
59        ECCurve                             curve,
60        org.bouncycastle.math.ec.ECPoint    g,
61        BigInteger                          n)
62    {
63        super(convertCurve(curve, null), convertPoint(g), n, 1);
64
65        this.name = name;
66    }
67
68    public ECNamedCurveSpec(
69        String          name,
70        EllipticCurve   curve,
71        ECPoint         g,
72        BigInteger      n)
73    {
74        super(curve, g, n, 1);
75
76        this.name = name;
77    }
78
79    public ECNamedCurveSpec(
80        String                              name,
81        ECCurve                             curve,
82        org.bouncycastle.math.ec.ECPoint    g,
83        BigInteger                          n,
84        BigInteger                          h)
85    {
86        super(convertCurve(curve, null), convertPoint(g), n, h.intValue());
87
88        this.name = name;
89    }
90
91    public ECNamedCurveSpec(
92        String          name,
93        EllipticCurve   curve,
94        ECPoint         g,
95        BigInteger      n,
96        BigInteger      h)
97    {
98        super(curve, g, n, h.intValue());
99
100        this.name = name;
101    }
102
103    public ECNamedCurveSpec(
104        String                              name,
105        ECCurve                             curve,
106        org.bouncycastle.math.ec.ECPoint    g,
107        BigInteger                          n,
108        BigInteger                          h,
109        byte[]                              seed)
110    {
111        super(convertCurve(curve, seed), convertPoint(g), n, h.intValue());
112
113        this.name = name;
114    }
115
116    /**
117     * return the name of the curve the EC domain parameters belong to.
118     */
119    public String getName()
120    {
121        return name;
122    }
123}
124