001: package org.bouncycastle.jce.provider.test;
002:
003: import org.bouncycastle.asn1.nist.NISTNamedCurves;
004: import org.bouncycastle.asn1.sec.SECNamedCurves;
005: import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
006: import org.bouncycastle.asn1.x9.X962NamedCurves;
007: import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
008: import org.bouncycastle.jce.provider.BouncyCastleProvider;
009: import org.bouncycastle.jce.spec.ECNamedCurveSpec;
010: import org.bouncycastle.util.test.SimpleTest;
011:
012: import javax.crypto.KeyAgreement;
013: import java.math.BigInteger;
014: import java.security.KeyFactory;
015: import java.security.KeyPair;
016: import java.security.KeyPairGenerator;
017: import java.security.PrivateKey;
018: import java.security.PublicKey;
019: import java.security.SecureRandom;
020: import java.security.Security;
021: import java.security.Signature;
022: import java.security.interfaces.ECPrivateKey;
023: import java.security.interfaces.ECPublicKey;
024: import java.security.spec.ECGenParameterSpec;
025: import java.security.spec.PKCS8EncodedKeySpec;
026: import java.security.spec.X509EncodedKeySpec;
027: import java.util.Enumeration;
028: import java.util.Hashtable;
029:
030: public class NamedCurveTest extends SimpleTest {
031: private static Hashtable CURVE_NAMES = new Hashtable();
032: private static Hashtable CURVE_ALIASES = new Hashtable();
033:
034: static {
035: CURVE_NAMES.put("prime192v1", "prime192v1"); // X9.62
036: CURVE_NAMES.put("sect571r1", "sect571r1"); // sec
037: CURVE_NAMES.put("secp224r1", "secp224r1");
038: CURVE_NAMES.put("B-409", SECNamedCurves.getName(NISTNamedCurves
039: .getOID("B-409"))); // nist
040: CURVE_NAMES.put("P-521", SECNamedCurves.getName(NISTNamedCurves
041: .getOID("P-521")));
042: CURVE_NAMES.put("brainpoolp160r1", "brainpoolp160r1"); // TeleTrusT
043:
044: CURVE_ALIASES.put("secp192r1", "prime192v1");
045: CURVE_ALIASES.put("secp256r1", "prime256v1");
046: }
047:
048: public void testCurve(String name) throws Exception {
049: ECGenParameterSpec ecSpec = new ECGenParameterSpec(name);
050:
051: if (ecSpec == null) {
052: fail("no curve for " + name + " found.");
053: }
054:
055: KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "BC");
056:
057: g.initialize(ecSpec, new SecureRandom());
058:
059: //
060: // a side
061: //
062: KeyPair aKeyPair = g.generateKeyPair();
063:
064: KeyAgreement aKeyAgree = KeyAgreement
065: .getInstance("ECDHC", "BC");
066:
067: aKeyAgree.init(aKeyPair.getPrivate());
068:
069: //
070: // b side
071: //
072: KeyPair bKeyPair = g.generateKeyPair();
073:
074: KeyAgreement bKeyAgree = KeyAgreement
075: .getInstance("ECDHC", "BC");
076:
077: bKeyAgree.init(bKeyPair.getPrivate());
078:
079: //
080: // agreement
081: //
082: aKeyAgree.doPhase(bKeyPair.getPublic(), true);
083: bKeyAgree.doPhase(aKeyPair.getPublic(), true);
084:
085: BigInteger k1 = new BigInteger(aKeyAgree.generateSecret());
086: BigInteger k2 = new BigInteger(bKeyAgree.generateSecret());
087:
088: if (!k1.equals(k2)) {
089: fail("2-way test failed");
090: }
091:
092: //
093: // public key encoding test
094: //
095: byte[] pubEnc = aKeyPair.getPublic().getEncoded();
096: KeyFactory keyFac = KeyFactory.getInstance("ECDH", "BC");
097: X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
098: ECPublicKey pubKey = (ECPublicKey) keyFac
099: .generatePublic(pubX509);
100:
101: if (!pubKey.getW().equals(
102: ((ECPublicKey) aKeyPair.getPublic()).getW())) {
103: fail("public key encoding (Q test) failed");
104: }
105:
106: if (!(pubKey.getParams() instanceof ECNamedCurveSpec)) {
107: fail("public key encoding not named curve");
108: }
109:
110: //
111: // private key encoding test
112: //
113: byte[] privEnc = aKeyPair.getPrivate().getEncoded();
114: PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
115: ECPrivateKey privKey = (ECPrivateKey) keyFac
116: .generatePrivate(privPKCS8);
117:
118: if (!privKey.getS().equals(
119: ((ECPrivateKey) aKeyPair.getPrivate()).getS())) {
120: fail("private key encoding (S test) failed");
121: }
122:
123: if (!(privKey.getParams() instanceof ECNamedCurveSpec)) {
124: fail("private key encoding not named curve");
125: }
126:
127: ECNamedCurveSpec privSpec = (ECNamedCurveSpec) privKey
128: .getParams();
129: if (!(privSpec.getName().equals(name) || privSpec.getName()
130: .equals(CURVE_NAMES.get(name)))) {
131: fail("private key encoding wrong named curve. Expected: "
132: + CURVE_NAMES.get(name) + " got "
133: + privSpec.getName());
134: }
135: }
136:
137: public void testECDSA(String name) throws Exception {
138: ECGenParameterSpec ecSpec = new ECGenParameterSpec(name);
139:
140: if (ecSpec == null) {
141: fail("no curve for " + name + " found.");
142: }
143:
144: KeyPairGenerator g = KeyPairGenerator
145: .getInstance("ECDSA", "BC");
146:
147: g.initialize(ecSpec, new SecureRandom());
148:
149: Signature sgr = Signature.getInstance("ECDSA", "BC");
150: KeyPair pair = g.generateKeyPair();
151: PrivateKey sKey = pair.getPrivate();
152: PublicKey vKey = pair.getPublic();
153:
154: sgr.initSign(sKey);
155:
156: byte[] message = new byte[] { (byte) 'a', (byte) 'b',
157: (byte) 'c' };
158:
159: sgr.update(message);
160:
161: byte[] sigBytes = sgr.sign();
162:
163: sgr.initVerify(vKey);
164:
165: sgr.update(message);
166:
167: if (!sgr.verify(sigBytes)) {
168: fail(name + " verification failed");
169: }
170:
171: //
172: // public key encoding test
173: //
174: byte[] pubEnc = vKey.getEncoded();
175: KeyFactory keyFac = KeyFactory.getInstance("ECDH", "BC");
176: X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
177: ECPublicKey pubKey = (ECPublicKey) keyFac
178: .generatePublic(pubX509);
179:
180: if (!pubKey.getW().equals(((ECPublicKey) vKey).getW())) {
181: fail("public key encoding (Q test) failed");
182: }
183:
184: if (!(pubKey.getParams() instanceof ECNamedCurveSpec)) {
185: fail("public key encoding not named curve");
186: }
187:
188: //
189: // private key encoding test
190: //
191: byte[] privEnc = sKey.getEncoded();
192: PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
193: ECPrivateKey privKey = (ECPrivateKey) keyFac
194: .generatePrivate(privPKCS8);
195:
196: if (!privKey.getS().equals(((ECPrivateKey) sKey).getS())) {
197: fail("private key encoding (S test) failed");
198: }
199:
200: if (!(privKey.getParams() instanceof ECNamedCurveSpec)) {
201: fail("private key encoding not named curve");
202: }
203:
204: ECNamedCurveSpec privSpec = (ECNamedCurveSpec) privKey
205: .getParams();
206: if (!privSpec.getName().equalsIgnoreCase(name)
207: && !privSpec.getName().equalsIgnoreCase(
208: (String) CURVE_ALIASES.get(name))) {
209: fail("private key encoding wrong named curve. Expected: "
210: + name + " got " + privSpec.getName());
211: }
212: }
213:
214: public void testECGOST(String name) throws Exception {
215: ECGenParameterSpec ecSpec = new ECGenParameterSpec(name);
216:
217: if (ecSpec == null) {
218: fail("no curve for " + name + " found.");
219: }
220:
221: KeyPairGenerator g = KeyPairGenerator.getInstance("ECGOST3410",
222: "BC");
223:
224: g.initialize(ecSpec, new SecureRandom());
225:
226: Signature sgr = Signature.getInstance("ECGOST3410", "BC");
227: KeyPair pair = g.generateKeyPair();
228: PrivateKey sKey = pair.getPrivate();
229: PublicKey vKey = pair.getPublic();
230:
231: sgr.initSign(sKey);
232:
233: byte[] message = new byte[] { (byte) 'a', (byte) 'b',
234: (byte) 'c' };
235:
236: sgr.update(message);
237:
238: byte[] sigBytes = sgr.sign();
239:
240: sgr.initVerify(vKey);
241:
242: sgr.update(message);
243:
244: if (!sgr.verify(sigBytes)) {
245: fail(name + " verification failed");
246: }
247:
248: //
249: // public key encoding test
250: //
251: byte[] pubEnc = vKey.getEncoded();
252: KeyFactory keyFac = KeyFactory.getInstance("ECGOST3410", "BC");
253: X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
254: ECPublicKey pubKey = (ECPublicKey) keyFac
255: .generatePublic(pubX509);
256:
257: if (!pubKey.getW().equals(((ECPublicKey) vKey).getW())) {
258: fail("public key encoding (Q test) failed");
259: }
260:
261: if (!(pubKey.getParams() instanceof ECNamedCurveSpec)) {
262: fail("public key encoding not named curve");
263: }
264:
265: //
266: // private key encoding test
267: //
268: byte[] privEnc = sKey.getEncoded();
269: PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
270: ECPrivateKey privKey = (ECPrivateKey) keyFac
271: .generatePrivate(privPKCS8);
272:
273: if (!privKey.getS().equals(((ECPrivateKey) sKey).getS())) {
274: fail("GOST private key encoding (S test) failed");
275: }
276:
277: if (!(privKey.getParams() instanceof ECNamedCurveSpec)) {
278: fail("GOST private key encoding not named curve");
279: }
280:
281: ECNamedCurveSpec privSpec = (ECNamedCurveSpec) privKey
282: .getParams();
283: if (!privSpec.getName().equalsIgnoreCase(name)
284: && !privSpec.getName().equalsIgnoreCase(
285: (String) CURVE_ALIASES.get(name))) {
286: fail("GOST private key encoding wrong named curve. Expected: "
287: + name + " got " + privSpec.getName());
288: }
289: }
290:
291: public String getName() {
292: return "NamedCurve";
293: }
294:
295: public void performTest() throws Exception {
296: testCurve("prime192v1"); // X9.62
297: testCurve("sect571r1"); // sec
298: testCurve("secp224r1");
299: testCurve("B-409"); // nist
300: testCurve("P-521");
301: testCurve("brainpoolp160r1"); // TeleTrusT
302:
303: for (Enumeration en = X962NamedCurves.getNames(); en
304: .hasMoreElements();) {
305: testECDSA((String) en.nextElement());
306: }
307:
308: for (Enumeration en = SECNamedCurves.getNames(); en
309: .hasMoreElements();) {
310: testECDSA((String) en.nextElement());
311: }
312:
313: for (Enumeration en = TeleTrusTNamedCurves.getNames(); en
314: .hasMoreElements();) {
315: testECDSA((String) en.nextElement());
316: }
317:
318: for (Enumeration en = ECGOST3410NamedCurves.getNames(); en
319: .hasMoreElements();) {
320: testECGOST((String) en.nextElement());
321: }
322: }
323:
324: public static void main(String[] args) {
325: Security.addProvider(new BouncyCastleProvider());
326:
327: runTest(new NamedCurveTest());
328: }
329: }
|