~zooko/cryptopp/trunk

1 by weidai
Initial revision
1
// validat2.cpp - written and placed in the public domain by Wei Dai
2
3
#include "pch.h"
4
5
#include "blumshub.h"
6
#include "rsa.h"
7
#include "md2.h"
8
#include "elgamal.h"
9
#include "nr.h"
10
#include "dsa.h"
11
#include "dh.h"
12
#include "mqv.h"
13
#include "luc.h"
14
#include "xtrcrypt.h"
15
#include "rabin.h"
16
#include "rw.h"
17
#include "eccrypto.h"
18
#include "ecp.h"
19
#include "ec2n.h"
20
#include "asn.h"
21
#include "rng.h"
22
#include "files.h"
23
#include "hex.h"
24
#include "oids.h"
25
#include "esign.h"
26
#include "osrng.h"
27
28
#include <iostream>
29
#include <iomanip>
30
31
#include "validate.h"
32
33
USING_NAMESPACE(CryptoPP)
34
USING_NAMESPACE(std)
35
36
class FixedRNG : public RandomNumberGenerator
37
{
38
public:
39
	FixedRNG(BufferedTransformation &source) : m_source(source) {}
40
41
	byte GenerateByte()
42
	{
43
		byte b;
44
		m_source.Get(b);
45
		return b;
46
	}
47
48
private:
49
	BufferedTransformation &m_source;
50
};
51
52
bool ValidateBBS()
53
{
54
	cout << "\nBlumBlumShub validation suite running...\n\n";
55
56
	Integer p("212004934506826557583707108431463840565872545889679278744389317666981496005411448865750399674653351");
57
	Integer q("100677295735404212434355574418077394581488455772477016953458064183204108039226017738610663984508231");
58
	Integer seed("63239752671357255800299643604761065219897634268887145610573595874544114193025997412441121667211431");
59
	BlumBlumShub bbs(p, q, seed);
60
	bool pass = true, fail;
61
	int j;
62
63
	const byte output1[] = {
64
		0x49,0xEA,0x2C,0xFD,0xB0,0x10,0x64,0xA0,0xBB,0xB9,
65
		0x2A,0xF1,0x01,0xDA,0xC1,0x8A,0x94,0xF7,0xB7,0xCE};
66
	const byte output2[] = {
67
		0x74,0x45,0x48,0xAE,0xAC,0xB7,0x0E,0xDF,0xAF,0xD7,
68
		0xD5,0x0E,0x8E,0x29,0x83,0x75,0x6B,0x27,0x46,0xA1};
69
70
	byte buf[20];
71
72
	bbs.GenerateBlock(buf, 20);
73
	fail = memcmp(output1, buf, 20) != 0;
74
	pass = pass && !fail;
75
76
	cout << (fail ? "FAILED    " : "passed    ");
77
	for (j=0;j<20;j++)
78
		cout << setw(2) << setfill('0') << hex << (int)buf[j];
79
	cout << endl;
80
81
	bbs.Seek(10);
82
	bbs.GenerateBlock(buf, 10);
83
	fail = memcmp(output1+10, buf, 10) != 0;
84
	pass = pass && !fail;
85
86
	cout << (fail ? "FAILED    " : "passed    ");
87
	for (j=0;j<10;j++)
88
		cout << setw(2) << setfill('0') << hex << (int)buf[j];
89
	cout << endl;
90
91
	bbs.Seek(1234567);
92
	bbs.GenerateBlock(buf, 20);
93
	fail = memcmp(output2, buf, 20) != 0;
94
	pass = pass && !fail;
95
96
	cout << (fail ? "FAILED    " : "passed    ");
97
	for (j=0;j<20;j++)
98
		cout << setw(2) << setfill('0') << hex << (int)buf[j];
99
	cout << endl;
100
101
	return pass;
102
}
103
104
bool SignatureValidate(PK_Signer &priv, PK_Verifier &pub, bool thorough = false)
105
{
106
	bool pass = true, fail;
107
108
	fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2);
109
	pass = pass && !fail;
110
111
	cout << (fail ? "FAILED    " : "passed    ");
112
	cout << "signature key validation\n";
113
114
	const byte *message = (byte *)"test message";
115
	const int messageLen = 12;
116
27 by weidai
various changes for 5.1
117
	SecByteBlock signature(priv.MaxSignatureLength());
118
	unsigned int signatureLength = priv.SignMessage(GlobalRNG(), message, messageLen, signature);
119
	fail = !pub.VerifyMessage(message, messageLen, signature, signatureLength);
1 by weidai
Initial revision
120
	pass = pass && !fail;
121
122
	cout << (fail ? "FAILED    " : "passed    ");
123
	cout << "signature and verification\n";
124
27 by weidai
various changes for 5.1
125
	++signature[0];
126
	fail = pub.VerifyMessage(message, messageLen, signature, signatureLength);
1 by weidai
Initial revision
127
	pass = pass && !fail;
128
129
	cout << (fail ? "FAILED    " : "passed    ");
130
	cout << "checking invalid signature" << endl;
131
27 by weidai
various changes for 5.1
132
	if (priv.MaxRecoverableLength() > 0)
133
	{
134
		signatureLength = priv.SignMessageWithRecovery(GlobalRNG(), message, messageLen, NULL, 0, signature);
135
		SecByteBlock recovered(priv.MaxRecoverableLengthFromSignatureLength(signatureLength));
136
		DecodingResult result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength);
137
		fail = !(result.isValidCoding && result.messageLength == messageLen && memcmp(recovered, message, messageLen) == 0);
138
		pass = pass && !fail;
139
140
		cout << (fail ? "FAILED    " : "passed    ");
141
		cout << "signature and verification with recovery" << endl;
142
143
		++signature[0];
144
		result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength);
145
		fail = result.isValidCoding;
146
		pass = pass && !fail;
147
148
		cout << (fail ? "FAILED    " : "passed    ");
149
		cout << "recovery with invalid signature" << endl;
150
	}
151
1 by weidai
Initial revision
152
	return pass;
153
}
154
155
bool CryptoSystemValidate(PK_Decryptor &priv, PK_Encryptor &pub, bool thorough = false)
156
{
157
	bool pass = true, fail;
158
159
	fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2);
160
	pass = pass && !fail;
161
162
	cout << (fail ? "FAILED    " : "passed    ");
163
	cout << "cryptosystem key validation\n";
164
165
	const byte *message = (byte *)"test message";
166
	const int messageLen = 12;
167
	SecByteBlock ciphertext(priv.CiphertextLength(messageLen));
168
	SecByteBlock plaintext(priv.MaxPlaintextLength(ciphertext.size()));
169
170
	pub.Encrypt(GlobalRNG(), message, messageLen, ciphertext);
27 by weidai
various changes for 5.1
171
	fail = priv.Decrypt(GlobalRNG(), ciphertext, priv.CiphertextLength(messageLen), plaintext) != DecodingResult(messageLen);
1 by weidai
Initial revision
172
	fail = fail || memcmp(message, plaintext, messageLen);
173
	pass = pass && !fail;
174
175
	cout << (fail ? "FAILED    " : "passed    ");
176
	cout << "encryption and decryption\n";
177
178
	return pass;
179
}
180
181
bool SimpleKeyAgreementValidate(SimpleKeyAgreementDomain &d)
182
{
183
	if (d.GetCryptoParameters().Validate(GlobalRNG(), 3))
184
		cout << "passed    simple key agreement domain parameters validation" << endl;
185
	else
186
	{
187
		cout << "FAILED    simple key agreement domain parameters invalid" << endl;
188
		return false;
189
	}
190
191
	SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength());
192
	SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength());
193
	SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength());
194
195
	d.GenerateKeyPair(GlobalRNG(), priv1, pub1);
196
	d.GenerateKeyPair(GlobalRNG(), priv2, pub2);
197
198
	memset(val1.begin(), 0x10, val1.size());
199
	memset(val2.begin(), 0x11, val2.size());
200
201
	if (!(d.Agree(val1, priv1, pub2) && d.Agree(val2, priv2, pub1)))
202
	{
203
		cout << "FAILED    simple key agreement failed" << endl;
204
		return false;
205
	}
206
207
	if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength()))
208
	{
209
		cout << "FAILED    simple agreed values not equal" << endl;
210
		return false;
211
	}
212
213
	cout << "passed    simple key agreement" << endl;
214
	return true;
215
}
216
217
bool AuthenticatedKeyAgreementValidate(AuthenticatedKeyAgreementDomain &d)
218
{
219
	if (d.GetCryptoParameters().Validate(GlobalRNG(), 3))
220
		cout << "passed    authenticated key agreement domain parameters validation" << endl;
221
	else
222
	{
223
		cout << "FAILED    authenticated key agreement domain parameters invalid" << endl;
224
		return false;
225
	}
226
227
	SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength());
228
	SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength());
229
	SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength());
230
	SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength());
231
	SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength());
232
233
	d.GenerateStaticKeyPair(GlobalRNG(), spriv1, spub1);
234
	d.GenerateStaticKeyPair(GlobalRNG(), spriv2, spub2);
235
	d.GenerateEphemeralKeyPair(GlobalRNG(), epriv1, epub1);
236
	d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2);
237
238
	memset(val1.begin(), 0x10, val1.size());
239
	memset(val2.begin(), 0x11, val2.size());
240
241
	if (!(d.Agree(val1, spriv1, epriv1, spub2, epub2) && d.Agree(val2, spriv2, epriv2, spub1, epub1)))
242
	{
243
		cout << "FAILED    authenticated key agreement failed" << endl;
244
		return false;
245
	}
246
247
	if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength()))
248
	{
249
		cout << "FAILED    authenticated agreed values not equal" << endl;
250
		return false;
251
	}
252
253
	cout << "passed    authenticated key agreement" << endl;
254
	return true;
255
}
256
257
bool ValidateRSA()
258
{
259
	cout << "\nRSA validation suite running...\n\n";
260
261
	byte out[100], outPlain[100];
262
	bool pass = true, fail;
263
264
	{
265
		char *plain = "Everyone gets Friday off.";
266
		byte *signature = (byte *)
267
			"\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84"
268
			"\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21"
269
			"\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b"
270
			"\x5c\x77\xdf\xd9\xb1\x5b\xfc\x3d\x55\x93\x53\x50\x34\x10\xc1\xe1";
271
272
		FileSource keys("rsa512a.dat", true, new HexDecoder);
273
		RSASSA_PKCS1v15_MD2_Signer rsaPriv(keys);
274
		RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv);
275
27 by weidai
various changes for 5.1
276
		unsigned int signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out);
1 by weidai
Initial revision
277
		fail = memcmp(signature, out, 64) != 0;
278
		pass = pass && !fail;
279
280
		cout << (fail ? "FAILED    " : "passed    ");
281
		cout << "signature check against test vector\n";
282
27 by weidai
various changes for 5.1
283
		fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
1 by weidai
Initial revision
284
		pass = pass && !fail;
285
286
		cout << (fail ? "FAILED    " : "passed    ");
287
		cout << "verification check against test vector\n";
288
289
		out[10]++;
27 by weidai
various changes for 5.1
290
		fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
1 by weidai
Initial revision
291
		pass = pass && !fail;
292
293
		cout << (fail ? "FAILED    " : "passed    ");
294
		cout << "invalid signature verification\n";
295
	}
296
	{
297
		FileSource keys("rsa1024.dat", true, new HexDecoder);
298
		RSAES_PKCS1v15_Decryptor rsaPriv(keys);
299
		RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv);
300
301
		pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass;
302
	}
303
	{
304
		byte *plain = (byte *)
305
			"\x54\x85\x9b\x34\x2c\x49\xea\x2a";
306
		byte *encrypted = (byte *)
307
			"\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
308
			"\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
309
			"\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
310
			"\x62\x51";
311
		byte *oaepSeed = (byte *)
312
			"\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2"
313
			"\xf0\x6c\xb5\x8f";
314
		ByteQueue bq;
315
		bq.Put(oaepSeed, 20);
316
		FixedRNG rng(bq);
317
318
		FileSource privFile("rsa400pv.dat", true, new HexDecoder);
319
		FileSource pubFile("rsa400pb.dat", true, new HexDecoder);
320
		RSAES_OAEP_SHA_Decryptor rsaPriv;
321
		rsaPriv.AccessKey().BERDecodeKey(privFile);
322
		RSAES_OAEP_SHA_Encryptor rsaPub(pubFile);
323
324
		memset(out, 0, 50);
325
		memset(outPlain, 0, 8);
326
		rsaPub.Encrypt(rng, plain, 8, out);
27 by weidai
various changes for 5.1
327
		DecodingResult result = rsaPriv.FixedLengthDecrypt(GlobalRNG(), encrypted, outPlain);
1 by weidai
Initial revision
328
		fail = !result.isValidCoding || (result.messageLength!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8);
329
		pass = pass && !fail;
330
331
		cout << (fail ? "FAILED    " : "passed    ");
332
		cout << "PKCS 2.0 encryption and decryption\n";
333
	}
334
335
	return pass;
336
}
337
338
bool ValidateDH()
339
{
340
	cout << "\nDH validation suite running...\n\n";
341
342
	FileSource f("dh1024.dat", true, new HexDecoder());
343
	DH dh(f);
344
	return SimpleKeyAgreementValidate(dh);
345
}
346
347
bool ValidateMQV()
348
{
349
	cout << "\nMQV validation suite running...\n\n";
350
351
	FileSource f("mqv1024.dat", true, new HexDecoder());
352
	MQV mqv(f);
353
	return AuthenticatedKeyAgreementValidate(mqv);
354
}
355
356
bool ValidateLUC_DH()
357
{
358
	cout << "\nLUC-DH validation suite running...\n\n";
359
360
	FileSource f("lucd512.dat", true, new HexDecoder());
361
	LUC_DH dh(f);
362
	return SimpleKeyAgreementValidate(dh);
363
}
364
365
bool ValidateXTR_DH()
366
{
367
	cout << "\nXTR-DH validation suite running...\n\n";
368
369
	FileSource f("xtrdh171.dat", true, new HexDecoder());
370
	XTR_DH dh(f);
371
	return SimpleKeyAgreementValidate(dh);
372
}
373
374
bool ValidateElGamal()
375
{
376
	cout << "\nElGamal validation suite running...\n\n";
377
	bool pass = true;
378
	{
379
		FileSource fc("elgc1024.dat", true, new HexDecoder);
380
		ElGamalDecryptor privC(fc);
381
		ElGamalEncryptor pubC(privC);
382
		privC.AccessKey().Precompute();
383
		ByteQueue queue;
384
		privC.AccessKey().SavePrecomputation(queue);
385
		privC.AccessKey().LoadPrecomputation(queue);
386
387
		pass = CryptoSystemValidate(privC, pubC) && pass;
388
	}
389
	return pass;
390
}
391
392
bool ValidateDLIES()
393
{
394
	cout << "\nDLIES validation suite running...\n\n";
395
	bool pass = true;
396
	{
397
		FileSource fc("dlie1024.dat", true, new HexDecoder);
398
		DLIES<>::Decryptor privC(fc);
399
		DLIES<>::Encryptor pubC(privC);
400
		pass = CryptoSystemValidate(privC, pubC) && pass;
401
	}
402
	{
403
		cout << "Generating new encryption key..." << endl;
404
		DLIES<>::GroupParameters gp;
405
		gp.GenerateRandomWithKeySize(GlobalRNG(), 128);
406
		DLIES<>::Decryptor decryptor;
407
		decryptor.AccessKey().GenerateRandom(GlobalRNG(), gp);
408
		DLIES<>::Encryptor encryptor(decryptor);
409
410
		pass = CryptoSystemValidate(decryptor, encryptor) && pass;
411
	}
412
	return pass;
413
}
414
415
bool ValidateNR()
416
{
417
	cout << "\nNR validation suite running...\n\n";
418
	bool pass = true;
419
	{
420
		FileSource f("nr2048.dat", true, new HexDecoder);
421
		NR<SHA>::Signer privS(f);
422
		privS.AccessKey().Precompute();
423
		NR<SHA>::Verifier pubS(privS);
424
425
		pass = SignatureValidate(privS, pubS) && pass;
426
	}
427
	{
428
		cout << "Generating new signature key..." << endl;
429
		NR<SHA>::Signer privS(GlobalRNG(), 256);
430
		NR<SHA>::Verifier pubS(privS);
431
432
		pass = SignatureValidate(privS, pubS) && pass;
433
	}
434
	return pass;
435
}
436
437
bool ValidateDSA(bool thorough)
438
{
439
	cout << "\nDSA validation suite running...\n\n";
440
441
	bool pass = true, fail;
442
	{
443
	FileSource fs("dsa512.dat", true, new HexDecoder());
444
	GDSA<SHA>::Signer priv(fs);
445
	priv.AccessKey().Precompute(16);
446
	GDSA<SHA>::Verifier pub(priv);
447
448
	byte seed[]={0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 
449
				 0x1b, 0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3};
450
	Integer k("358dad57 1462710f 50e254cf 1a376b2b deaadfbfh");
451
	Integer h("a9993e36 4706816a ba3e2571 7850c26c 9cd0d89dh");
452
	byte sig[]={0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43, 0x5c, 0xb7, 0x18,
453
				0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3, 0x41, 0xc0, 
454
				0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf, 0x24, 0x58, 0xf4, 
455
				0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc, 0xd8, 0xc8};
456
	Integer r(sig, 20);
457
	Integer s(sig+20, 20);
458
459
	Integer pGen, qGen, rOut, sOut;
460
	int c;
461
462
	fail = !DSA::GeneratePrimes(seed, 160, c, pGen, 512, qGen);
463
	fail = fail || (pGen != pub.GetKey().GetGroupParameters().GetModulus()) || (qGen != pub.GetKey().GetGroupParameters().GetSubgroupOrder());
464
	pass = pass && !fail;
465
466
	cout << (fail ? "FAILED    " : "passed    ");
467
	cout << "prime generation test\n";
468
27 by weidai
various changes for 5.1
469
	priv.RawSign(k, h, rOut, sOut);
1 by weidai
Initial revision
470
	fail = (rOut != r) || (sOut != s);
471
	pass = pass && !fail;
472
473
	cout << (fail ? "FAILED    " : "passed    ");
474
	cout << "signature check against test vector\n";
475
27 by weidai
various changes for 5.1
476
	fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig));
1 by weidai
Initial revision
477
	pass = pass && !fail;
478
479
	cout << (fail ? "FAILED    " : "passed    ");
480
	cout << "verification check against test vector\n";
481
27 by weidai
various changes for 5.1
482
	fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig));
1 by weidai
Initial revision
483
	pass = pass && !fail;
484
	}
485
	FileSource fs1("dsa1024.dat", true, new HexDecoder());
486
	DSA::Signer priv(fs1);
487
	DSA::Verifier pub(priv);
488
	FileSource fs2("dsa1024b.dat", true, new HexDecoder());
489
	DSA::Verifier pub1(fs2);
490
	assert(pub.GetKey() == pub1.GetKey());
491
	pass = SignatureValidate(priv, pub, thorough) && pass;
492
	return pass;
493
}
494
495
bool ValidateLUC()
496
{
497
	cout << "\nLUC validation suite running...\n\n";
498
	bool pass=true;
499
500
	{
501
		FileSource f("luc1024.dat", true, new HexDecoder);
502
		LUCSSA_PKCS1v15_SHA_Signer priv(f);
503
		LUCSSA_PKCS1v15_SHA_Verifier pub(priv);
504
		pass = SignatureValidate(priv, pub) && pass;
505
	}
506
	{
507
		LUCES_OAEP_SHA_Decryptor priv(GlobalRNG(), 512);
508
		LUCES_OAEP_SHA_Encryptor pub(priv);
509
		pass = CryptoSystemValidate(priv, pub) && pass;
510
	}
511
	return pass;
512
}
513
514
bool ValidateLUC_DL()
515
{
516
	cout << "\nLUC-HMP validation suite running...\n\n";
517
518
	FileSource f("lucs512.dat", true, new HexDecoder);
519
	LUC_HMP<SHA>::Signer privS(f);
520
	LUC_HMP<SHA>::Verifier pubS(privS);
521
	bool pass = SignatureValidate(privS, pubS);
522
523
	cout << "\nLUC-IES validation suite running...\n\n";
524
525
	FileSource fc("lucc512.dat", true, new HexDecoder);
526
	LUC_IES<>::Decryptor privC(fc);
527
	LUC_IES<>::Encryptor pubC(privC);
528
	pass = CryptoSystemValidate(privC, pubC) && pass;
529
530
	return pass;
531
}
532
533
bool ValidateRabin()
534
{
535
	cout << "\nRabin validation suite running...\n\n";
536
	bool pass=true;
537
538
	{
539
		FileSource f("rabi1024.dat", true, new HexDecoder);
27 by weidai
various changes for 5.1
540
		RabinSS<PSSR, SHA>::Signer priv(f);
541
		RabinSS<PSSR, SHA>::Verifier pub(priv);
1 by weidai
Initial revision
542
		pass = SignatureValidate(priv, pub) && pass;
543
	}
544
	{
545
		RabinES<OAEP<SHA> >::Decryptor priv(GlobalRNG(), 512);
546
		RabinES<OAEP<SHA> >::Encryptor pub(priv);
547
		pass = CryptoSystemValidate(priv, pub) && pass;
548
	}
549
	return pass;
550
}
551
552
bool ValidateRW()
553
{
554
	cout << "\nRW validation suite running...\n\n";
555
556
	FileSource f("rw1024.dat", true, new HexDecoder);
27 by weidai
various changes for 5.1
557
	RWSS<PSSR, SHA>::Signer priv(f);
558
	RWSS<PSSR, SHA>::Verifier pub(priv);
1 by weidai
Initial revision
559
560
	return SignatureValidate(priv, pub);
561
}
562
563
/*
564
bool ValidateBlumGoldwasser()
565
{
566
	cout << "\nBlumGoldwasser validation suite running...\n\n";
567
568
	FileSource f("blum512.dat", true, new HexDecoder);
569
	BlumGoldwasserPrivateKey priv(f);
570
	BlumGoldwasserPublicKey pub(priv);
571
572
	return CryptoSystemValidate(priv, pub);
573
}
574
*/
575
576
bool ValidateECP()
577
{
578
	cout << "\nECP validation suite running...\n\n";
579
580
	ECIES<ECP>::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1());
581
	ECIES<ECP>::Encryptor cpub(cpriv);
582
	ByteQueue bq;
583
	cpriv.GetKey().DEREncode(bq);
584
	cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
585
	cpub.GetKey().DEREncode(bq);
586
	ECDSA<ECP, SHA>::Signer spriv(bq);
587
	ECDSA<ECP, SHA>::Verifier spub(bq);
588
	ECDH<ECP>::Domain ecdhc(ASN1::secp192r1());
589
	ECMQV<ECP>::Domain ecmqvc(ASN1::secp192r1());
590
591
	spriv.AccessKey().Precompute();
592
	ByteQueue queue;
593
	spriv.AccessKey().SavePrecomputation(queue);
594
	spriv.AccessKey().LoadPrecomputation(queue);
595
596
	bool pass = SignatureValidate(spriv, spub);
597
	cpub.AccessKey().Precompute();
598
	cpriv.AccessKey().Precompute();
599
	pass = CryptoSystemValidate(cpriv, cpub) && pass;
600
	pass = SimpleKeyAgreementValidate(ecdhc) && pass;
601
	pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
602
603
	cout << "Turning on point compression..." << endl;
604
	cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
605
	cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
606
	ecdhc.AccessGroupParameters().SetPointCompression(true);
607
	ecmqvc.AccessGroupParameters().SetPointCompression(true);
608
	pass = CryptoSystemValidate(cpriv, cpub) && pass;
609
	pass = SimpleKeyAgreementValidate(ecdhc) && pass;
610
	pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
611
612
	cout << "Testing SEC 2 recommended curves..." << endl;
613
	OID oid;
614
	while (!(oid = DL_GroupParameters_EC<ECP>::GetNextRecommendedParametersOID(oid)).m_values.empty())
615
	{
616
		DL_GroupParameters_EC<ECP> params(oid);
617
		bool fail = !params.Validate(GlobalRNG(), 2);
618
		cout << (fail ? "FAILED" : "passed") << "    " << dec << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
619
		pass = pass && !fail;
620
	}
621
622
	return pass;
623
}
624
625
bool ValidateEC2N()
626
{
627
	cout << "\nEC2N validation suite running...\n\n";
628
629
	ECIES<EC2N>::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1());
630
	ECIES<EC2N>::Encryptor cpub(cpriv);
631
	ByteQueue bq;
632
	cpriv.DEREncode(bq);
633
	cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
634
	cpub.DEREncode(bq);
635
	ECDSA<EC2N, SHA>::Signer spriv(bq);
636
	ECDSA<EC2N, SHA>::Verifier spub(bq);
637
	ECDH<EC2N>::Domain ecdhc(ASN1::sect193r1());
638
	ECMQV<EC2N>::Domain ecmqvc(ASN1::sect193r1());
639
640
	spriv.AccessKey().Precompute();
641
	ByteQueue queue;
642
	spriv.AccessKey().SavePrecomputation(queue);
643
	spriv.AccessKey().LoadPrecomputation(queue);
644
645
	bool pass = SignatureValidate(spriv, spub);
646
	pass = CryptoSystemValidate(cpriv, cpub) && pass;
647
	pass = SimpleKeyAgreementValidate(ecdhc) && pass;
648
	pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
649
650
	cout << "Turning on point compression..." << endl;
651
	cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
652
	cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
653
	ecdhc.AccessGroupParameters().SetPointCompression(true);
654
	ecmqvc.AccessGroupParameters().SetPointCompression(true);
655
	pass = CryptoSystemValidate(cpriv, cpub) && pass;
656
	pass = SimpleKeyAgreementValidate(ecdhc) && pass;
657
	pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
658
659
#if 0	// TODO: turn this back on when I make EC2N faster for pentanomial basis
660
	cout << "Testing SEC 2 recommended curves..." << endl;
661
	OID oid;
662
	while (!(oid = ECParameters<EC2N>::GetNextRecommendedParametersOID(oid)).m_values.empty())
663
	{
664
		ECParameters<EC2N> params(oid);
665
		bool fail = !params.ValidateParameters(GlobalRNG());
666
		cout << (fail ? "FAILED" : "passed") << "    " << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
667
		pass = pass && !fail;
668
	}
669
#endif
670
671
	return pass;
672
}
673
674
bool ValidateECDSA()
675
{
676
	cout << "\nECDSA validation suite running...\n\n";
677
678
	// from Sample Test Vectors for P1363
679
	GF2NT gf2n(191, 9, 0);
680
	byte a[]="\x28\x66\x53\x7B\x67\x67\x52\x63\x6A\x68\xF5\x65\x54\xE1\x26\x40\x27\x6B\x64\x9E\xF7\x52\x62\x67";
681
	byte b[]="\x2E\x45\xEF\x57\x1F\x00\x78\x6F\x67\xB0\x08\x1B\x94\x95\xA3\xD9\x54\x62\xF5\xDE\x0A\xA1\x85\xEC";
682
	EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24));
683
684
	EC2N::Point P;
685
	ec.DecodePoint(P, (byte *)"\x04\x36\xB3\xDA\xF8\xA2\x32\x06\xF9\xC4\xF2\x99\xD7\xB2\x1A\x9C\x36\x91\x37\xF2\xC8\x4A\xE1\xAA\x0D"
686
		"\x76\x5B\xE7\x34\x33\xB3\xF9\x5E\x33\x29\x32\xE7\x0E\xA2\x45\xCA\x24\x18\xEA\x0E\xF9\x80\x18\xFB", ec.EncodedPointSize());
687
	Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H");
688
	Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH");
689
	EC2N::Point Q(ec.Multiply(d, P));
690
	ECDSA<EC2N, SHA>::Signer priv(ec, P, n, d);
691
	ECDSA<EC2N, SHA>::Verifier pub(priv);
692
693
	Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH");
694
	Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H");
695
	byte sig[]="\x03\x8e\x5a\x11\xfb\x55\xe4\xc6\x54\x71\xdc\xd4\x99\x84\x52\xb1\xe0\x2d\x8a\xf7\x09\x9b\xb9\x30"
696
		"\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e";
697
	Integer r(sig, 24);
698
	Integer s(sig+24, 24);
699
700
	Integer rOut, sOut;
701
	bool fail, pass=true;
702
27 by weidai
various changes for 5.1
703
	priv.RawSign(k, h, rOut, sOut);
1 by weidai
Initial revision
704
	fail = (rOut != r) || (sOut != s);
705
	pass = pass && !fail;
706
707
	cout << (fail ? "FAILED    " : "passed    ");
708
	cout << "signature check against test vector\n";
709
27 by weidai
various changes for 5.1
710
	fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig));
1 by weidai
Initial revision
711
	pass = pass && !fail;
712
713
	cout << (fail ? "FAILED    " : "passed    ");
714
	cout << "verification check against test vector\n";
715
27 by weidai
various changes for 5.1
716
	fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig));
1 by weidai
Initial revision
717
	pass = pass && !fail;
718
719
	pass = SignatureValidate(priv, pub) && pass;
720
721
	return pass;
722
}
723
724
bool ValidateESIGN()
725
{
726
	cout << "\nESIGN validation suite running...\n\n";
727
728
	bool pass = true, fail;
729
730
	const char *plain = "test";
731
	const byte *signature = (byte *)
732
		"\xA3\xE3\x20\x65\xDE\xDA\xE7\xEC\x05\xC1\xBF\xCD\x25\x79\x7D\x99\xCD\xD5\x73\x9D\x9D\xF3\xA4\xAA\x9A\xA4\x5A\xC8\x23\x3D\x0D\x37\xFE\xBC\x76\x3F\xF1\x84\xF6\x59"
733
		"\x14\x91\x4F\x0C\x34\x1B\xAE\x9A\x5C\x2E\x2E\x38\x08\x78\x77\xCB\xDC\x3C\x7E\xA0\x34\x44\x5B\x0F\x67\xD9\x35\x2A\x79\x47\x1A\x52\x37\x71\xDB\x12\x67\xC1\xB6\xC6"
734
		"\x66\x73\xB3\x40\x2E\xD6\xF2\x1A\x84\x0A\xB6\x7B\x0F\xEB\x8B\x88\xAB\x33\xDD\xE4\x83\x21\x90\x63\x2D\x51\x2A\xB1\x6F\xAB\xA7\x5C\xFD\x77\x99\xF2\xE1\xEF\x67\x1A"
735
		"\x74\x02\x37\x0E\xED\x0A\x06\xAD\xF4\x15\x65\xB8\xE1\xD1\x45\xAE\x39\x19\xB4\xFF\x5D\xF1\x45\x7B\xE0\xFE\x72\xED\x11\x92\x8F\x61\x41\x4F\x02\x00\xF2\x76\x6F\x7C"
736
		"\x79\xA2\xE5\x52\x20\x5D\x97\x5E\xFE\x39\xAE\x21\x10\xFB\x35\xF4\x80\x81\x41\x13\xDD\xE8\x5F\xCA\x1E\x4F\xF8\x9B\xB2\x68\xFB\x28";
737
738
	FileSource keys("esig1536.dat", true, new HexDecoder);
739
	ESIGN<SHA>::Signer signer(keys);
740
	ESIGN<SHA>::Verifier verifier(signer);
741
742
	fail = !SignatureValidate(signer, verifier);
743
	pass = pass && !fail;
744
27 by weidai
various changes for 5.1
745
	fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength());
1 by weidai
Initial revision
746
	pass = pass && !fail;
747
748
	cout << (fail ? "FAILED    " : "passed    ");
749
	cout << "verification check against test vector\n";
750
751
	cout << "Generating signature key from seed..." << endl;
752
	InvertibleESIGNFunction priv;
753
	priv.GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512));
754
755
	fail = !SignatureValidate(signer, verifier);
756
	pass = pass && !fail;
757
758
	return pass;
759
}