18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpackage org.bouncycastle.asn1.x9;
20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport java.math.BigInteger;
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1EncodableVector;
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1Integer;
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1Object;
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1ObjectIdentifier;
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1OctetString;
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1Primitive;
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.ASN1Sequence;
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.DERBitString;
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.asn1.DERSequence;
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport org.bouncycastle.math.ec.ECCurve;
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/**
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ASN.1 def for Elliptic-Curve Curve structure. See
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * X9.62, for further details.
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic class X9Curve
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    extends ASN1Object
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    implements X9ObjectIdentifiers
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private ECCurve     curve;
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private byte[]      seed;
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private ASN1ObjectIdentifier fieldIdentifier = null;
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public X9Curve(
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ECCurve     curve)
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        this.curve = curve;
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        this.seed = null;
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setFieldIdentifier();
34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public X9Curve(
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ECCurve     curve,
38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        byte[]      seed)
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        this.curve = curve;
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        this.seed = seed;
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setFieldIdentifier();
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
44563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public X9Curve(
46cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        X9FieldID     fieldID,
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASN1Sequence  seq)
48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fieldIdentifier = fieldID.getIdentifier();
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (fieldIdentifier.equals(prime_field))
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            BigInteger      p = ((ASN1Integer)fieldID.getParameters()).getValue();
53635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            X9FieldElement  x9A = new X9FieldElement(p, (ASN1OctetString)seq.getObjectAt(0));
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            X9FieldElement  x9B = new X9FieldElement(p, (ASN1OctetString)seq.getObjectAt(1));
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curve = new ECCurve.Fp(p, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger());
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
58563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        {
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (fieldIdentifier.equals(characteristic_two_field))
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Characteristic two field
62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                ASN1Sequence parameters = ASN1Sequence.getInstance(fieldID.getParameters());
63563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark                int m = ((ASN1Integer)parameters.getObjectAt(0)).getValue().
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    intValue();
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ASN1ObjectIdentifier representation
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    = (ASN1ObjectIdentifier)parameters.getObjectAt(1);
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int k1 = 0;
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int k2 = 0;
7081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                int k3 = 0;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (representation.equals(tpBasis))
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                {
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Trinomial basis representation
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    k1 = ((ASN1Integer)parameters.getObjectAt(2)).getValue().
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        intValue();
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                {
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Pentanomial basis representation
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    DERSequence pentanomial
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        = (DERSequence)parameters.getObjectAt(2);
82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    k1 = ((ASN1Integer)pentanomial.getObjectAt(0)).getValue().
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        intValue();
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    k2 = ((ASN1Integer)pentanomial.getObjectAt(1)).getValue().
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        intValue();
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    k3 = ((ASN1Integer)pentanomial.getObjectAt(2)).getValue().
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        intValue();
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                X9FieldElement x9A = new X9FieldElement(m, k1, k2, k3, (ASN1OctetString)seq.getObjectAt(0));
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                X9FieldElement x9B = new X9FieldElement(m, k1, k2, k3, (ASN1OctetString)seq.getObjectAt(1));
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // TODO Is it possible to get the order (n) and cofactor(h) too?
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                curve = new ECCurve.F2m(m, k1, k2, k3, x9A.getValue().toBigInteger(), x9B.getValue().toBigInteger());
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (seq.size() == 3)
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            seed = ((DERBitString)seq.getObjectAt(2)).getBytes();
990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    private void setFieldIdentifier()
1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (curve instanceof ECCurve.Fp)
1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            fieldIdentifier = prime_field;
1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else if (curve instanceof ECCurve.F2m)
1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            fieldIdentifier = characteristic_two_field;
1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            throw new IllegalArgumentException("This type of ECCurve is not "
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    + "implemented");
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public ECCurve  getCurve()
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return curve;
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public byte[]   getSeed()
125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    {
126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return seed;
127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    /**
130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     * Produce an object suitable for an ASN1OutputStream.
131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     * <pre>
1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch     *  Curve ::= SEQUENCE {
1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch     *      a               FieldElement,
134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     *      b               FieldElement,
135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     *      seed            BIT STRING      OPTIONAL
136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     *  }
137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     * </pre>
138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     */
139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    public ASN1Primitive toASN1Primitive()
140635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    {
141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASN1EncodableVector v = new ASN1EncodableVector();
142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (fieldIdentifier.equals(prime_field))
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            v.add(new X9FieldElement(curve.getA()).toASN1Primitive());
146643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            v.add(new X9FieldElement(curve.getB()).toASN1Primitive());
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (fieldIdentifier.equals(characteristic_two_field))
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            v.add(new X9FieldElement(curve.getA()).toASN1Primitive());
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            v.add(new X9FieldElement(curve.getB()).toASN1Primitive());
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (seed != null)
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            v.add(new DERBitString(seed));
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
159635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return new DERSequence(v);
160635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
161635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project