• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.jcajce.provider.asymmetric.util;
2 
3 import java.math.BigInteger;
4 import java.security.spec.ECField;
5 import java.security.spec.ECFieldF2m;
6 import java.security.spec.ECFieldFp;
7 import java.security.spec.ECParameterSpec;
8 import java.security.spec.ECPoint;
9 import java.security.spec.EllipticCurve;
10 import java.util.Enumeration;
11 import java.util.HashMap;
12 import java.util.Map;
13 
14 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
15 import org.bouncycastle.asn1.x9.ECNamedCurveTable;
16 import org.bouncycastle.asn1.x9.X962Parameters;
17 import org.bouncycastle.asn1.x9.X9ECParameters;
18 import org.bouncycastle.crypto.ec.CustomNamedCurves;
19 import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
20 import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
21 import org.bouncycastle.jce.spec.ECNamedCurveSpec;
22 import org.bouncycastle.math.ec.ECAlgorithms;
23 import org.bouncycastle.math.ec.ECCurve;
24 import org.bouncycastle.math.field.FiniteField;
25 import org.bouncycastle.math.field.Polynomial;
26 import org.bouncycastle.math.field.PolynomialExtensionField;
27 import org.bouncycastle.util.Arrays;
28 
29 public class EC5Util
30 {
31     private static Map customCurves = new HashMap();
32 
33     static
34     {
35         Enumeration e = CustomNamedCurves.getNames();
36         while (e.hasMoreElements())
37         {
38             String name = (String)e.nextElement();
39 
40             X9ECParameters curveParams = ECNamedCurveTable.getByName(name);
41             if (curveParams != null)  // there may not be a regular curve, may just be a custom curve.
42             {
curveParams.getCurve()43                 customCurves.put(curveParams.getCurve(), CustomNamedCurves.getByName(name).getCurve());
44             }
45         }
46     }
47 
getCurve( ProviderConfiguration configuration, X962Parameters params)48     public static ECCurve getCurve(
49         ProviderConfiguration configuration,
50         X962Parameters params)
51     {
52         ECCurve curve;
53 
54         if (params.isNamedCurve())
55         {
56             ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
57             X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
58 
59             curve = ecP.getCurve();
60         }
61         else if (params.isImplicitlyCA())
62         {
63             curve = configuration.getEcImplicitlyCa().getCurve();
64         }
65         else
66         {
67             X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
68 
69             curve = ecP.getCurve();
70         }
71 
72         return curve;
73     }
74 
convertToSpec( X962Parameters params, ECCurve curve)75     public static ECParameterSpec convertToSpec(
76         X962Parameters params, ECCurve curve)
77     {
78         ECParameterSpec ecSpec;
79         EllipticCurve ellipticCurve;
80 
81         if (params.isNamedCurve())
82         {
83             ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
84             X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
85 
86             ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
87 
88             ecSpec = new ECNamedCurveSpec(
89                 ECUtil.getCurveName(oid),
90                 ellipticCurve,
91                 new ECPoint(
92                     ecP.getG().getAffineXCoord().toBigInteger(),
93                     ecP.getG().getAffineYCoord().toBigInteger()),
94                 ecP.getN(),
95                 ecP.getH());
96         }
97         else if (params.isImplicitlyCA())
98         {
99             ecSpec = null;
100         }
101         else
102         {
103             X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
104 
105             ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
106 
107             if (ecP.getH() != null)
108             {
109                 ecSpec = new ECParameterSpec(
110                     ellipticCurve,
111                     new ECPoint(
112                         ecP.getG().getAffineXCoord().toBigInteger(),
113                         ecP.getG().getAffineYCoord().toBigInteger()),
114                     ecP.getN(),
115                     ecP.getH().intValue());
116             }
117             else
118             {
119                 ecSpec = new ECParameterSpec(
120                     ellipticCurve,
121                     new ECPoint(
122                         ecP.getG().getAffineXCoord().toBigInteger(),
123                         ecP.getG().getAffineYCoord().toBigInteger()),
124                     ecP.getN(), 1);      // TODO: not strictly correct... need to fix the test data...
125             }
126         }
127 
128         return ecSpec;
129     }
130 
convertToSpec( X9ECParameters domainParameters)131     public static ECParameterSpec convertToSpec(
132         X9ECParameters domainParameters)
133     {
134         return new ECParameterSpec(
135             convertCurve(domainParameters.getCurve(), null),  // JDK 1.5 has trouble with this if it's not null...
136             new ECPoint(
137                 domainParameters.getG().getAffineXCoord().toBigInteger(),
138                 domainParameters.getG().getAffineYCoord().toBigInteger()),
139             domainParameters.getN(),
140             domainParameters.getH().intValue());
141     }
142 
convertCurve( ECCurve curve, byte[] seed)143     public static EllipticCurve convertCurve(
144         ECCurve curve,
145         byte[]  seed)
146     {
147         ECField field = convertField(curve.getField());
148         BigInteger a = curve.getA().toBigInteger(), b = curve.getB().toBigInteger();
149 
150         // TODO: the Sun EC implementation doesn't currently handle the seed properly
151         // so at the moment it's set to null. Should probably look at making this configurable
152         return new EllipticCurve(field, a, b, null);
153     }
154 
convertCurve( EllipticCurve ec)155     public static ECCurve convertCurve(
156         EllipticCurve ec)
157     {
158         ECField field = ec.getField();
159         BigInteger a = ec.getA();
160         BigInteger b = ec.getB();
161 
162         if (field instanceof ECFieldFp)
163         {
164             ECCurve.Fp curve = new ECCurve.Fp(((ECFieldFp)field).getP(), a, b);
165 
166             if (customCurves.containsKey(curve))
167             {
168                 return (ECCurve)customCurves.get(curve);
169             }
170 
171             return curve;
172         }
173         else
174         {
175             ECFieldF2m fieldF2m = (ECFieldF2m)field;
176             int m = fieldF2m.getM();
177             int ks[] = ECUtil.convertMidTerms(fieldF2m.getMidTermsOfReductionPolynomial());
178             return new ECCurve.F2m(m, ks[0], ks[1], ks[2], a, b);
179         }
180     }
181 
convertField(FiniteField field)182     public static ECField convertField(FiniteField field)
183     {
184         if (ECAlgorithms.isFpField(field))
185         {
186             return new ECFieldFp(field.getCharacteristic());
187         }
188         else //if (ECAlgorithms.isF2mField(curveField))
189         {
190             Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
191             int[] exponents = poly.getExponentsPresent();
192             int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
193             return new ECFieldF2m(poly.getDegree(), ks);
194         }
195     }
196 
convertSpec( EllipticCurve ellipticCurve, org.bouncycastle.jce.spec.ECParameterSpec spec)197     public static ECParameterSpec convertSpec(
198         EllipticCurve ellipticCurve,
199         org.bouncycastle.jce.spec.ECParameterSpec spec)
200     {
201         if (spec instanceof ECNamedCurveParameterSpec)
202         {
203             return new ECNamedCurveSpec(
204                 ((ECNamedCurveParameterSpec)spec).getName(),
205                 ellipticCurve,
206                 new ECPoint(
207                     spec.getG().getAffineXCoord().toBigInteger(),
208                     spec.getG().getAffineYCoord().toBigInteger()),
209                 spec.getN(),
210                 spec.getH());
211         }
212         else
213         {
214             return new ECParameterSpec(
215                 ellipticCurve,
216                 new ECPoint(
217                     spec.getG().getAffineXCoord().toBigInteger(),
218                     spec.getG().getAffineYCoord().toBigInteger()),
219                 spec.getN(),
220                 spec.getH().intValue());
221         }
222     }
223 
convertSpec( ECParameterSpec ecSpec, boolean withCompression)224     public static org.bouncycastle.jce.spec.ECParameterSpec convertSpec(
225         ECParameterSpec ecSpec,
226         boolean withCompression)
227     {
228         ECCurve curve = convertCurve(ecSpec.getCurve());
229 
230         return new org.bouncycastle.jce.spec.ECParameterSpec(
231             curve,
232             convertPoint(curve, ecSpec.getGenerator(), withCompression),
233             ecSpec.getOrder(),
234             BigInteger.valueOf(ecSpec.getCofactor()),
235             ecSpec.getCurve().getSeed());
236     }
237 
convertPoint( ECParameterSpec ecSpec, ECPoint point, boolean withCompression)238     public static org.bouncycastle.math.ec.ECPoint convertPoint(
239         ECParameterSpec ecSpec,
240         ECPoint point,
241         boolean withCompression)
242     {
243         return convertPoint(convertCurve(ecSpec.getCurve()), point, withCompression);
244     }
245 
convertPoint( ECCurve curve, ECPoint point, boolean withCompression)246     public static org.bouncycastle.math.ec.ECPoint convertPoint(
247         ECCurve curve,
248         ECPoint point,
249         boolean withCompression)
250     {
251         return curve.createPoint(point.getAffineX(), point.getAffineY());
252     }
253 }
254