package org.bouncycastle.jce.provider.test;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.KeyAgreement;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.interfaces.ECPrivateKey;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.util.test.SimpleTestResult;
import org.bouncycastle.util.test.Test;
import org.bouncycastle.util.test.TestResult;
public class NamedCurveTest
implements Test
{
private String name;
NamedCurveTest()
{
this("prime192v1");
}
NamedCurveTest(
String name)
{
this.name = name;
}
public TestResult perform()
{
try
{
ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(name);
if (ecSpec == null)
{
return new SimpleTestResult(false, getName() + " no curve for " + name + " found.");
}
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "BC");
g.initialize(ecSpec, new SecureRandom());
//
// a side
//
KeyPair aKeyPair = g.generateKeyPair();
KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDHC", "BC");
aKeyAgree.init(aKeyPair.getPrivate());
//
// b side
//
KeyPair bKeyPair = g.generateKeyPair();
KeyAgreement bKeyAgree = KeyAgreement.getInstance("ECDHC", "BC");
bKeyAgree.init(bKeyPair.getPrivate());
//
// agreement
//
aKeyAgree.doPhase(bKeyPair.getPublic(), true);
bKeyAgree.doPhase(aKeyPair.getPublic(), true);
BigInteger k1 = new BigInteger(aKeyAgree.generateSecret());
BigInteger k2 = new BigInteger(bKeyAgree.generateSecret());
if (!k1.equals(k2))
{
return new SimpleTestResult(false, getName() + " 2-way test failed");
}
//
// public key encoding test
//
byte[] pubEnc = aKeyPair.getPublic().getEncoded();
KeyFactory keyFac = KeyFactory.getInstance("ECDH", "BC");
X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
ECPublicKey pubKey = (ECPublicKey)keyFac.generatePublic(pubX509);
if (!pubKey.getQ().equals(((ECPublicKey)aKeyPair.getPublic()).getQ()))
{
return new SimpleTestResult(false, getName() + ": public key encoding (Q test) failed");
}
if (!(pubKey.getParameters() instanceof ECNamedCurveParameterSpec))
{
return new SimpleTestResult(false, getName() + ": public key encoding not named curve");
}
//
// private key encoding test
//
byte[] privEnc = aKeyPair.getPrivate().getEncoded();
PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
ECPrivateKey privKey = (ECPrivateKey)keyFac.generatePrivate(privPKCS8);
if (!privKey.getD().equals(((ECPrivateKey)aKeyPair.getPrivate()).getD()))
{
return new SimpleTestResult(false, getName() + ": private key encoding (D test) failed");
}
if (!(privKey.getParameters() instanceof ECNamedCurveParameterSpec))
{
return new SimpleTestResult(false, getName() + ": private key encoding not named curve");
}
if (!((ECNamedCurveParameterSpec)privKey.getParameters()).getName().equals(name))
{
return new SimpleTestResult(false, getName() + ": private key encoding wrong named curve");
}
return new SimpleTestResult(true, getName() + ": Okay");
}
catch (Exception e)
{
return new SimpleTestResult(false, getName() + ": exception - " + e.toString());
}
}
public String getName()
{
return "NamedCurve";
}
public static void main(
String[] args)
{
Security.addProvider(new BouncyCastleProvider());
Test test;
if (args.length == 0)
{
test = new NamedCurveTest();
}
else
{
test = new NamedCurveTest(args[0]);
}
TestResult result = test.perform();
System.out.println(result.toString());
}
}