Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'prov/src/test/java/org/spongycastle/jce/provider/test/ECDSA5Test.java')
-rw-r--r--prov/src/test/java/org/spongycastle/jce/provider/test/ECDSA5Test.java934
1 files changed, 934 insertions, 0 deletions
diff --git a/prov/src/test/java/org/spongycastle/jce/provider/test/ECDSA5Test.java b/prov/src/test/java/org/spongycastle/jce/provider/test/ECDSA5Test.java
new file mode 100644
index 00000000..b87189cf
--- /dev/null
+++ b/prov/src/test/java/org/spongycastle/jce/provider/test/ECDSA5Test.java
@@ -0,0 +1,934 @@
+package org.spongycastle.jce.provider.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECFieldF2m;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.EllipticCurve;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.ASN1Primitive;
+import org.spongycastle.asn1.ASN1Sequence;
+import org.spongycastle.asn1.bsi.BSIObjectIdentifiers;
+import org.spongycastle.asn1.eac.EACObjectIdentifiers;
+import org.spongycastle.asn1.pkcs.PrivateKeyInfo;
+import org.spongycastle.asn1.sec.SECObjectIdentifiers;
+import org.spongycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.spongycastle.asn1.x9.X962Parameters;
+import org.spongycastle.asn1.x9.X9ECParameters;
+import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
+import org.spongycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.spongycastle.jce.ECKeyUtil;
+import org.spongycastle.jce.ECNamedCurveTable;
+import org.spongycastle.jce.ECPointUtil;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.math.ec.ECCurve;
+import org.spongycastle.util.BigIntegers;
+import org.spongycastle.util.encoders.Hex;
+import org.spongycastle.util.test.FixedSecureRandom;
+import org.spongycastle.util.test.SimpleTest;
+
+public class ECDSA5Test
+ extends SimpleTest
+{
+ byte[] k1 = Hex.decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3");
+ byte[] k2 = Hex.decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded");
+
+ SecureRandom random = new FixedSecureRandom(new byte[][] { k1, k2 });
+
+ private void decodeTest()
+ {
+ EllipticCurve curve = new EllipticCurve(
+ new ECFieldFp(new BigInteger("6277101735386680763835789423207666416083908700390324961279")), // q
+ new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16), // a
+ new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16)); // b
+
+ ECPoint p = ECPointUtil.decodePoint(curve, Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012"));
+
+ if (!p.getAffineX().equals(new BigInteger("188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", 16)))
+ {
+ fail("x uncompressed incorrectly");
+ }
+
+ if (!p.getAffineY().equals(new BigInteger("7192b95ffc8da78631011ed6b24cdd573f977a11e794811", 16)))
+ {
+ fail("y uncompressed incorrectly");
+ }
+ }
+
+ /**
+ * X9.62 - 1998,<br>
+ * J.3.2, Page 155, ECDSA over the field Fp<br>
+ * an example with 239 bit prime
+ */
+ private void testECDSA239bitPrime()
+ throws Exception
+ {
+ BigInteger r = new BigInteger("308636143175167811492622547300668018854959378758531778147462058306432176");
+ BigInteger s = new BigInteger("323813553209797357708078776831250505931891051755007842781978505179448783");
+
+ byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("700000017569056646655505781757157107570501575775705779575555657156756655"));
+
+ SecureRandom k = new FixedSecureRandom(kData);
+
+ EllipticCurve curve = new EllipticCurve(
+ new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q
+ new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a
+ new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b
+
+ ECParameterSpec spec = new ECParameterSpec(
+ curve,
+ ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
+ new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n
+ 1); // h
+
+
+ ECPrivateKeySpec priKey = new ECPrivateKeySpec(
+ new BigInteger("876300101507107567501066130761671078357010671067781776716671676178726717"), // d
+ spec);
+
+ ECPublicKeySpec pubKey = new ECPublicKeySpec(
+ ECPointUtil.decodePoint(curve, Hex.decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q
+ spec);
+
+ Signature sgr = Signature.getInstance("ECDSA", "SC");
+ KeyFactory f = KeyFactory.getInstance("ECDSA", "SC");
+ PrivateKey sKey = f.generatePrivate(priKey);
+ PublicKey vKey = f.generatePublic(pubKey);
+
+ sgr.initSign(sKey, k);
+
+ byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' };
+
+ sgr.update(message);
+
+ byte[] sigBytes = sgr.sign();
+
+ sgr.initVerify(vKey);
+
+ sgr.update(message);
+
+ if (!sgr.verify(sigBytes))
+ {
+ fail("239 Bit EC verification failed");
+ }
+
+ BigInteger[] sig = derDecode(sigBytes);
+
+ if (!r.equals(sig[0]))
+ {
+ fail("r component wrong." + System.getProperty("line.separator")
+ + " expecting: " + r + System.getProperty("line.separator")
+ + " got : " + sig[0]);
+ }
+
+ if (!s.equals(sig[1]))
+ {
+ fail("s component wrong." + System.getProperty("line.separator")
+ + " expecting: " + s + System.getProperty("line.separator")
+ + " got : " + sig[1]);
+ }
+ }
+
+ // test BSI algorithm support.
+ private void testBSI()
+ throws Exception
+ {
+ KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ECDSA", "SC");
+
+ kpGen.initialize(new ECGenParameterSpec(TeleTrusTObjectIdentifiers.brainpoolP512r1.getId()));
+
+ KeyPair kp = kpGen.generateKeyPair();
+
+ byte[] data = "Hello World!!!".getBytes();
+ String[] cvcAlgs = { "SHA1WITHCVC-ECDSA", "SHA224WITHCVC-ECDSA",
+ "SHA256WITHCVC-ECDSA", "SHA384WITHCVC-ECDSA",
+ "SHA512WITHCVC-ECDSA" };
+ String[] cvcOids = { EACObjectIdentifiers.id_TA_ECDSA_SHA_1.getId(), EACObjectIdentifiers.id_TA_ECDSA_SHA_224.getId(),
+ EACObjectIdentifiers.id_TA_ECDSA_SHA_256.getId(), EACObjectIdentifiers.id_TA_ECDSA_SHA_384.getId(),
+ EACObjectIdentifiers.id_TA_ECDSA_SHA_512.getId() };
+
+ testBsiAlgorithms(kp, data, cvcAlgs, cvcOids);
+
+ String[] plainAlgs = { "SHA1WITHPLAIN-ECDSA", "SHA224WITHPLAIN-ECDSA",
+ "SHA256WITHPLAIN-ECDSA", "SHA384WITHPLAIN-ECDSA",
+ "SHA512WITHPLAIN-ECDSA", "RIPEMD160WITHPLAIN-ECDSA" };
+ String[] plainOids = { BSIObjectIdentifiers.ecdsa_plain_SHA1.getId(), BSIObjectIdentifiers.ecdsa_plain_SHA224.getId(),
+ BSIObjectIdentifiers.ecdsa_plain_SHA256.getId(), BSIObjectIdentifiers.ecdsa_plain_SHA384.getId(),
+ BSIObjectIdentifiers.ecdsa_plain_SHA512.getId(), BSIObjectIdentifiers.ecdsa_plain_RIPEMD160.getId() };
+
+ testBsiAlgorithms(kp, data, plainAlgs, plainOids);
+ }
+
+ private void testBsiAlgorithms(KeyPair kp, byte[] data, String[] algs, String[] oids)
+ throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException
+ {
+ for (int i = 0; i != algs.length; i++)
+ {
+ Signature sig1 = Signature.getInstance(algs[i], "SC");
+ Signature sig2 = Signature.getInstance(oids[i], "SC");
+
+ sig1.initSign(kp.getPrivate());
+
+ sig1.update(data);
+
+ byte[] sig = sig1.sign();
+
+ sig2.initVerify(kp.getPublic());
+
+ sig2.update(data);
+
+ if (!sig2.verify(sig))
+ {
+ fail("BSI CVC signature failed: " + algs[i]);
+ }
+ }
+ }
+
+ /**
+ * X9.62 - 1998,<br>
+ * J.2.1, Page 100, ECDSA over the field F2m<br>
+ * an example with 191 bit binary field
+ */
+ private void testECDSA239bitBinary()
+ throws Exception
+ {
+ BigInteger r = new BigInteger("21596333210419611985018340039034612628818151486841789642455876922391552");
+ BigInteger s = new BigInteger("197030374000731686738334997654997227052849804072198819102649413465737174");
+
+ byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("171278725565216523967285789236956265265265235675811949404040041670216363"));
+
+ SecureRandom k = new FixedSecureRandom(kData);
+
+ EllipticCurve curve = new EllipticCurve(
+ new ECFieldF2m(239, // m
+ new int[] { 36 }), // k
+ new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a
+ new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b
+
+ ECParameterSpec params = new ECParameterSpec(
+ curve,
+ ECPointUtil.decodePoint(curve, Hex.decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G
+ new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n
+ 4); // h
+
+ ECPrivateKeySpec priKeySpec = new ECPrivateKeySpec(
+ new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d
+ params);
+
+ ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(
+ ECPointUtil.decodePoint(curve, Hex.decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q
+ params);
+
+ Signature sgr = Signature.getInstance("ECDSA", "SC");
+ KeyFactory f = KeyFactory.getInstance("ECDSA", "SC");
+ PrivateKey sKey = f.generatePrivate(priKeySpec);
+ PublicKey vKey = f.generatePublic(pubKeySpec);
+ byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' };
+
+ sgr.initSign(sKey, k);
+
+ sgr.update(message);
+
+ byte[] sigBytes = sgr.sign();
+
+ sgr.initVerify(vKey);
+
+ sgr.update(message);
+
+ if (!sgr.verify(sigBytes))
+ {
+ fail("239 Bit EC verification failed");
+ }
+
+ BigInteger[] sig = derDecode(sigBytes);
+
+ if (!r.equals(sig[0]))
+ {
+ fail("r component wrong." + System.getProperty("line.separator")
+ + " expecting: " + r + System.getProperty("line.separator")
+ + " got : " + sig[0]);
+ }
+
+ if (!s.equals(sig[1]))
+ {
+ fail("s component wrong." + System.getProperty("line.separator")
+ + " expecting: " + s + System.getProperty("line.separator")
+ + " got : " + sig[1]);
+ }
+ }
+
+ private void testGeneration()
+ throws Exception
+ {
+ //
+ // ECDSA generation test
+ //
+ byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+ Signature s = Signature.getInstance("ECDSA", "SC");
+ KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "SC");
+
+ EllipticCurve curve = new EllipticCurve(
+ new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q
+ new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a
+ new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b
+
+ ECParameterSpec ecSpec = new ECParameterSpec(
+ curve,
+ ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
+ new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n
+ 1); // h
+
+ g.initialize(ecSpec, new SecureRandom());
+
+ KeyPair p = g.generateKeyPair();
+
+ PrivateKey sKey = p.getPrivate();
+ PublicKey vKey = p.getPublic();
+
+ s.initSign(sKey);
+
+ s.update(data);
+
+ byte[] sigBytes = s.sign();
+
+ s = Signature.getInstance("ECDSA", "SC");
+
+ s.initVerify(vKey);
+
+ s.update(data);
+
+ if (!s.verify(sigBytes))
+ {
+ fail("ECDSA verification failed");
+ }
+
+ testKeyFactory((ECPublicKey)vKey, (ECPrivateKey)sKey);
+ testSerialise((ECPublicKey)vKey, (ECPrivateKey)sKey);
+ }
+
+ private void testSerialise(ECPublicKey ecPublicKey, ECPrivateKey ecPrivateKey)
+ throws Exception
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ ObjectOutputStream oOut = new ObjectOutputStream(bOut);
+
+ oOut.writeObject(ecPublicKey);
+ oOut.writeObject(ecPrivateKey);
+ oOut.close();
+
+ ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray()));
+
+ PublicKey pubKey = (PublicKey)oIn.readObject();
+ PrivateKey privKey = (PrivateKey)oIn.readObject();
+
+ if (!ecPublicKey.equals(pubKey))
+ {
+ fail("public key serialisation check failed");
+ }
+
+ if (!ecPrivateKey.equals(privKey))
+ {
+ fail("private key serialisation check failed");
+ }
+ }
+
+ private void testKeyFactory(ECPublicKey pub, ECPrivateKey priv)
+ throws Exception
+ {
+ KeyFactory ecFact = KeyFactory.getInstance("ECDSA");
+
+ ECPublicKeySpec pubSpec = (ECPublicKeySpec)ecFact.getKeySpec(pub, ECPublicKeySpec.class);
+ ECPrivateKeySpec privSpec = (ECPrivateKeySpec)ecFact.getKeySpec(priv, ECPrivateKeySpec.class);
+
+ if (!pubSpec.getW().equals(pub.getW()) || !pubSpec.getParams().getCurve().equals(pub.getParams().getCurve()))
+ {
+ fail("pubSpec not correct");
+ }
+
+ if (!privSpec.getS().equals(priv.getS()) || !privSpec.getParams().getCurve().equals(priv.getParams().getCurve()))
+ {
+ fail("privSpec not correct");
+ }
+
+ ECPublicKey pubKey = (ECPublicKey)ecFact.translateKey(pub);
+ ECPrivateKey privKey = (ECPrivateKey)ecFact.translateKey(priv);
+
+ if (!pubKey.getW().equals(pub.getW()) || !pubKey.getParams().getCurve().equals(pub.getParams().getCurve()))
+ {
+ fail("pubKey not correct");
+ }
+
+ if (!privKey.getS().equals(priv.getS()) || !privKey.getParams().getCurve().equals(priv.getParams().getCurve()))
+ {
+ fail("privKey not correct");
+ }
+ }
+
+ private void testKeyConversion()
+ throws Exception
+ {
+ KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ECDSA", "SC");
+
+ kpGen.initialize(new ECGenParameterSpec("prime192v1"));
+
+ KeyPair pair = kpGen.generateKeyPair();
+
+ PublicKey pubKey = ECKeyUtil.publicToExplicitParameters(pair.getPublic(), "SC");
+
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pubKey.getEncoded()));
+ X962Parameters params = X962Parameters.getInstance(info.getAlgorithmId().getParameters());
+
+ if (params.isNamedCurve() || params.isImplicitlyCA())
+ {
+ fail("public key conversion to explicit failed");
+ }
+
+ if (!((ECPublicKey)pair.getPublic()).getW().equals(((ECPublicKey)pubKey).getW()))
+ {
+ fail("public key conversion check failed");
+ }
+
+ PrivateKey privKey = ECKeyUtil.privateToExplicitParameters(pair.getPrivate(), "SC");
+ PrivateKeyInfo privInfo = PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(privKey.getEncoded()));
+ params = X962Parameters.getInstance(privInfo.getAlgorithmId().getParameters());
+
+ if (params.isNamedCurve() || params.isImplicitlyCA())
+ {
+ fail("private key conversion to explicit failed");
+ }
+
+ if (!((ECPrivateKey)pair.getPrivate()).getS().equals(((ECPrivateKey)privKey).getS()))
+ {
+ fail("private key conversion check failed");
+ }
+ }
+
+ private void testAdaptiveKeyConversion()
+ throws Exception
+ {
+ KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ECDSA", "SC");
+
+ kpGen.initialize(new ECGenParameterSpec("prime192v1"));
+
+ KeyPair pair = kpGen.generateKeyPair();
+
+ final PrivateKey privKey = pair.getPrivate();
+ final PublicKey pubKey = pair.getPublic();
+
+ Signature s = Signature.getInstance("ECDSA", "SC");
+
+ // raw interface tests
+ s.initSign(new PrivateKey()
+ {
+ public String getAlgorithm()
+ {
+ return privKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return privKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return privKey.getEncoded();
+ }
+ });
+
+ s.initVerify(new PublicKey()
+ {
+ public String getAlgorithm()
+ {
+ return pubKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return pubKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return pubKey.getEncoded();
+ }
+ });
+
+
+ s.initSign(new ECPrivateKey()
+ {
+ public String getAlgorithm()
+ {
+ return privKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return privKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return privKey.getEncoded();
+ }
+
+ public BigInteger getS()
+ {
+ return ((ECPrivateKey)privKey).getS();
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return ((ECPrivateKey)privKey).getParams();
+ }
+ });
+
+ s.initVerify(new ECPublicKey()
+ {
+ public String getAlgorithm()
+ {
+ return pubKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return pubKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return pubKey.getEncoded();
+ }
+
+ public ECPoint getW()
+ {
+ return ((ECPublicKey)pubKey).getW();
+ }
+
+ public ECParameterSpec getParams()
+ {
+ return ((ECPublicKey)pubKey).getParams();
+ }
+ });
+
+ try
+ {
+ s.initSign(new PrivateKey()
+ {
+ public String getAlgorithm()
+ {
+ return privKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return privKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return null;
+ }
+ });
+
+ fail("no exception thrown!!!");
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+
+ try
+ {
+ s.initVerify(new PublicKey()
+ {
+ public String getAlgorithm()
+ {
+ return pubKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return pubKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return null;
+ }
+ });
+
+ fail("no exception thrown!!!");
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+
+ // try bogus encoding
+ try
+ {
+ s.initSign(new PrivateKey()
+ {
+ public String getAlgorithm()
+ {
+ return privKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return privKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return new byte[20];
+ }
+ });
+
+ fail("no exception thrown!!!");
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+
+ try
+ {
+ s.initVerify(new PublicKey()
+ {
+ public String getAlgorithm()
+ {
+ return pubKey.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return pubKey.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return new byte[20];
+ }
+ });
+
+ fail("no exception thrown!!!");
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+
+ // try encoding of wrong key
+ kpGen = KeyPairGenerator.getInstance("RSA", "SC");
+
+ kpGen.initialize(512);
+
+ pair = kpGen.generateKeyPair();
+
+ final PrivateKey privRsa = pair.getPrivate();
+ final PublicKey pubRsa = pair.getPublic();
+
+ try
+ {
+ s.initSign(new PrivateKey()
+ {
+ public String getAlgorithm()
+ {
+ return privRsa.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return privRsa.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return privRsa.getEncoded();
+ }
+ });
+
+ fail("no exception thrown!!!");
+
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+
+ try
+ {
+ s.initVerify(new PublicKey()
+ {
+ public String getAlgorithm()
+ {
+ return pubRsa.getAlgorithm();
+ }
+
+ public String getFormat()
+ {
+ return pubRsa.getFormat();
+ }
+
+ public byte[] getEncoded()
+ {
+ return pubRsa.getEncoded();
+ }
+ });
+
+ fail("no exception thrown!!!");
+ }
+ catch (InvalidKeyException e)
+ {
+ // ignore
+ }
+ }
+
+ private void testKeyPairGenerationWithOIDs()
+ throws Exception
+ {
+ KeyPairGenerator kpGen = KeyPairGenerator.getInstance("ECDSA", "SC");
+
+ kpGen.initialize(new ECGenParameterSpec(X9ObjectIdentifiers.prime192v1.getId()));
+ kpGen.initialize(new ECGenParameterSpec(TeleTrusTObjectIdentifiers.brainpoolP160r1.getId()));
+ kpGen.initialize(new ECGenParameterSpec(SECObjectIdentifiers.secp128r1.getId()));
+
+ try
+ {
+ kpGen.initialize(new ECGenParameterSpec("1.1"));
+
+ fail("non-existant curve OID failed");
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ if (!"unknown curve OID: 1.1".equals(e.getMessage()))
+ {
+ fail("OID message check failed");
+ }
+ }
+
+ try
+ {
+ kpGen.initialize(new ECGenParameterSpec("flibble"));
+
+ fail("non-existant curve name failed");
+ }
+ catch (InvalidAlgorithmParameterException e)
+ {
+ if (!"unknown curve name: flibble".equals(e.getMessage()))
+ {
+ fail("name message check failed");
+ }
+ }
+ }
+
+ private static class ECRandom
+ extends SecureRandom
+ {
+ public void nextBytes(byte[] bytes)
+ {
+ byte[] src = new BigInteger("e2eb6663f551331bda00b90f1272c09d980260c1a70cab1ec481f6c937f34b62", 16).toByteArray();
+
+ if (src.length <= bytes.length)
+ {
+ System.arraycopy(src, 0, bytes, bytes.length - src.length, src.length);
+ }
+ else
+ {
+ System.arraycopy(src, 0, bytes, 0, bytes.length);
+ }
+ }
+ }
+
+ private void testNamedCurveParameterPreservation()
+ throws Exception
+ {
+ AlgorithmParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
+ KeyPairGenerator keygen = KeyPairGenerator.getInstance("EC", "SC");
+ keygen.initialize(ecSpec, new ECRandom());
+
+ KeyPair keys = keygen.generateKeyPair();
+
+ PrivateKeyInfo priv1 = PrivateKeyInfo.getInstance(keys.getPrivate().getEncoded());
+ SubjectPublicKeyInfo pub1 = SubjectPublicKeyInfo.getInstance(keys.getPublic().getEncoded());
+
+ keygen = KeyPairGenerator.getInstance("EC", "SC");
+ keygen.initialize(new ECGenParameterSpec("secp256r1"), new ECRandom());
+
+ PrivateKeyInfo priv2 = PrivateKeyInfo.getInstance(keys.getPrivate().getEncoded());
+ SubjectPublicKeyInfo pub2 = SubjectPublicKeyInfo.getInstance(keys.getPublic().getEncoded());
+
+ if (!priv1.equals(priv2) || !pub1.equals(pub2))
+ {
+ fail("mismatch between alg param spec and ECGenParameterSpec");
+ }
+
+ if (!(priv2.getPrivateKeyAlgorithm().getParameters() instanceof ASN1ObjectIdentifier))
+ {
+ fail("OID not preserved in private key");
+ }
+
+ if (!(pub1.getAlgorithm().getParameters() instanceof ASN1ObjectIdentifier))
+ {
+ fail("OID not preserved in public key");
+ }
+ }
+
+ private void testNamedCurveSigning()
+ throws Exception
+ {
+ testCustomNamedCurveSigning("secp256r1");
+
+ try
+ {
+ testCustomNamedCurveSigning("secp256k1");
+ }
+ catch (IllegalArgumentException e)
+ {
+ if (!e.getMessage().equals("first coefficient is negative")) // bogus jdk 1.5 exception...
+ {
+ throw e;
+ }
+ }
+ }
+
+ private void testCustomNamedCurveSigning(String name)
+ throws Exception
+ {
+ X9ECParameters x9Params = ECUtil.getNamedCurveByOid(ECUtil.getNamedCurveOid(name));
+
+ // TODO: one day this may have to change
+ if (x9Params.getCurve() instanceof ECCurve.Fp)
+ {
+ fail("curve not custom curve!!");
+ }
+
+ AlgorithmParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(name);
+ KeyPairGenerator keygen = KeyPairGenerator.getInstance("EC", "SC");
+ keygen.initialize(ecSpec, new ECRandom());
+
+ KeyPair keys = keygen.generateKeyPair();
+
+ PrivateKeyInfo priv1 = PrivateKeyInfo.getInstance(keys.getPrivate().getEncoded());
+ SubjectPublicKeyInfo pub1 = SubjectPublicKeyInfo.getInstance(keys.getPublic().getEncoded());
+
+ keygen = KeyPairGenerator.getInstance("EC", "SC");
+ keygen.initialize(new ECGenParameterSpec("secp256r1"), new ECRandom());
+
+ Signature ecdsaSigner = Signature.getInstance("ECDSA", "SC");
+
+ ecdsaSigner.initSign(keys.getPrivate());
+
+ ecdsaSigner.update(new byte[100]);
+
+ byte[] sig = ecdsaSigner.sign();
+
+ ecdsaSigner.initVerify(keys.getPublic());
+
+ ecdsaSigner.update(new byte[100]);
+
+ if (!ecdsaSigner.verify(sig))
+ {
+ fail("signature failed to verify");
+ }
+
+ KeyFactory kFact = KeyFactory.getInstance("EC", "SC");
+
+ PublicKey pub = kFact.generatePublic(new X509EncodedKeySpec(pub1.getEncoded()));
+ PrivateKey pri = kFact.generatePrivate(new PKCS8EncodedKeySpec(priv1.getEncoded()));
+
+ ecdsaSigner = Signature.getInstance("ECDSA", "SC");
+
+ ecdsaSigner.initSign(pri);
+
+ ecdsaSigner.update(new byte[100]);
+
+ sig = ecdsaSigner.sign();
+
+ ecdsaSigner.initVerify(pub);
+
+ ecdsaSigner.update(new byte[100]);
+
+ if (!ecdsaSigner.verify(sig))
+ {
+ fail("signature failed to verify");
+ }
+ }
+
+ protected BigInteger[] derDecode(
+ byte[] encoding)
+ throws IOException
+ {
+ ByteArrayInputStream bIn = new ByteArrayInputStream(encoding);
+ ASN1InputStream aIn = new ASN1InputStream(bIn);
+ ASN1Sequence s = (ASN1Sequence)aIn.readObject();
+
+ BigInteger[] sig = new BigInteger[2];
+
+ sig[0] = ((ASN1Integer)s.getObjectAt(0)).getValue();
+ sig[1] = ((ASN1Integer)s.getObjectAt(1)).getValue();
+
+ return sig;
+ }
+
+ public String getName()
+ {
+ return "ECDSA5";
+ }
+
+ public void performTest()
+ throws Exception
+ {
+ testKeyConversion();
+ testAdaptiveKeyConversion();
+ decodeTest();
+ testECDSA239bitPrime();
+ testECDSA239bitBinary();
+ testGeneration();
+ testKeyPairGenerationWithOIDs();
+ testNamedCurveParameterPreservation();
+ testNamedCurveSigning();
+ testBSI();
+ }
+
+ public static void main(
+ String[] args)
+ {
+ Security.addProvider(new BouncyCastleProvider());
+
+ runTest(new ECDSA5Test());
+ }
+}