1
package org.bouncycastle.jce.provider.test;
3
import java.math.BigInteger;
4
import java.security.KeyFactory;
5
import java.security.KeyPair;
6
import java.security.KeyPairGenerator;
7
import java.security.PrivateKey;
8
import java.security.PublicKey;
9
import java.security.SecureRandom;
10
import java.security.Security;
11
import java.security.Signature;
12
import java.security.KeyStore;
13
import java.security.KeyStoreException;
14
import java.security.NoSuchAlgorithmException;
15
import java.security.NoSuchProviderException;
16
import java.security.SignatureException;
17
import java.security.InvalidKeyException;
18
import java.security.UnrecoverableKeyException;
19
import java.security.cert.X509Certificate;
20
import java.security.cert.Certificate;
21
import java.security.cert.CertificateException;
22
import java.security.spec.PKCS8EncodedKeySpec;
23
import java.security.spec.X509EncodedKeySpec;
24
import java.util.Date;
25
import java.io.ByteArrayOutputStream;
26
import java.io.ByteArrayInputStream;
27
import java.io.IOException;
29
import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
30
import org.bouncycastle.jce.interfaces.GOST3410PrivateKey;
31
import org.bouncycastle.jce.interfaces.GOST3410PublicKey;
32
import org.bouncycastle.jce.provider.BouncyCastleProvider;
33
import org.bouncycastle.jce.spec.ECParameterSpec;
34
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
35
import org.bouncycastle.jce.spec.ECPublicKeySpec;
36
import org.bouncycastle.jce.spec.GOST3410ParameterSpec;
37
import org.bouncycastle.jce.X509Principal;
38
import org.bouncycastle.math.ec.ECCurve;
39
import org.bouncycastle.math.ec.ECFieldElement;
40
import org.bouncycastle.math.ec.ECPoint;
41
import org.bouncycastle.util.BigIntegers;
42
import org.bouncycastle.util.test.FixedSecureRandom;
43
import org.bouncycastle.util.test.SimpleTest;
44
import org.bouncycastle.x509.X509V3CertificateGenerator;
46
public class GOST3410Test
49
private void ecGOST3410Test()
53
BigInteger r = new BigInteger("29700980915817952874371204983938256990422752107994319651632687982059210933395");
54
BigInteger s = new BigInteger("46959264877825372965922731380059061821746083849389763294914877353246631700866");
56
byte[] kData = BigIntegers.asUnsignedByteArray(new BigInteger("53854137677348463731403841147996619241504003434302020712960838528893196233395"));
58
SecureRandom k = new FixedSecureRandom(kData);
60
BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
62
ECCurve curve = new ECCurve.Fp(
64
new BigInteger("7"), // a
65
new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b
67
ECParameterSpec spec = new ECParameterSpec(
70
new ECFieldElement.Fp(mod_p,new BigInteger("2")), // x
71
new ECFieldElement.Fp(mod_p,new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y
72
new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q
74
ECPrivateKeySpec priKey = new ECPrivateKeySpec(
75
new BigInteger("55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d
78
ECPublicKeySpec pubKey = new ECPublicKeySpec(
80
new ECFieldElement.Fp(mod_p, new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403")), // x
81
new ECFieldElement.Fp(mod_p, new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994"))), // y
84
Signature sgr = Signature.getInstance("ECGOST3410", "BC");
85
KeyFactory f = KeyFactory.getInstance("ECGOST3410", "BC");
86
PrivateKey sKey = f.generatePrivate(priKey);
87
PublicKey vKey = f.generatePublic(pubKey);
89
sgr.initSign(sKey, k);
91
byte[] message = new byte[] { (byte)'a', (byte)'b', (byte)'c' };
95
byte[] sigBytes = sgr.sign();
101
if (!sgr.verify(sigBytes))
103
fail("ECGOST3410 verification failed");
106
BigInteger[] sig = decode(sigBytes);
108
if (!r.equals(sig[0]))
111
": r component wrong." + System.getProperty("line.separator")
112
+ " expecting: " + r + System.getProperty("line.separator")
113
+ " got : " + sig[0]);
116
if (!s.equals(sig[1]))
119
": s component wrong." + System.getProperty("line.separator")
120
+ " expecting: " + s + System.getProperty("line.separator")
121
+ " got : " + sig[1]);
125
private void generationTest()
128
Signature s = Signature.getInstance("GOST3410", "BC");
129
KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", "BC");
130
byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
131
GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A.getId());
133
g.initialize(gost3410P, new SecureRandom());
135
KeyPair p = g.generateKeyPair();
137
PrivateKey sKey = p.getPrivate();
138
PublicKey vKey = p.getPublic();
144
byte[] sigBytes = s.sign();
146
s = Signature.getInstance("GOST3410", "BC");
152
if (!s.verify(sigBytes))
154
fail("GOST3410 verification failed");
158
// default iniialisation test
160
s = Signature.getInstance("GOST3410", "BC");
161
g = KeyPairGenerator.getInstance("GOST3410", "BC");
163
p = g.generateKeyPair();
165
sKey = p.getPrivate();
166
vKey = p.getPublic();
174
s = Signature.getInstance("GOST3410", "BC");
180
if (!s.verify(sigBytes))
182
fail("GOST3410 verification failed");
188
KeyFactory f = KeyFactory.getInstance("GOST3410", "BC");
190
X509EncodedKeySpec x509s = new X509EncodedKeySpec(vKey.getEncoded());
191
GOST3410PublicKey k1 = (GOST3410PublicKey)f.generatePublic(x509s);
193
if (!k1.getY().equals(((GOST3410PublicKey)vKey).getY()))
195
fail("public number not decoded properly");
198
PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(sKey.getEncoded());
199
GOST3410PrivateKey k2 = (GOST3410PrivateKey)f.generatePrivate(pkcs8);
201
if (!k2.getX().equals(((GOST3410PrivateKey)sKey).getX()))
203
fail("private number not decoded properly");
207
// ECGOST3410 generation test
209
s = Signature.getInstance("ECGOST3410", "BC");
210
g = KeyPairGenerator.getInstance("ECGOST3410", "BC");
212
BigInteger mod_p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
214
ECCurve curve = new ECCurve.Fp(
216
new BigInteger("7"), // a
217
new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b
219
ECParameterSpec ecSpec = new ECParameterSpec(
221
new ECPoint.Fp(curve,
222
new ECFieldElement.Fp(mod_p,new BigInteger("2")), // x
223
new ECFieldElement.Fp(mod_p,new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y
224
new BigInteger("57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q
226
g.initialize(ecSpec, new SecureRandom());
228
p = g.generateKeyPair();
230
sKey = p.getPrivate();
231
vKey = p.getPublic();
239
s = Signature.getInstance("ECGOST3410", "BC");
245
if (!s.verify(sigBytes))
247
fail("ECGOST3410 verification failed");
251
private void keyStoreTest(PrivateKey sKey, PublicKey vKey)
252
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, UnrecoverableKeyException
257
KeyStore ks = KeyStore.getInstance("JKS");
262
// create the certificate - version 3
264
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
266
certGen.setSerialNumber(BigInteger.valueOf(1));
267
certGen.setIssuerDN(new X509Principal("CN=Test"));
268
certGen.setNotBefore(new Date(System.currentTimeMillis() - 50000));
269
certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000));
270
certGen.setSubjectDN(new X509Principal("CN=Test"));
271
certGen.setPublicKey(vKey);
272
certGen.setSignatureAlgorithm("GOST3411withGOST3410");
274
X509Certificate cert = certGen.generate(sKey, "BC");
276
ks.setKeyEntry("gost",sKey, "gost".toCharArray(), new Certificate[] { cert });
278
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
280
ks.store(bOut, "gost".toCharArray());
282
ks = KeyStore.getInstance("JKS");
284
ks.load(new ByteArrayInputStream(bOut.toByteArray()), "gost".toCharArray());
286
PrivateKey gKey = (PrivateKey)ks.getKey("gost", "gost".toCharArray());
289
private void parametersTest()
292
// AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("GOST3410", "BC");
293
// a.init(512, random);
294
// AlgorithmParameters params = a.generateParameters();
296
// byte[] encodeParams = params.getEncoded();
298
// AlgorithmParameters a2 = AlgorithmParameters.getInstance("GOST3410", "BC");
299
// a2.init(encodeParams);
301
// // a and a2 should be equivalent!
302
// byte[] encodeParams_2 = a2.getEncoded();
304
// if (!arrayEquals(encodeParams, encodeParams_2))
306
// fail("encode/decode parameters failed");
309
GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_B.getId());
311
KeyPairGenerator g = KeyPairGenerator.getInstance("GOST3410", "BC");
312
g.initialize(gost3410P, new SecureRandom());
313
KeyPair p = g.generateKeyPair();
315
PrivateKey sKey = p.getPrivate();
316
PublicKey vKey = p.getPublic();
318
Signature s = Signature.getInstance("GOST3410", "BC");
319
byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
325
byte[] sigBytes = s.sign();
327
s = Signature.getInstance("GOST3410", "BC");
333
if (!s.verify(sigBytes))
335
fail("GOST3410 verification failed");
338
keyStoreTest(sKey, vKey);
341
private BigInteger[] decode(
344
byte[] r = new byte[32];
345
byte[] s = new byte[32];
347
System.arraycopy(encoding, 0, s, 0, 32);
349
System.arraycopy(encoding, 32, r, 0, 32);
351
BigInteger[] sig = new BigInteger[2];
353
sig[0] = new BigInteger(1, r);
354
sig[1] = new BigInteger(1, s);
359
public String getName()
361
return "GOST3410/ECGOST3410";
364
public void performTest()
372
public static void main(
375
Security.addProvider(new BouncyCastleProvider());
377
runTest(new GOST3410Test());