1package org.bouncycastle.jce.provider.asymmetric.ec;
2
3import org.bouncycastle.asn1.DERObjectIdentifier;
4// BEGIN android-removed
5// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
6// END android-removed
7import org.bouncycastle.asn1.nist.NISTNamedCurves;
8import org.bouncycastle.asn1.sec.SECNamedCurves;
9// BEGIN android-removed
10// import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
11// END android-removed
12import org.bouncycastle.asn1.x9.X962NamedCurves;
13import org.bouncycastle.asn1.x9.X9ECParameters;
14import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
15import org.bouncycastle.crypto.params.ECDomainParameters;
16import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
17import org.bouncycastle.crypto.params.ECPublicKeyParameters;
18import org.bouncycastle.jce.interfaces.ECPrivateKey;
19import org.bouncycastle.jce.interfaces.ECPublicKey;
20import org.bouncycastle.jce.spec.ECParameterSpec;
21import org.bouncycastle.jce.provider.ProviderUtil;
22import org.bouncycastle.jce.provider.JCEECPublicKey;
23
24import java.security.InvalidKeyException;
25import java.security.PrivateKey;
26import java.security.PublicKey;
27
28/**
29 * utility class for converting jce/jca ECDSA, ECDH, and ECDHC
30 * objects into their org.bouncycastle.crypto counterparts.
31 */
32public class ECUtil
33{
34    /**
35     * Returns a sorted array of middle terms of the reduction polynomial.
36     * @param k The unsorted array of middle terms of the reduction polynomial
37     * of length 1 or 3.
38     * @return the sorted array of middle terms of the reduction polynomial.
39     * This array always has length 3.
40     */
41    static int[] convertMidTerms(
42        int[] k)
43    {
44        int[] res = new int[3];
45
46        if (k.length == 1)
47        {
48            res[0] = k[0];
49        }
50        else
51        {
52            if (k.length != 3)
53            {
54                throw new IllegalArgumentException("Only Trinomials and pentanomials supported");
55            }
56
57            if (k[0] < k[1] && k[0] < k[2])
58            {
59                res[0] = k[0];
60                if (k[1] < k[2])
61                {
62                    res[1] = k[1];
63                    res[2] = k[2];
64                }
65                else
66                {
67                    res[1] = k[2];
68                    res[2] = k[1];
69                }
70            }
71            else if (k[1] < k[2])
72            {
73                res[0] = k[1];
74                if (k[0] < k[2])
75                {
76                    res[1] = k[0];
77                    res[2] = k[2];
78                }
79                else
80                {
81                    res[1] = k[2];
82                    res[2] = k[0];
83                }
84            }
85            else
86            {
87                res[0] = k[2];
88                if (k[0] < k[1])
89                {
90                    res[1] = k[0];
91                    res[2] = k[1];
92                }
93                else
94                {
95                    res[1] = k[1];
96                    res[2] = k[0];
97                }
98            }
99        }
100
101        return res;
102    }
103
104    public static AsymmetricKeyParameter generatePublicKeyParameter(
105        PublicKey    key)
106        throws InvalidKeyException
107    {
108        if (key instanceof ECPublicKey)
109        {
110            ECPublicKey    k = (ECPublicKey)key;
111            ECParameterSpec s = k.getParameters();
112
113            if (s == null)
114            {
115                s = ProviderUtil.getEcImplicitlyCa();
116
117                return new ECPublicKeyParameters(
118                            ((JCEECPublicKey)k).engineGetQ(),
119                            new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
120            }
121            else
122            {
123                return new ECPublicKeyParameters(
124                            k.getQ(),
125                            new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
126            }
127        }
128        else if (key instanceof java.security.interfaces.ECPublicKey)
129        {
130            java.security.interfaces.ECPublicKey pubKey = (java.security.interfaces.ECPublicKey)key;
131            ECParameterSpec s = EC5Util.convertSpec(pubKey.getParams(), false);
132            return new ECPublicKeyParameters(
133                EC5Util.convertPoint(pubKey.getParams(), pubKey.getW(), false),
134                            new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
135        }
136
137        throw new InvalidKeyException("cannot identify EC public key.");
138    }
139
140    public static AsymmetricKeyParameter generatePrivateKeyParameter(
141        PrivateKey    key)
142        throws InvalidKeyException
143    {
144        if (key instanceof ECPrivateKey)
145        {
146            ECPrivateKey  k = (ECPrivateKey)key;
147            ECParameterSpec s = k.getParameters();
148
149            if (s == null)
150            {
151                s = ProviderUtil.getEcImplicitlyCa();
152            }
153
154            return new ECPrivateKeyParameters(
155                            k.getD(),
156                            new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
157        }
158
159        throw new InvalidKeyException("can't identify EC private key.");
160    }
161
162    public static DERObjectIdentifier getNamedCurveOid(
163        String name)
164    {
165        DERObjectIdentifier oid = X962NamedCurves.getOID(name);
166
167        if (oid == null)
168        {
169            oid = SECNamedCurves.getOID(name);
170            if (oid == null)
171            {
172                oid = NISTNamedCurves.getOID(name);
173            }
174            // BEGIN android-removed
175            // if (oid == null)
176            // {
177            //     oid = TeleTrusTNamedCurves.getOID(name);
178            // }
179            // if (oid == null)
180            // {
181            //     oid = ECGOST3410NamedCurves.getOID(name);
182            // }
183            // END android-removed
184        }
185
186        return oid;
187    }
188
189    public static X9ECParameters getNamedCurveByOid(
190        DERObjectIdentifier oid)
191    {
192        X9ECParameters params = X962NamedCurves.getByOID(oid);
193
194        if (params == null)
195        {
196            params = SECNamedCurves.getByOID(oid);
197            if (params == null)
198            {
199                params = NISTNamedCurves.getByOID(oid);
200            }
201            // BEGIN android-removed
202            // if (params == null)
203            // {
204            //     params = TeleTrusTNamedCurves.getByOID(oid);
205            // }
206            // END android-removed
207        }
208
209        return params;
210    }
211
212    public static String getCurveName(
213        DERObjectIdentifier oid)
214    {
215        String name = X962NamedCurves.getName(oid);
216
217        if (name == null)
218        {
219            name = SECNamedCurves.getName(oid);
220            if (name == null)
221            {
222                name = NISTNamedCurves.getName(oid);
223            }
224            // BEGIN android-removed
225            // if (name == null)
226            // {
227            //     name = TeleTrusTNamedCurves.getName(oid);
228            // }
229            // if (name == null)
230            // {
231            //     name = ECGOST3410NamedCurves.getName(oid);
232            // }
233            // END android-removed
234        }
235
236        return name;
237    }
238}
239