001: package org.bouncycastle.crypto.test;
002:
003: import org.bouncycastle.util.encoders.Hex;
004: import org.bouncycastle.util.test.FixedSecureRandom;
005: import org.bouncycastle.util.test.SimpleTest;
006: import org.bouncycastle.math.ec.ECCurve;
007: import org.bouncycastle.math.ec.ECPoint;
008: import org.bouncycastle.math.ec.ECFieldElement;
009: import org.bouncycastle.crypto.params.*;
010: import org.bouncycastle.crypto.signers.ECGOST3410Signer;
011: import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
012: import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
013: import org.bouncycastle.crypto.digests.GOST3411Digest;
014:
015: import java.math.BigInteger;
016: import java.security.SecureRandom;
017:
018: /**
019: * ECGOST3410 tests are taken from GOST R 34.10-2001.
020: */
021: public class ECGOST3410Test extends SimpleTest {
022: byte[] hashmessage = Hex
023: .decode("3042453136414534424341374533364339313734453431443642453241453435");
024:
025: /**
026: * ECGOST3410 over the field Fp<br>
027: */
028: BigInteger r = new BigInteger(
029: "29700980915817952874371204983938256990422752107994319651632687982059210933395");
030: BigInteger s = new BigInteger(
031: "574973400270084654178925310019147038455227042649098563933718999175515839552");
032:
033: byte[] kData = new BigInteger(
034: "53854137677348463731403841147996619241504003434302020712960838528893196233395")
035: .toByteArray();
036:
037: SecureRandom k = new FixedSecureRandom(kData);
038:
039: private void ecGOST3410_TEST() {
040: BigInteger mod_p = new BigInteger(
041: "57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
042:
043: ECCurve.Fp curve = new ECCurve.Fp(
044: mod_p, // p
045: new BigInteger("7"), // a
046: new BigInteger(
047: "43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b
048:
049: ECDomainParameters params = new ECDomainParameters(
050: curve,
051: new ECPoint.Fp(curve,
052: new ECFieldElement.Fp(mod_p,
053: new BigInteger("2")), // x
054: new ECFieldElement.Fp(
055: mod_p,
056: new BigInteger(
057: "4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y
058: new BigInteger(
059: "57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q
060:
061: ECPrivateKeyParameters priKey = new ECPrivateKeyParameters(
062: new BigInteger(
063: "55441196065363246126355624130324183196576709222340016572108097750006097525544"), // d
064: params);
065:
066: ParametersWithRandom param = new ParametersWithRandom(priKey, k);
067:
068: ECGOST3410Signer ecgost3410 = new ECGOST3410Signer();
069:
070: ecgost3410.init(true, param);
071:
072: byte[] mVal = new BigInteger(
073: "20798893674476452017134061561508270130637142515379653289952617252661468872421")
074: .toByteArray();
075: byte[] message = new byte[mVal.length];
076:
077: for (int i = 0; i != mVal.length; i++) {
078: message[i] = mVal[mVal.length - 1 - i];
079: }
080:
081: BigInteger[] sig = ecgost3410.generateSignature(message);
082:
083: if (!r.equals(sig[0])) {
084: fail("r component wrong.", r, sig[0]);
085: }
086:
087: if (!s.equals(sig[1])) {
088: fail("s component wrong.", s, sig[1]);
089: }
090:
091: // Verify the signature
092: ECPublicKeyParameters pubKey = new ECPublicKeyParameters(
093: new ECPoint.Fp(
094: curve,
095: new ECFieldElement.Fp(
096: mod_p,
097: new BigInteger(
098: "57520216126176808443631405023338071176630104906313632182896741342206604859403")), // x
099: new ECFieldElement.Fp(
100: mod_p,
101: new BigInteger(
102: "17614944419213781543809391949654080031942662045363639260709847859438286763994"))), // y
103: params);
104:
105: ecgost3410.init(false, pubKey);
106: if (!ecgost3410.verifySignature(message, sig[0], sig[1])) {
107: fail("verification fails");
108: }
109: }
110:
111: /**
112: * Test Sign & Verify with test parameters
113: * see: http://www.ietf.org/internet-drafts/draft-popov-cryptopro-cpalgs-01.txt
114: * gostR3410-2001-TestParamSet P.46
115: */
116: private void ecGOST3410_TestParam() {
117: SecureRandom random = new SecureRandom();
118:
119: BigInteger mod_p = new BigInteger(
120: "57896044618658097711785492504343953926634992332820282019728792003956564821041"); //p
121:
122: ECCurve.Fp curve = new ECCurve.Fp(
123: mod_p, // p
124: new BigInteger("7"), // a
125: new BigInteger(
126: "43308876546767276905765904595650931995942111794451039583252968842033849580414")); // b
127:
128: ECDomainParameters params = new ECDomainParameters(
129: curve,
130: new ECPoint.Fp(curve,
131: new ECFieldElement.Fp(mod_p,
132: new BigInteger("2")), // x
133: new ECFieldElement.Fp(
134: mod_p,
135: new BigInteger(
136: "4018974056539037503335449422937059775635739389905545080690979365213431566280"))), // y
137: new BigInteger(
138: "57896044618658097711785492504343953927082934583725450622380973592137631069619")); // q
139:
140: ECKeyPairGenerator pGen = new ECKeyPairGenerator();
141: ECKeyGenerationParameters genParam = new ECKeyGenerationParameters(
142: params, random);
143:
144: pGen.init(genParam);
145:
146: AsymmetricCipherKeyPair pair = pGen.generateKeyPair();
147:
148: ParametersWithRandom param = new ParametersWithRandom(pair
149: .getPrivate(), random);
150:
151: ECGOST3410Signer ecgost3410 = new ECGOST3410Signer();
152:
153: ecgost3410.init(true, param);
154:
155: //get hash message using the digest GOST3411.
156: byte[] message = "Message for sign".getBytes();
157: GOST3411Digest gost3411 = new GOST3411Digest();
158: gost3411.update(message, 0, message.length);
159: byte[] hashmessage = new byte[gost3411.getDigestSize()];
160: gost3411.doFinal(hashmessage, 0);
161:
162: BigInteger[] sig = ecgost3410.generateSignature(hashmessage);
163:
164: ecgost3410.init(false, pair.getPublic());
165:
166: if (!ecgost3410.verifySignature(hashmessage, sig[0], sig[1])) {
167: fail("signature fails");
168: }
169: }
170:
171: /**
172: * Test Sign & Verify with A parameters
173: * see: http://www.ietf.org/internet-drafts/draft-popov-cryptopro-cpalgs-01.txt
174: * gostR3410-2001-CryptoPro-A-ParamSet P.47
175: */
176: public void ecGOST3410_AParam() {
177: SecureRandom random = new SecureRandom();
178:
179: BigInteger mod_p = new BigInteger(
180: "115792089237316195423570985008687907853269984665640564039457584007913129639319"); //p
181:
182: ECCurve.Fp curve = new ECCurve.Fp(
183: mod_p, // p
184: new BigInteger(
185: "115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a
186: new BigInteger("166")); // b
187:
188: ECDomainParameters params = new ECDomainParameters(
189: curve,
190: new ECPoint.Fp(curve,
191: new ECFieldElement.Fp(mod_p,
192: new BigInteger("1")), // x
193: new ECFieldElement.Fp(
194: mod_p,
195: new BigInteger(
196: "64033881142927202683649881450433473985931760268884941288852745803908878638612"))), // y
197: new BigInteger(
198: "115792089237316195423570985008687907853073762908499243225378155805079068850323")); // q
199:
200: ECKeyPairGenerator pGen = new ECKeyPairGenerator();
201: ECKeyGenerationParameters genParam = new ECKeyGenerationParameters(
202: params, random);
203:
204: pGen.init(genParam);
205:
206: AsymmetricCipherKeyPair pair = pGen.generateKeyPair();
207:
208: ParametersWithRandom param = new ParametersWithRandom(pair
209: .getPrivate(), random);
210:
211: ECGOST3410Signer ecgost3410 = new ECGOST3410Signer();
212:
213: ecgost3410.init(true, param);
214:
215: BigInteger[] sig = ecgost3410.generateSignature(hashmessage);
216:
217: ecgost3410.init(false, pair.getPublic());
218:
219: if (!ecgost3410.verifySignature(hashmessage, sig[0], sig[1])) {
220: fail("signature fails");
221: }
222: }
223:
224: /**
225: * Test Sign & Verify with B parameters
226: * see: http://www.ietf.org/internet-drafts/draft-popov-cryptopro-cpalgs-01.txt
227: * gostR3410-2001-CryptoPro-B-ParamSet P.47-48
228: */
229: private void ecGOST3410_BParam() {
230: SecureRandom random = new SecureRandom();
231:
232: BigInteger mod_p = new BigInteger(
233: "57896044618658097711785492504343953926634992332820282019728792003956564823193"); //p
234:
235: ECCurve.Fp curve = new ECCurve.Fp(
236: mod_p, // p
237: new BigInteger(
238: "57896044618658097711785492504343953926634992332820282019728792003956564823190"), // a
239: new BigInteger(
240: "28091019353058090096996979000309560759124368558014865957655842872397301267595")); // b
241:
242: ECDomainParameters params = new ECDomainParameters(
243: curve,
244: new ECPoint.Fp(curve,
245: new ECFieldElement.Fp(mod_p,
246: new BigInteger("1")), // x
247: new ECFieldElement.Fp(
248: mod_p,
249: new BigInteger(
250: "28792665814854611296992347458380284135028636778229113005756334730996303888124"))), // y
251: new BigInteger(
252: "57896044618658097711785492504343953927102133160255826820068844496087732066703")); // q
253:
254: ECKeyPairGenerator pGen = new ECKeyPairGenerator();
255: ECKeyGenerationParameters genParam = new ECKeyGenerationParameters(
256: params, random);
257:
258: pGen.init(genParam);
259:
260: AsymmetricCipherKeyPair pair = pGen.generateKeyPair();
261:
262: ParametersWithRandom param = new ParametersWithRandom(pair
263: .getPrivate(), random);
264:
265: ECGOST3410Signer ecgost3410 = new ECGOST3410Signer();
266:
267: ecgost3410.init(true, param);
268:
269: BigInteger[] sig = ecgost3410.generateSignature(hashmessage);
270:
271: ecgost3410.init(false, pair.getPublic());
272:
273: if (!ecgost3410.verifySignature(hashmessage, sig[0], sig[1])) {
274: fail("signature fails");
275: }
276: }
277:
278: /**
279: * Test Sign & Verify with C parameters
280: * see: http://www.ietf.org/internet-drafts/draft-popov-cryptopro-cpalgs-01.txt
281: * gostR3410-2001-CryptoPro-C-ParamSet P.48
282: */
283: private void ecGOST3410_CParam() {
284: SecureRandom random = new SecureRandom();
285:
286: BigInteger mod_p = new BigInteger(
287: "70390085352083305199547718019018437841079516630045180471284346843705633502619"); //p
288:
289: ECCurve.Fp curve = new ECCurve.Fp(
290: mod_p, // p
291: new BigInteger(
292: "70390085352083305199547718019018437841079516630045180471284346843705633502616"), // a
293: new BigInteger("32858")); // b
294:
295: ECDomainParameters params = new ECDomainParameters(
296: curve,
297: new ECPoint.Fp(curve,
298: new ECFieldElement.Fp(mod_p,
299: new BigInteger("0")), // x
300: new ECFieldElement.Fp(
301: mod_p,
302: new BigInteger(
303: "29818893917731240733471273240314769927240550812383695689146495261604565990247"))), // y
304: new BigInteger(
305: "70390085352083305199547718019018437840920882647164081035322601458352298396601")); // q
306:
307: ECKeyPairGenerator pGen = new ECKeyPairGenerator();
308: ECKeyGenerationParameters genParam = new ECKeyGenerationParameters(
309: params, random);
310:
311: pGen.init(genParam);
312:
313: AsymmetricCipherKeyPair pair = pGen.generateKeyPair();
314:
315: ParametersWithRandom param = new ParametersWithRandom(pair
316: .getPrivate(), random);
317:
318: ECGOST3410Signer ecgost3410 = new ECGOST3410Signer();
319:
320: ecgost3410.init(true, param);
321:
322: BigInteger[] sig = ecgost3410.generateSignature(hashmessage);
323:
324: ecgost3410.init(false, pair.getPublic());
325:
326: if (!ecgost3410.verifySignature(hashmessage, sig[0], sig[1])) {
327: fail("signature fails");
328: }
329: }
330:
331: public String getName() {
332: return "ECGOST3410";
333: }
334:
335: public void performTest() {
336: ecGOST3410_TEST();
337: ecGOST3410_TestParam();
338: ecGOST3410_AParam();
339: ecGOST3410_BParam();
340: ecGOST3410_CParam();
341: }
342:
343: public static void main(String[] args) {
344: runTest(new ECGOST3410Test());
345: }
346: }
|