14c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompackage org.bouncycastle.jcajce.provider.asymmetric.ec;
24c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
34c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.IOException;
44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.ObjectInputStream;
54c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.ObjectOutputStream;
64c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.math.BigInteger;
74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.interfaces.ECPublicKey;
84c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.spec.ECParameterSpec;
94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.spec.ECPoint;
104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.spec.ECPublicKeySpec;
114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.spec.EllipticCurve;
124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Encodable;
144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1ObjectIdentifier;
154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1OctetString;
164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Primitive;
174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.DERBitString;
184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.DERNull;
194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.DEROctetString;
204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x509.AlgorithmIdentifier;
214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x9.X962Parameters;
234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x9.X9ECParameters;
244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x9.X9ECPoint;
254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x9.X9IntegerConverter;
264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.params.ECDomainParameters;
284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.params.ECPublicKeyParameters;
294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jce.interfaces.ECPointEncoder;
324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jce.provider.BouncyCastleProvider;
334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jce.spec.ECNamedCurveSpec;
344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.math.ec.ECCurve;
354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompublic class BCECPublicKey
374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder
384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom{
394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    static final long serialVersionUID = 2422789860422731812L;
404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private String    algorithm = "EC";
424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private boolean   withCompression;
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private transient org.bouncycastle.math.ec.ECPoint q;
454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private transient ECParameterSpec         ecSpec;
464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private transient ProviderConfiguration   configuration;
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public BCECPublicKey(
494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        String algorithm,
504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        BCECPublicKey key)
514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.algorithm = algorithm;
534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.q = key.q;
544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.ecSpec = key.ecSpec;
554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.withCompression = key.withCompression;
564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.configuration = key.configuration;
574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public BCECPublicKey(
604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        String algorithm,
614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ECPublicKeySpec spec,
624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ProviderConfiguration configuration)
634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.algorithm = algorithm;
654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.ecSpec = spec.getParams();
664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.q = EC5Util.convertPoint(ecSpec, spec.getW(), false);
674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.configuration = configuration;
684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public BCECPublicKey(
714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        String algorithm,
724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        org.bouncycastle.jce.spec.ECPublicKeySpec spec,
734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ProviderConfiguration configuration)
744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.algorithm = algorithm;
764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.q = spec.getQ();
774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (spec.getParams() != null) // can be null if implictlyCa
794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ECCurve curve = spec.getParams().getCurve();
814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed());
824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams());
844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else
864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (q.getCurve() == null)
884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                org.bouncycastle.jce.spec.ECParameterSpec s = configuration.getEcImplicitlyCa();
904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                q = s.getCurve().createPoint(q.getX().toBigInteger(), q.getY().toBigInteger(), false);
924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.ecSpec = null;
944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.configuration = configuration;
974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public BCECPublicKey(
1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        String algorithm,
1014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ECPublicKeyParameters params,
1024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ECParameterSpec spec,
1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ProviderConfiguration configuration)
1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ECDomainParameters      dp = params.getParameters();
1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.algorithm = algorithm;
1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.q = params.getQ();
1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (spec == null)
1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.ecSpec = createSpec(ellipticCurve, dp);
1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else
1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.ecSpec = spec;
1194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.configuration = configuration;
1224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public BCECPublicKey(
1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        String algorithm,
1264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ECPublicKeyParameters params,
1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        org.bouncycastle.jce.spec.ECParameterSpec spec,
1284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ProviderConfiguration configuration)
1294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ECDomainParameters      dp = params.getParameters();
1314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.algorithm = algorithm;
1334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.q = params.getQ();
1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (spec == null)
1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.ecSpec = createSpec(ellipticCurve, dp);
1404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else
1424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed());
1444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec);
1464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.configuration = configuration;
1494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /*
1524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * called for implicitCA
1534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public BCECPublicKey(
1554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        String algorithm,
1564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ECPublicKeyParameters params,
1574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ProviderConfiguration configuration)
1584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.algorithm = algorithm;
1604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.q = params.getQ();
1614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.ecSpec = null;
1624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.configuration = configuration;
1634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public BCECPublicKey(
1664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ECPublicKey key,
1674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ProviderConfiguration configuration)
1684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.algorithm = key.getAlgorithm();
1704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.ecSpec = key.getParams();
1714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.q = EC5Util.convertPoint(this.ecSpec, key.getW(), false);
1724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    BCECPublicKey(
1754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        String algorithm,
1764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        SubjectPublicKeyInfo info,
1774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ProviderConfiguration configuration)
1784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.algorithm = algorithm;
1804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.configuration = configuration;
1814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        populateFromPubKeyInfo(info);
1824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private ECParameterSpec createSpec(EllipticCurve ellipticCurve, ECDomainParameters dp)
1854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return new ECParameterSpec(
1874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ellipticCurve,
1884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                new ECPoint(
1894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        dp.getG().getX().toBigInteger(),
1904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        dp.getG().getY().toBigInteger()),
1914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        dp.getN(),
1924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        dp.getH().intValue());
1934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private void populateFromPubKeyInfo(SubjectPublicKeyInfo info)
1964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        X962Parameters params = new X962Parameters((ASN1Primitive)info.getAlgorithm().getParameters());
1984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ECCurve                 curve;
1994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        EllipticCurve           ellipticCurve;
2004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (params.isNamedCurve())
2024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
2044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
2054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            curve = ecP.getCurve();
2074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
2084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ecSpec = new ECNamedCurveSpec(
2104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    ECUtil.getCurveName(oid),
2114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    ellipticCurve,
2124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    new ECPoint(
2134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            ecP.getG().getX().toBigInteger(),
2144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            ecP.getG().getY().toBigInteger()),
2154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    ecP.getN(),
2164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    ecP.getH());
2174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (params.isImplicitlyCA())
2194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ecSpec = null;
2214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            curve = configuration.getEcImplicitlyCa().getCurve();
2224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else
2244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            X9ECParameters          ecP = X9ECParameters.getInstance(params.getParameters());
2264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            curve = ecP.getCurve();
2284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
2294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.ecSpec = new ECParameterSpec(
2314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    ellipticCurve,
2324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    new ECPoint(
2334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            ecP.getG().getX().toBigInteger(),
2344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            ecP.getG().getY().toBigInteger()),
2354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    ecP.getN(),
2364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    ecP.getH().intValue());
2374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        DERBitString    bits = info.getPublicKeyData();
2404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[]          data = bits.getBytes();
2414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1OctetString key = new DEROctetString(data);
2424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        //
2444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        // extra octet string - one of our old certs...
2454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        //
2464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (data[0] == 0x04 && data[1] == data.length - 2
2474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            && (data[2] == 0x02 || data[2] == 0x03))
2484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            int qLength = new X9IntegerConverter().getByteLength(curve);
2504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (qLength >= data.length - 3)
2524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
2534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                try
2544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
2554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    key = (ASN1OctetString) ASN1Primitive.fromByteArray(data);
2564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
2574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                catch (IOException ex)
2584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
2594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    throw new IllegalArgumentException("error recovering public key");
2604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
2614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
2624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        X9ECPoint derQ = new X9ECPoint(curve, key);
2644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.q = derQ.getPoint();
2664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
2674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public String getAlgorithm()
2694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return algorithm;
2714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
2724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public String getFormat()
2744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return "X.509";
2764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
2774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public byte[] getEncoded()
2794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable        params;
2814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        SubjectPublicKeyInfo info;
2824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (ecSpec instanceof ECNamedCurveSpec)
2844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName());
2864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (curveOid == null)
2874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
2884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName());
2894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
2904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            params = new X962Parameters(curveOid);
2914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (ecSpec == null)
2934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            params = new X962Parameters(DERNull.INSTANCE);
2954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else
2974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve());
2994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            X9ECParameters ecP = new X9ECParameters(
3014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                curve,
3024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
3034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ecSpec.getOrder(),
3044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                BigInteger.valueOf(ecSpec.getCofactor()),
3054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ecSpec.getCurve().getSeed());
3064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            params = new X962Parameters(ecP);
3084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ECCurve curve = this.engineGetQ().getCurve();
3114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1OctetString p = (ASN1OctetString)
3124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            new X9ECPoint(curve.createPoint(this.getQ().getX().toBigInteger(), this.getQ().getY().toBigInteger(), withCompression)).toASN1Primitive();
3134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets());
3154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
3174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private void extractBytes(byte[] encKey, int offSet, BigInteger bI)
3204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[] val = bI.toByteArray();
3224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (val.length < 32)
3234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            byte[] tmp = new byte[32];
3254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            System.arraycopy(val, 0, tmp, tmp.length - val.length, val.length);
3264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            val = tmp;
3274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        for (int i = 0; i != 32; i++)
3304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            encKey[offSet + i] = val[val.length - 1 - i];
3324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ECParameterSpec getParams()
3364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return ecSpec;
3384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public org.bouncycastle.jce.spec.ECParameterSpec getParameters()
3414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (ecSpec == null)     // implictlyCA
3434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return null;
3454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return EC5Util.convertSpec(ecSpec, withCompression);
3484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ECPoint getW()
3514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return new ECPoint(q.getX().toBigInteger(), q.getY().toBigInteger());
3534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public org.bouncycastle.math.ec.ECPoint getQ()
3564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (ecSpec == null)
3584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (q instanceof org.bouncycastle.math.ec.ECPoint.Fp)
3604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
3614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return new org.bouncycastle.math.ec.ECPoint.Fp(null, q.getX(), q.getY());
3624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
3634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            else
3644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
3654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return new org.bouncycastle.math.ec.ECPoint.F2m(null, q.getX(), q.getY());
3664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
3674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return q;
3704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public org.bouncycastle.math.ec.ECPoint engineGetQ()
3734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return q;
3754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
3784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (ecSpec != null)
3804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return EC5Util.convertSpec(ecSpec, withCompression);
3824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return configuration.getEcImplicitlyCa();
3854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public String toString()
3884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        StringBuffer    buf = new StringBuffer();
3904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        String          nl = System.getProperty("line.separator");
3914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        buf.append("EC Public Key").append(nl);
3934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        buf.append("            X: ").append(this.q.getX().toBigInteger().toString(16)).append(nl);
3944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        buf.append("            Y: ").append(this.q.getY().toBigInteger().toString(16)).append(nl);
3954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return buf.toString();
3974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public void setPointFormat(String style)
4014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
4024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom       withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
4034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
4044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public boolean equals(Object o)
4064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
4074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (!(o instanceof BCECPublicKey))
4084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
4094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return false;
4104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
4114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        BCECPublicKey other = (BCECPublicKey)o;
4134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return engineGetQ().equals(other.engineGetQ()) && (engineGetSpec().equals(other.engineGetSpec()));
4154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
4164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public int hashCode()
4184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
4194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return engineGetQ().hashCode() ^ engineGetSpec().hashCode();
4204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
4214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private void readObject(
4234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ObjectInputStream in)
4244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException, ClassNotFoundException
4254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
4264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        in.defaultReadObject();
4274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[] enc = (byte[])in.readObject();
4294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
4314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.configuration = BouncyCastleProvider.CONFIGURATION;
4334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
4344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private void writeObject(
4364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ObjectOutputStream out)
4374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException
4384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
4394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        out.defaultWriteObject();
4404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        out.writeObject(this.getEncoded());
4424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
4434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom}
444