aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/GOST3410Test.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/GOST3410Test.java')
-rw-r--r--libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/GOST3410Test.java517
1 files changed, 517 insertions, 0 deletions
diff --git a/libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/GOST3410Test.java b/libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/GOST3410Test.java
new file mode 100644
index 000000000..5aa64c3cf
--- /dev/null
+++ b/libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/GOST3410Test.java
@@ -0,0 +1,517 @@
+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.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+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.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Date;
+
+import org.spongycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+import org.spongycastle.jce.X509Principal;
+import org.spongycastle.jce.interfaces.ECPrivateKey;
+import org.spongycastle.jce.interfaces.ECPublicKey;
+import org.spongycastle.jce.interfaces.GOST3410PrivateKey;
+import org.spongycastle.jce.interfaces.GOST3410PublicKey;
+import org.spongycastle.jce.interfaces.PKCS12BagAttributeCarrier;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.jce.spec.ECNamedCurveGenParameterSpec;
+import org.spongycastle.jce.spec.ECParameterSpec;
+import org.spongycastle.jce.spec.ECPrivateKeySpec;
+import org.spongycastle.jce.spec.ECPublicKeySpec;
+import org.spongycastle.jce.spec.GOST3410ParameterSpec;
+import org.spongycastle.math.ec.ECCurve;
+import org.spongycastle.math.ec.ECFieldElement;
+import org.spongycastle.math.ec.ECPoint;
+import org.spongycastle.util.BigIntegers;
+import org.spongycastle.util.test.FixedSecureRandom;
+import org.spongycastle.util.test.SimpleTest;
+import org.spongycastle.x509.X509V3CertificateGenerator;
+
+public class GOST3410Test
+ extends SimpleTest
+{
+ private void ecGOST3410Test()
+ throws Exception
+ {
+
+ BigInteger r = new BigInteger("29700980915817952874371204983938256990422752107994319651632687982059210933395");
+ BigInteger s = new BigInteger("46959264877825372965922731380059061821746083849389763294914877353246631700866");
+
+ byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("53854137677348463731403841147996619241504003434302020712960838528893196233395"));
+
+ SecureRandom k = new FixedSecureRandom(kData);
+
+ BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
+
+ ECCurve curve = new ECCurve.Fp(
+ mod_p, // p
+ new BigInteger("7"), // a
+ new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b
+
+ ECParameterSpec spec = new ECParameterSpec(
+ curve,
+ new ECPoint.Fp(curve,
+ new ECFieldElement.Fp(mod_p,new BigInteger("2")), // x
+ new ECFieldElement.Fp(mod_p,new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y
+ new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q
+
+ ECPrivateKeySpec priKey = new ECPrivateKeySpec(
+ new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d
+ spec);
+
+ ECPublicKeySpec pubKey = new ECPublicKeySpec(
+ new ECPoint.Fp(curve,
+ new ECFieldElement.Fp(mod_p, new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403")), // x
+ new ECFieldElement.Fp(mod_p, new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994"))), // y
+ spec);
+
+ Signature sgr = Signature.getInstance("ECGOST3410", "SC");
+ KeyFactory f = KeyFactory.getInstance("ECGOST3410", "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("ECGOST3410 verification failed");
+ }
+
+ BigInteger[] sig = decode(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 generationTest()
+ throws Exception
+ {
+ Signature s = Signature.getInstance("GOST3410", "SC");
+ KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", "SC");
+ byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+ GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A.getId());
+
+ g.initialize(gost3410P, 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("GOST3410", "SC");
+
+ s.initVerify(vKey);
+
+ s.update(data);
+
+ if (!s.verify(sigBytes))
+ {
+ fail("GOST3410 verification failed");
+ }
+
+ //
+ // default initialisation test
+ //
+ s = Signature.getInstance("GOST3410", "SC");
+ g = KeyPairGenerator.getInstance("GOST3410", "SC");
+
+ p = g.generateKeyPair();
+
+ sKey = p.getPrivate();
+ vKey = p.getPublic();
+
+ s.initSign(sKey);
+
+ s.update(data);
+
+ sigBytes = s.sign();
+
+ s = Signature.getInstance("GOST3410", "SC");
+
+ s.initVerify(vKey);
+
+ s.update(data);
+
+ if (!s.verify(sigBytes))
+ {
+ fail("GOST3410 verification failed");
+ }
+
+ //
+ // encoded test
+ //
+ KeyFactory f = KeyFactory.getInstance("GOST3410", "SC");
+
+ X509EncodedKeySpec x509s = new X509EncodedKeySpec(vKey.getEncoded());
+ GOST3410PublicKey k1 = (GOST3410PublicKey)f.generatePublic(x509s);
+
+ if (!k1.getY().equals(((GOST3410PublicKey)vKey).getY()))
+ {
+ fail("public number not decoded properly");
+ }
+
+ if (!k1.getParameters().equals(((GOST3410PublicKey)vKey).getParameters()))
+ {
+ fail("public parameters not decoded properly");
+ }
+
+ PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(sKey.getEncoded());
+ GOST3410PrivateKey k2 = (GOST3410PrivateKey)f.generatePrivate(pkcs8);
+
+ if (!k2.getX().equals(((GOST3410PrivateKey)sKey).getX()))
+ {
+ fail("private number not decoded properly");
+ }
+
+ if (!k2.getParameters().equals(((GOST3410PrivateKey)sKey).getParameters()))
+ {
+ fail("private number not decoded properly");
+ }
+
+ k2 = (GOST3410PrivateKey)serializeDeserialize(sKey);
+ if (!k2.getX().equals(((GOST3410PrivateKey)sKey).getX()))
+ {
+ fail("private number not deserialised properly");
+ }
+
+ if (!k2.getParameters().equals(((GOST3410PrivateKey)sKey).getParameters()))
+ {
+ fail("private number not deserialised properly");
+ }
+
+ checkEquals(k2, sKey);
+
+ if (!(k2 instanceof PKCS12BagAttributeCarrier))
+ {
+ fail("private key not implementing PKCS12 attribute carrier");
+ }
+
+ k1 = (GOST3410PublicKey)serializeDeserialize(vKey);
+
+ if (!k1.getY().equals(((GOST3410PublicKey)vKey).getY()))
+ {
+ fail("public number not deserialised properly");
+ }
+
+ if (!k1.getParameters().equals(((GOST3410PublicKey)vKey).getParameters()))
+ {
+ fail("public parameters not deserialised properly");
+ }
+
+ checkEquals(k1, vKey);
+
+ //
+ // ECGOST3410 generation test
+ //
+ s = Signature.getInstance("ECGOST3410", "SC");
+ g = KeyPairGenerator.getInstance("ECGOST3410", "SC");
+
+// BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
+//
+// ECCurve curve = new ECCurve.Fp(
+// mod_p, // p
+// new BigInteger("7"), // a
+// new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b
+//
+// ECParameterSpec ecSpec = new ECParameterSpec(
+// curve,
+// new ECPoint.Fp(curve,
+// new ECFieldElement.Fp(mod_p,new BigInteger("2")), // x
+// new ECFieldElement.Fp(mod_p,new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y
+// new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q
+
+ g.initialize(new ECNamedCurveGenParameterSpec("GostR3410-2001-CryptoPro-A"), new SecureRandom());
+
+ p = g.generateKeyPair();
+
+ sKey = p.getPrivate();
+ vKey = p.getPublic();
+
+ s.initSign(sKey);
+
+ s.update(data);
+
+ sigBytes = s.sign();
+
+ s = Signature.getInstance("ECGOST3410", "SC");
+
+ s.initVerify(vKey);
+
+ s.update(data);
+
+ if (!s.verify(sigBytes))
+ {
+ fail("ECGOST3410 verification failed");
+ }
+
+ //
+ // encoded test
+ //
+ f = KeyFactory.getInstance("ECGOST3410", "SC");
+
+ x509s = new X509EncodedKeySpec(vKey.getEncoded());
+ ECPublicKey eck1 = (ECPublicKey)f.generatePublic(x509s);
+
+ if (!eck1.getQ().equals(((ECPublicKey)vKey).getQ()))
+ {
+ fail("public number not decoded properly");
+ }
+
+ if (!eck1.getParameters().equals(((ECPublicKey)vKey).getParameters()))
+ {
+ fail("public parameters not decoded properly");
+ }
+
+ pkcs8 = new PKCS8EncodedKeySpec(sKey.getEncoded());
+ ECPrivateKey eck2 = (ECPrivateKey)f.generatePrivate(pkcs8);
+
+ if (!eck2.getD().equals(((ECPrivateKey)sKey).getD()))
+ {
+ fail("private number not decoded properly");
+ }
+
+ if (!eck2.getParameters().equals(((ECPrivateKey)sKey).getParameters()))
+ {
+ fail("private number not decoded properly");
+ }
+
+ eck2 = (ECPrivateKey)serializeDeserialize(sKey);
+ if (!eck2.getD().equals(((ECPrivateKey)sKey).getD()))
+ {
+ fail("private number not decoded properly");
+ }
+
+ if (!eck2.getParameters().equals(((ECPrivateKey)sKey).getParameters()))
+ {
+ fail("private number not decoded properly");
+ }
+
+ checkEquals(eck2, sKey);
+
+ if (!(eck2 instanceof PKCS12BagAttributeCarrier))
+ {
+ fail("private key not implementing PKCS12 attribute carrier");
+ }
+
+ eck1 = (ECPublicKey)serializeDeserialize(vKey);
+
+ if (!eck1.getQ().equals(((ECPublicKey)vKey).getQ()))
+ {
+ fail("public number not decoded properly");
+ }
+
+ if (!eck1.getParameters().equals(((ECPublicKey)vKey).getParameters()))
+ {
+ fail("public parameters not decoded properly");
+ }
+
+ checkEquals(eck1, vKey);
+ }
+
+ private void keyStoreTest(PrivateKey sKey, PublicKey vKey)
+ throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, UnrecoverableKeyException
+ {
+ //
+ // keystore test
+ //
+ KeyStore ks = KeyStore.getInstance("JKS");
+
+ ks.load(null, null);
+
+ //
+ // create the certificate - version 3
+ //
+ X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
+
+ certGen.setSerialNumber(BigInteger.valueOf(1));
+ certGen.setIssuerDN(new X509Principal("CN=Test"));
+ certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000));
+ certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000));
+ certGen.setSubjectDN(new X509Principal("CN=Test"));
+ certGen.setPublicKey(vKey);
+ certGen.setSignatureAlgorithm("GOST3411withGOST3410");
+
+ X509Certificate cert = certGen.generate(sKey, "SC");
+
+ ks.setKeyEntry("gost",sKey, "gost".toCharArray(), new Certificate[] { cert });
+
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ ks.store(bOut, "gost".toCharArray());
+
+ ks = KeyStore.getInstance("JKS");
+
+ ks.load(new ByteArrayInputStream(bOut.toByteArray()), "gost".toCharArray());
+
+ PrivateKey gKey = (PrivateKey)ks.getKey("gost", "gost".toCharArray());
+ }
+
+ private void checkEquals(Object o1, Object o2)
+ {
+ if (!o1.equals(o2))
+ {
+ fail("comparison test failed");
+ }
+
+ if (o1.hashCode() != o2.hashCode())
+ {
+ fail("hashCode test failed");
+ }
+ }
+
+ private void parametersTest()
+ throws Exception
+ {
+// AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("GOST3410", "SC");
+// a.init(512, random);
+// AlgorithmParameters params = a.generateParameters();
+//
+// byte[] encodeParams = params.getEncoded();
+//
+// AlgorithmParameters a2 = AlgorithmParameters.getInstance("GOST3410", "SC");
+// a2.init(encodeParams);
+//
+// // a and a2 should be equivalent!
+// byte[] encodeParams_2 = a2.getEncoded();
+//
+// if (!arrayEquals(encodeParams, encodeParams_2))
+// {
+// fail("encode/decode parameters failed");
+// }
+
+ GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_B.getId());
+
+ KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", "SC");
+ g.initialize(gost3410P, new SecureRandom());
+ KeyPair p = g.generateKeyPair();
+
+ PrivateKey sKey = p.getPrivate();
+ PublicKey vKey = p.getPublic();
+
+ Signature s = Signature.getInstance("GOST3410", "SC");
+ byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+
+ s.initSign(sKey);
+
+ s.update(data);
+
+ byte[] sigBytes = s.sign();
+
+ s = Signature.getInstance("GOST3410", "SC");
+
+ s.initVerify(vKey);
+
+ s.update(data);
+
+ if (!s.verify(sigBytes))
+ {
+ fail("GOST3410 verification failed");
+ }
+
+ keyStoreTest(sKey, vKey);
+ }
+
+ private BigInteger[] decode(
+ byte[] encoding)
+ {
+ byte[] r = new byte[32];
+ byte[] s = new byte[32];
+
+ System.arraycopy(encoding, 0, s, 0, 32);
+
+ System.arraycopy(encoding, 32, r, 0, 32);
+
+ BigInteger[] sig = new BigInteger[2];
+
+ sig[0] = new BigInteger(1, r);
+ sig[1] = new BigInteger(1, s);
+
+ return sig;
+ }
+
+ private Object serializeDeserialize(Object o)
+ throws Exception
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ ObjectOutputStream oOut = new ObjectOutputStream(bOut);
+
+ oOut.writeObject(o);
+ oOut.close();
+
+ ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(bOut.toByteArray()));
+
+ return oIn.readObject();
+ }
+
+ public String getName()
+ {
+ return "GOST3410/ECGOST3410";
+ }
+
+ public void performTest()
+ throws Exception
+ {
+ ecGOST3410Test();
+ generationTest();
+ parametersTest();
+ }
+
+ public static void main(
+ String[] args)
+ {
+ Security.addProvider(new BouncyCastleProvider());
+
+ runTest(new GOST3410Test());
+ }
+}