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