001: package org.bouncycastle.crypto.test;
002:
003: import java.math.BigInteger;
004: import java.security.SecureRandom;
005:
006: import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
007: import org.bouncycastle.crypto.agreement.DHAgreement;
008: import org.bouncycastle.crypto.agreement.DHBasicAgreement;
009: import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator;
010: import org.bouncycastle.crypto.generators.DHKeyPairGenerator;
011: import org.bouncycastle.crypto.generators.DHParametersGenerator;
012: import org.bouncycastle.crypto.params.DHKeyGenerationParameters;
013: import org.bouncycastle.crypto.params.DHParameters;
014: import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
015: import org.bouncycastle.crypto.params.DHPublicKeyParameters;
016: import org.bouncycastle.crypto.params.ParametersWithRandom;
017: import org.bouncycastle.util.test.SimpleTest;
018:
019: public class DHTest extends SimpleTest {
020: private BigInteger g512 = new BigInteger(
021: "153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc",
022: 16);
023: private BigInteger p512 = new BigInteger(
024: "9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b",
025: 16);
026:
027: private BigInteger g768 = new BigInteger(
028: "7c240073c1316c621df461b71ebb0cdcc90a6e5527e5e126633d131f87461c4dc4afc60c2cb0f053b6758871489a69613e2a8b4c8acde23954c08c81cbd36132cfd64d69e4ed9f8e51ed6e516297206672d5c0a69135df0a5dcf010d289a9ca1",
029: 16);
030: private BigInteger p768 = new BigInteger(
031: "8c9dd223debed1b80103b8b309715be009d48860ed5ae9b9d5d8159508efd802e3ad4501a7f7e1cfec78844489148cd72da24b21eddd01aa624291c48393e277cfc529e37075eccef957f3616f962d15b44aeab4039d01b817fde9eaa12fd73f",
032: 16);
033:
034: private BigInteger g1024 = new BigInteger(
035: "1db17639cdf96bc4eabba19454f0b7e5bd4e14862889a725c96eb61048dcd676ceb303d586e30f060dbafd8a571a39c4d823982117da5cc4e0f89c77388b7a08896362429b94a18a327604eb7ff227bffbc83459ade299e57b5f77b50fb045250934938efa145511166e3197373e1b5b1e52de713eb49792bedde722c6717abf",
036: 16);
037: private BigInteger p1024 = new BigInteger(
038: "a00e283b3c624e5b2b4d9fbc2653b5185d99499b00fd1bf244c6f0bb817b4d1c451b2958d62a0f8a38caef059fb5ecd25d75ed9af403f5b5bdab97a642902f824e3c13789fed95fa106ddfe0ff4a707c85e2eb77d49e68f2808bcea18ce128b178cd287c6bc00efa9a1ad2a673fe0dceace53166f75b81d6709d5f8af7c66bb7",
039: 16);
040:
041: public String getName() {
042: return "DH";
043: }
044:
045: private void testDH(int size, BigInteger g, BigInteger p) {
046: DHKeyPairGenerator kpGen = getDHKeyPairGenerator(g, p);
047:
048: //
049: // generate first pair
050: //
051: AsymmetricCipherKeyPair pair = kpGen.generateKeyPair();
052:
053: DHPublicKeyParameters pu1 = (DHPublicKeyParameters) pair
054: .getPublic();
055: DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters) pair
056: .getPrivate();
057: //
058: // generate second pair
059: //
060: pair = kpGen.generateKeyPair();
061:
062: DHPublicKeyParameters pu2 = (DHPublicKeyParameters) pair
063: .getPublic();
064: DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters) pair
065: .getPrivate();
066:
067: //
068: // two way
069: //
070: DHAgreement e1 = new DHAgreement();
071: DHAgreement e2 = new DHAgreement();
072:
073: e1.init(pv1);
074: e2.init(pv2);
075:
076: BigInteger m1 = e1.calculateMessage();
077: BigInteger m2 = e2.calculateMessage();
078:
079: BigInteger k1 = e1.calculateAgreement(pu2, m2);
080: BigInteger k2 = e2.calculateAgreement(pu1, m1);
081:
082: if (!k1.equals(k2)) {
083: fail(size + " bit 2-way test failed");
084: }
085: }
086:
087: private void testDHBasic(int size, int privateValueSize,
088: BigInteger g, BigInteger p) {
089: DHBasicKeyPairGenerator kpGen = getDHBasicKeyPairGenerator(g,
090: p, privateValueSize);
091:
092: //
093: // generate first pair
094: //
095: AsymmetricCipherKeyPair pair = kpGen.generateKeyPair();
096:
097: DHPublicKeyParameters pu1 = (DHPublicKeyParameters) pair
098: .getPublic();
099: DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters) pair
100: .getPrivate();
101:
102: checkKeySize(privateValueSize, pv1);
103: //
104: // generate second pair
105: //
106: pair = kpGen.generateKeyPair();
107:
108: DHPublicKeyParameters pu2 = (DHPublicKeyParameters) pair
109: .getPublic();
110: DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters) pair
111: .getPrivate();
112:
113: checkKeySize(privateValueSize, pv2);
114: //
115: // two way
116: //
117: DHBasicAgreement e1 = new DHBasicAgreement();
118: DHBasicAgreement e2 = new DHBasicAgreement();
119:
120: e1.init(pv1);
121: e2.init(pv2);
122:
123: BigInteger k1 = e1.calculateAgreement(pu2);
124: BigInteger k2 = e2.calculateAgreement(pu1);
125:
126: if (!k1.equals(k2)) {
127: fail("basic " + size + " bit 2-way test failed");
128: }
129: }
130:
131: private void checkKeySize(int privateValueSize,
132: DHPrivateKeyParameters priv) {
133: if (privateValueSize != 0) {
134: if (priv.getX().bitLength() != privateValueSize) {
135: fail("limited key check failed for key size "
136: + privateValueSize);
137: }
138: }
139: }
140:
141: private void testGPWithRandom(DHKeyPairGenerator kpGen) {
142: //
143: // generate first pair
144: //
145: AsymmetricCipherKeyPair pair = kpGen.generateKeyPair();
146:
147: DHPublicKeyParameters pu1 = (DHPublicKeyParameters) pair
148: .getPublic();
149: DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters) pair
150: .getPrivate();
151: //
152: // generate second pair
153: //
154: pair = kpGen.generateKeyPair();
155:
156: DHPublicKeyParameters pu2 = (DHPublicKeyParameters) pair
157: .getPublic();
158: DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters) pair
159: .getPrivate();
160:
161: //
162: // two way
163: //
164: DHAgreement e1 = new DHAgreement();
165: DHAgreement e2 = new DHAgreement();
166:
167: e1.init(new ParametersWithRandom(pv1, new SecureRandom()));
168: e2.init(new ParametersWithRandom(pv2, new SecureRandom()));
169:
170: BigInteger m1 = e1.calculateMessage();
171: BigInteger m2 = e2.calculateMessage();
172:
173: BigInteger k1 = e1.calculateAgreement(pu2, m2);
174: BigInteger k2 = e2.calculateAgreement(pu1, m1);
175:
176: if (!k1.equals(k2)) {
177: fail("basic with random 2-way test failed");
178: }
179: }
180:
181: private void testSimpleWithRandom(DHBasicKeyPairGenerator kpGen) {
182: //
183: // generate first pair
184: //
185: AsymmetricCipherKeyPair pair = kpGen.generateKeyPair();
186:
187: DHPublicKeyParameters pu1 = (DHPublicKeyParameters) pair
188: .getPublic();
189: DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters) pair
190: .getPrivate();
191: //
192: // generate second pair
193: //
194: pair = kpGen.generateKeyPair();
195:
196: DHPublicKeyParameters pu2 = (DHPublicKeyParameters) pair
197: .getPublic();
198: DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters) pair
199: .getPrivate();
200:
201: //
202: // two way
203: //
204: DHBasicAgreement e1 = new DHBasicAgreement();
205: DHBasicAgreement e2 = new DHBasicAgreement();
206:
207: e1.init(new ParametersWithRandom(pv1, new SecureRandom()));
208: e2.init(new ParametersWithRandom(pv2, new SecureRandom()));
209:
210: BigInteger k1 = e1.calculateAgreement(pu2);
211: BigInteger k2 = e2.calculateAgreement(pu1);
212:
213: if (!k1.equals(k2)) {
214: fail("basic with random 2-way test failed");
215: }
216: }
217:
218: private DHBasicKeyPairGenerator getDHBasicKeyPairGenerator(
219: BigInteger g, BigInteger p, int privateValueSize) {
220: DHParameters dhParams = new DHParameters(p, g, null,
221: privateValueSize);
222: DHKeyGenerationParameters params = new DHKeyGenerationParameters(
223: new SecureRandom(), dhParams);
224: DHBasicKeyPairGenerator kpGen = new DHBasicKeyPairGenerator();
225:
226: kpGen.init(params);
227:
228: return kpGen;
229: }
230:
231: private DHKeyPairGenerator getDHKeyPairGenerator(BigInteger g,
232: BigInteger p) {
233: DHParameters dhParams = new DHParameters(p, g);
234: DHKeyGenerationParameters params = new DHKeyGenerationParameters(
235: new SecureRandom(), dhParams);
236: DHKeyPairGenerator kpGen = new DHKeyPairGenerator();
237:
238: kpGen.init(params);
239:
240: return kpGen;
241: }
242:
243: /**
244: * this test is can take quiet a while
245: */
246: private void testGeneration(int size) {
247: DHParametersGenerator pGen = new DHParametersGenerator();
248:
249: pGen.init(size, 10, new SecureRandom());
250:
251: DHParameters dhParams = pGen.generateParameters();
252:
253: if (dhParams.getJ() != 0) {
254: fail("DHParametersGenerator failed to set J to 0 in generated DHParameters");
255: }
256:
257: DHKeyGenerationParameters params = new DHKeyGenerationParameters(
258: new SecureRandom(), dhParams);
259:
260: DHBasicKeyPairGenerator kpGen = new DHBasicKeyPairGenerator();
261:
262: kpGen.init(params);
263:
264: //
265: // generate first pair
266: //
267: AsymmetricCipherKeyPair pair = kpGen.generateKeyPair();
268:
269: DHPublicKeyParameters pu1 = (DHPublicKeyParameters) pair
270: .getPublic();
271: DHPrivateKeyParameters pv1 = (DHPrivateKeyParameters) pair
272: .getPrivate();
273:
274: //
275: // generate second pair
276: //
277: params = new DHKeyGenerationParameters(new SecureRandom(), pu1
278: .getParameters());
279:
280: kpGen.init(params);
281:
282: pair = kpGen.generateKeyPair();
283:
284: DHPublicKeyParameters pu2 = (DHPublicKeyParameters) pair
285: .getPublic();
286: DHPrivateKeyParameters pv2 = (DHPrivateKeyParameters) pair
287: .getPrivate();
288:
289: //
290: // two way
291: //
292: DHBasicAgreement e1 = new DHBasicAgreement();
293: DHBasicAgreement e2 = new DHBasicAgreement();
294:
295: e1.init(new ParametersWithRandom(pv1, new SecureRandom()));
296: e2.init(new ParametersWithRandom(pv2, new SecureRandom()));
297:
298: BigInteger k1 = e1.calculateAgreement(pu2);
299: BigInteger k2 = e2.calculateAgreement(pu1);
300:
301: if (!k1.equals(k2)) {
302: fail("basic with " + size + " bit 2-way test failed");
303: }
304: }
305:
306: public void performTest() {
307: testDHBasic(512, 0, g512, p512);
308: testDHBasic(768, 0, g768, p768);
309: testDHBasic(1024, 0, g1024, p1024);
310:
311: testDHBasic(512, 64, g512, p512);
312: testDHBasic(768, 128, g768, p768);
313: testDHBasic(1024, 256, g1024, p1024);
314:
315: testDH(512, g512, p512);
316: testDH(768, g768, p768);
317: testDH(1024, g1024, p1024);
318:
319: //
320: // generation test.
321: //
322: testGeneration(256);
323:
324: //
325: // with random test
326: //
327: DHBasicKeyPairGenerator kpBasicGen = getDHBasicKeyPairGenerator(
328: g512, p512, 0);
329:
330: testSimpleWithRandom(kpBasicGen);
331:
332: DHKeyPairGenerator kpGen = getDHKeyPairGenerator(g512, p512);
333:
334: testGPWithRandom(kpGen);
335:
336: //
337: // parameter tests
338: //
339: DHAgreement dh = new DHAgreement();
340: AsymmetricCipherKeyPair dhPair = kpGen.generateKeyPair();
341:
342: try {
343: dh.init(dhPair.getPublic());
344: fail("DHAgreement key check failed");
345: } catch (IllegalArgumentException e) {
346: // ignore
347: }
348:
349: DHKeyPairGenerator kpGen768 = getDHKeyPairGenerator(g768, p768);
350:
351: try {
352: dh.init(dhPair.getPrivate());
353:
354: dh.calculateAgreement((DHPublicKeyParameters) kpGen768
355: .generateKeyPair().getPublic(), BigInteger
356: .valueOf(100));
357:
358: fail("DHAgreement agreement check failed");
359: } catch (IllegalArgumentException e) {
360: // ignore
361: }
362:
363: DHBasicAgreement dhBasic = new DHBasicAgreement();
364: AsymmetricCipherKeyPair dhBasicPair = kpBasicGen
365: .generateKeyPair();
366:
367: try {
368: dhBasic.init(dhBasicPair.getPublic());
369: fail("DHBasicAgreement key check failed");
370: } catch (IllegalArgumentException e) {
371: // expected
372: }
373:
374: DHBasicKeyPairGenerator kpBasicGen768 = getDHBasicKeyPairGenerator(
375: g768, p768, 0);
376:
377: try {
378: dhBasic.init(dhPair.getPrivate());
379:
380: dhBasic
381: .calculateAgreement((DHPublicKeyParameters) kpBasicGen768
382: .generateKeyPair().getPublic());
383:
384: fail("DHBasicAgreement agreement check failed");
385: } catch (IllegalArgumentException e) {
386: // expected
387: }
388: }
389:
390: public static void main(String[] args) {
391: runTest(new DHTest());
392: }
393: }
|