18212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrompackage org.bouncycastle.asn1.x9;
28212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
38212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport java.math.BigInteger;
48212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
58212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport org.bouncycastle.asn1.ASN1Encodable;
68212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport org.bouncycastle.asn1.ASN1EncodableVector;
78212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport org.bouncycastle.asn1.ASN1OctetString;
88212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport org.bouncycastle.asn1.ASN1Sequence;
98212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport org.bouncycastle.asn1.DERBitString;
108212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport org.bouncycastle.asn1.DERInteger;
118212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport org.bouncycastle.asn1.DERObject;
128212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport org.bouncycastle.asn1.DERObjectIdentifier;
138212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport org.bouncycastle.asn1.DERSequence;
148212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstromimport org.bouncycastle.math.ec.ECCurve;
158212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
168212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom/**
178212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * ASN.1 def for Elliptic-Curve Curve structure. See
188212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom * X9.62, for further details.
198212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom */
208212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrompublic class X9Curve
218212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    extends ASN1Encodable
228212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    implements X9ObjectIdentifiers
238212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom{
248212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    private ECCurve     curve;
258212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    private byte[]      seed;
268212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    private DERObjectIdentifier fieldIdentifier = null;
278212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
288212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    public X9Curve(
298212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        ECCurve     curve)
308212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    {
318212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        this.curve = curve;
328212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        this.seed = null;
338212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        setFieldIdentifier();
348212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    }
358212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
368212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    public X9Curve(
378212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        ECCurve     curve,
388212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        byte[]      seed)
398212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    {
408212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        this.curve = curve;
418212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        this.seed = seed;
428212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        setFieldIdentifier();
438212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    }
448212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
458212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    public X9Curve(
468212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        X9FieldID     fieldID,
478212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        ASN1Sequence  seq)
488212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    {
498212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        fieldIdentifier = fieldID.getIdentifier();
508212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        if (fieldIdentifier.equals(prime_field))
518212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        {
528212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            BigInteger      p = ((DERInteger)fieldID.getParameters()).getValue();
538212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            X9FieldElement  x9A = new X9FieldElement(p, (ASN1OctetString)seq.getObjectAt(0));
548212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            X9FieldElement  x9B = new X9FieldElement(p, (ASN1OctetString)seq.getObjectAt(1));
558212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            curve = new ECCurve.Fp(p, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger());
568212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        }
578212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        else
588212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        {
598212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            if (fieldIdentifier.equals(characteristic_two_field))
608212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            {
618212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                // Characteristic two field
628212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                DERSequence parameters = (DERSequence)fieldID.getParameters();
638212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                int m = ((DERInteger)parameters.getObjectAt(0)).getValue().
648212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                    intValue();
658212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                DERObjectIdentifier representation
668212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                    = (DERObjectIdentifier)parameters.getObjectAt(1);
678212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
688212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                int k1 = 0;
698212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                int k2 = 0;
708212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                int k3 = 0;
718212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                if (representation.equals(tpBasis))
728212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                {
738212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                    // Trinomial basis representation
748212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                    k1 = ((DERInteger)parameters.getObjectAt(2)).getValue().
758212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                        intValue();
768212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                }
778212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                else
788212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                {
798212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                    // Pentanomial basis representation
808212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                    DERSequence pentanomial
818212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                        = (DERSequence)parameters.getObjectAt(2);
828212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                    k1 = ((DERInteger)pentanomial.getObjectAt(0)).getValue().
838212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                        intValue();
848212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                    k2 = ((DERInteger)pentanomial.getObjectAt(1)).getValue().
858212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                        intValue();
868212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                    k3 = ((DERInteger)pentanomial.getObjectAt(2)).getValue().
878212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                        intValue();
888212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                }
898212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                X9FieldElement x9A = new X9FieldElement(m, k1, k2, k3, (ASN1OctetString)seq.getObjectAt(0));
908212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                X9FieldElement x9B = new X9FieldElement(m, k1, k2, k3, (ASN1OctetString)seq.getObjectAt(1));
918212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                // TODO Is it possible to get the order (n) and cofactor(h) too?
928212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                curve = new ECCurve.F2m(m, k1, k2, k3, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger());
938212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            }
948212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        }
958212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
968212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        if (seq.size() == 3)
978212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        {
988212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            seed = ((DERBitString)seq.getObjectAt(2)).getBytes();
998212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        }
1008212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    }
1018212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
1028212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    private void setFieldIdentifier()
1038212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    {
1048212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        if (curve instanceof ECCurve.Fp)
1058212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        {
1068212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            fieldIdentifier = prime_field;
1078212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        }
1088212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        else if (curve instanceof ECCurve.F2m)
1098212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        {
1108212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            fieldIdentifier = characteristic_two_field;
1118212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        }
1128212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        else
1138212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        {
1148212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            throw new IllegalArgumentException("This type of ECCurve is not "
1158212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom                    + "implemented");
1168212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        }
1178212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    }
1188212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
1198212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    public ECCurve  getCurve()
1208212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    {
1218212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        return curve;
1228212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    }
1238212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
1248212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    public byte[]   getSeed()
1258212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    {
1268212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        return seed;
1278212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    }
1288212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
1298212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    /**
1308212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom     * Produce an object suitable for an ASN1OutputStream.
1318212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom     * <pre>
1328212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom     *  Curve ::= SEQUENCE {
1338212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom     *      a               FieldElement,
1348212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom     *      b               FieldElement,
1358212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom     *      seed            BIT STRING      OPTIONAL
1368212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom     *  }
1378212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom     * </pre>
1388212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom     */
1398212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    public DERObject toASN1Object()
1408212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    {
1418212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        ASN1EncodableVector v = new ASN1EncodableVector();
1428212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
1438212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        if (fieldIdentifier.equals(prime_field))
1448212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        {
1458212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            v.add(new X9FieldElement(curve.getA()).getDERObject());
1468212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            v.add(new X9FieldElement(curve.getB()).getDERObject());
1478212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        }
1488212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        else if (fieldIdentifier.equals(characteristic_two_field))
1498212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        {
1508212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            v.add(new X9FieldElement(curve.getA()).getDERObject());
1518212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            v.add(new X9FieldElement(curve.getB()).getDERObject());
1528212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        }
1538212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
1548212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        if (seed != null)
1558212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        {
1568212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom            v.add(new DERBitString(seed));
1578212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        }
1588212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom
1598212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom        return new DERSequence(v);
1608212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom    }
1618212855a312dc8ebe081a3e08b1d2d8f8757af02Brian Carlstrom}
162