Crypto++  5.6.3
Free C++ class library of cryptographic schemes
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 
7 #include "cryptlib.h"
8 #include "pubkey.h"
9 #include "gfpcrypt.h"
10 #include "eccrypto.h"
11 #include "blumshub.h"
12 #include "filters.h"
13 #include "files.h"
14 #include "rsa.h"
15 #include "md2.h"
16 #include "elgamal.h"
17 #include "nr.h"
18 #include "dsa.h"
19 #include "dh.h"
20 #include "mqv.h"
21 #include "luc.h"
22 #include "xtrcrypt.h"
23 #include "rabin.h"
24 #include "rw.h"
25 #include "eccrypto.h"
26 #include "integer.h"
27 #include "gf2n.h"
28 #include "ecp.h"
29 #include "ec2n.h"
30 #include "asn.h"
31 #include "rng.h"
32 #include "hex.h"
33 #include "oids.h"
34 #include "esign.h"
35 #include "osrng.h"
36 #include "smartptr.h"
37 
38 #include <iostream>
39 #include <sstream>
40 #include <iomanip>
41 
42 #include "validate.h"
43 
44 // Aggressive stack checking with VS2005 SP1 and above.
45 #if (CRYPTOPP_MSC_VERSION >= 1410)
46 # pragma strict_gs_check (on)
47 #endif
48 
49 USING_NAMESPACE(CryptoPP)
50 USING_NAMESPACE(std)
51 
53 {
54 public:
55  FixedRNG(BufferedTransformation &source) : m_source(source) {}
56 
57  void GenerateBlock(byte *output, size_t size)
58  {
59  m_source.Get(output, size);
60  }
61 
62 private:
63  BufferedTransformation &m_source;
64 };
65 
66 bool ValidateBBS()
67 {
68  cout << "\nBlumBlumShub validation suite running...\n\n";
69 
70  Integer p("212004934506826557583707108431463840565872545889679278744389317666981496005411448865750399674653351");
71  Integer q("100677295735404212434355574418077394581488455772477016953458064183204108039226017738610663984508231");
72  Integer seed("63239752671357255800299643604761065219897634268887145610573595874544114193025997412441121667211431");
73  BlumBlumShub bbs(p, q, seed);
74  bool pass = true, fail;
75  int j;
76 
77  static const byte output1[] = {
78  0x49,0xEA,0x2C,0xFD,0xB0,0x10,0x64,0xA0,0xBB,0xB9,
79  0x2A,0xF1,0x01,0xDA,0xC1,0x8A,0x94,0xF7,0xB7,0xCE};
80  static const byte output2[] = {
81  0x74,0x45,0x48,0xAE,0xAC,0xB7,0x0E,0xDF,0xAF,0xD7,
82  0xD5,0x0E,0x8E,0x29,0x83,0x75,0x6B,0x27,0x46,0xA1};
83 
84  // Coverity finding, also see http://stackoverflow.com/a/34509163/608639.
85  StreamState ss(cout);
86  byte buf[20];
87 
88  bbs.GenerateBlock(buf, 20);
89  fail = memcmp(output1, buf, 20) != 0;
90  pass = pass && !fail;
91 
92  cout << (fail ? "FAILED " : "passed ");
93  for (j=0;j<20;j++)
94  cout << setw(2) << setfill('0') << hex << (int)buf[j];
95  cout << endl;
96 
97  bbs.Seek(10);
98  bbs.GenerateBlock(buf, 10);
99  fail = memcmp(output1+10, buf, 10) != 0;
100  pass = pass && !fail;
101 
102  cout << (fail ? "FAILED " : "passed ");
103  for (j=0;j<10;j++)
104  cout << setw(2) << setfill('0') << hex << (int)buf[j];
105  cout << endl;
106 
107  bbs.Seek(1234567);
108  bbs.GenerateBlock(buf, 20);
109  fail = memcmp(output2, buf, 20) != 0;
110  pass = pass && !fail;
111 
112  cout << (fail ? "FAILED " : "passed ");
113  for (j=0;j<20;j++)
114  cout << setw(2) << setfill('0') << hex << (int)buf[j];
115  cout << endl;
116 
117  return pass;
118 }
119 
120 bool SignatureValidate(PK_Signer &priv, PK_Verifier &pub, bool thorough = false)
121 {
122  bool pass = true, fail;
123 
124  fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2);
125  pass = pass && !fail;
126 
127  cout << (fail ? "FAILED " : "passed ");
128  cout << "signature key validation\n";
129 
130  const byte *message = (byte *)"test message";
131  const int messageLen = 12;
132 
133  SecByteBlock signature(priv.MaxSignatureLength());
134  size_t signatureLength = priv.SignMessage(GlobalRNG(), message, messageLen, signature);
135  fail = !pub.VerifyMessage(message, messageLen, signature, signatureLength);
136  pass = pass && !fail;
137 
138  cout << (fail ? "FAILED " : "passed ");
139  cout << "signature and verification\n";
140 
141  ++signature[0];
142  fail = pub.VerifyMessage(message, messageLen, signature, signatureLength);
143  pass = pass && !fail;
144 
145  cout << (fail ? "FAILED " : "passed ");
146  cout << "checking invalid signature" << endl;
147 
148  if (priv.MaxRecoverableLength() > 0)
149  {
150  signatureLength = priv.SignMessageWithRecovery(GlobalRNG(), message, messageLen, NULL, 0, signature);
151  SecByteBlock recovered(priv.MaxRecoverableLengthFromSignatureLength(signatureLength));
152  DecodingResult result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength);
153  fail = !(result.isValidCoding && result.messageLength == messageLen && memcmp(recovered, message, messageLen) == 0);
154  pass = pass && !fail;
155 
156  cout << (fail ? "FAILED " : "passed ");
157  cout << "signature and verification with recovery" << endl;
158 
159  ++signature[0];
160  result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength);
161  fail = result.isValidCoding;
162  pass = pass && !fail;
163 
164  cout << (fail ? "FAILED " : "passed ");
165  cout << "recovery with invalid signature" << endl;
166  }
167 
168  return pass;
169 }
170 
171 bool CryptoSystemValidate(PK_Decryptor &priv, PK_Encryptor &pub, bool thorough = false)
172 {
173  bool pass = true, fail;
174 
175  fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2);
176  pass = pass && !fail;
177 
178  cout << (fail ? "FAILED " : "passed ");
179  cout << "cryptosystem key validation\n";
180 
181  const byte *message = (byte *)"test message";
182  const int messageLen = 12;
183  SecByteBlock ciphertext(priv.CiphertextLength(messageLen));
184  SecByteBlock plaintext(priv.MaxPlaintextLength(ciphertext.size()));
185 
186  pub.Encrypt(GlobalRNG(), message, messageLen, ciphertext);
187  fail = priv.Decrypt(GlobalRNG(), ciphertext, priv.CiphertextLength(messageLen), plaintext) != DecodingResult(messageLen);
188  fail = fail || memcmp(message, plaintext, messageLen);
189  pass = pass && !fail;
190 
191  cout << (fail ? "FAILED " : "passed ");
192  cout << "encryption and decryption\n";
193 
194  return pass;
195 }
196 
197 bool SimpleKeyAgreementValidate(SimpleKeyAgreementDomain &d)
198 {
199  if (d.GetCryptoParameters().Validate(GlobalRNG(), 3))
200  cout << "passed simple key agreement domain parameters validation" << endl;
201  else
202  {
203  cout << "FAILED simple key agreement domain parameters invalid" << endl;
204  return false;
205  }
206 
207  SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength());
208  SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength());
209  SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength());
210 
211  d.GenerateKeyPair(GlobalRNG(), priv1, pub1);
212  d.GenerateKeyPair(GlobalRNG(), priv2, pub2);
213 
214  memset(val1.begin(), 0x10, val1.size());
215  memset(val2.begin(), 0x11, val2.size());
216 
217  if (!(d.Agree(val1, priv1, pub2) && d.Agree(val2, priv2, pub1)))
218  {
219  cout << "FAILED simple key agreement failed" << endl;
220  return false;
221  }
222 
223  if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength()))
224  {
225  cout << "FAILED simple agreed values not equal" << endl;
226  return false;
227  }
228 
229  cout << "passed simple key agreement" << endl;
230  return true;
231 }
232 
233 bool AuthenticatedKeyAgreementValidate(AuthenticatedKeyAgreementDomain &d)
234 {
235  if (d.GetCryptoParameters().Validate(GlobalRNG(), 3))
236  cout << "passed authenticated key agreement domain parameters validation" << endl;
237  else
238  {
239  cout << "FAILED authenticated key agreement domain parameters invalid" << endl;
240  return false;
241  }
242 
247  SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength());
248 
249  d.GenerateStaticKeyPair(GlobalRNG(), spriv1, spub1);
250  d.GenerateStaticKeyPair(GlobalRNG(), spriv2, spub2);
251  d.GenerateEphemeralKeyPair(GlobalRNG(), epriv1, epub1);
252  d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2);
253 
254  memset(val1.begin(), 0x10, val1.size());
255  memset(val2.begin(), 0x11, val2.size());
256 
257  if (!(d.Agree(val1, spriv1, epriv1, spub2, epub2) && d.Agree(val2, spriv2, epriv2, spub1, epub1)))
258  {
259  cout << "FAILED authenticated key agreement failed" << endl;
260  return false;
261  }
262 
263  if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength()))
264  {
265  cout << "FAILED authenticated agreed values not equal" << endl;
266  return false;
267  }
268 
269  cout << "passed authenticated key agreement" << endl;
270  return true;
271 }
272 
273 bool ValidateRSA()
274 {
275  cout << "\nRSA validation suite running...\n\n";
276 
277  byte out[100], outPlain[100];
278  bool pass = true, fail;
279 
280  {
281  const char *plain = "Everyone gets Friday off.";
282  static const byte signature[] =
283  "\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84"
284  "\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21"
285  "\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b"
286  "\x5c\x77\xdf\xd9\xb1\x5b\xfc\x3d\x55\x93\x53\x50\x34\x10\xc1\xe1";
287 
288  FileSource keys(CRYPTOPP_DATA_DIR "TestData/rsa512a.dat", true, new HexDecoder);
289  Weak::RSASSA_PKCS1v15_MD2_Signer rsaPriv(keys);
290  Weak::RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv);
291 
292  size_t signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out);
293  fail = memcmp(signature, out, 64) != 0;
294  pass = pass && !fail;
295 
296  cout << (fail ? "FAILED " : "passed ");
297  cout << "signature check against test vector\n";
298 
299  fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
300  pass = pass && !fail;
301 
302  cout << (fail ? "FAILED " : "passed ");
303  cout << "verification check against test vector\n";
304 
305  out[10]++;
306  fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
307  pass = pass && !fail;
308 
309  cout << (fail ? "FAILED " : "passed ");
310  cout << "invalid signature verification\n";
311  }
312  {
313  FileSource keys(CRYPTOPP_DATA_DIR "TestData/rsa1024.dat", true, new HexDecoder);
314  RSAES_PKCS1v15_Decryptor rsaPriv(keys);
315  RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv);
316 
317  pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass;
318  }
319  {
320  RSAES<OAEP<SHA> >::Decryptor rsaPriv(GlobalRNG(), 512);
321  RSAES<OAEP<SHA> >::Encryptor rsaPub(rsaPriv);
322 
323  pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass;
324  }
325  {
326  byte *plain = (byte *)
327  "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
328  static const byte encrypted[] =
329  "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
330  "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
331  "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
332  "\x62\x51";
333  static const byte oaepSeed[] =
334  "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2"
335  "\xf0\x6c\xb5\x8f";
336  ByteQueue bq;
337  bq.Put(oaepSeed, 20);
338  FixedRNG rng(bq);
339 
340  FileSource privFile(CRYPTOPP_DATA_DIR "TestData/rsa400pv.dat", true, new HexDecoder);
341  FileSource pubFile(CRYPTOPP_DATA_DIR "TestData/rsa400pb.dat", true, new HexDecoder);
342  RSAES_OAEP_SHA_Decryptor rsaPriv;
343  rsaPriv.AccessKey().BERDecodePrivateKey(privFile, false, 0);
344  RSAES_OAEP_SHA_Encryptor rsaPub(pubFile);
345 
346  memset(out, 0, 50);
347  memset(outPlain, 0, 8);
348  rsaPub.Encrypt(rng, plain, 8, out);
349  DecodingResult result = rsaPriv.FixedLengthDecrypt(GlobalRNG(), encrypted, outPlain);
350  fail = !result.isValidCoding || (result.messageLength!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8);
351  pass = pass && !fail;
352 
353  cout << (fail ? "FAILED " : "passed ");
354  cout << "PKCS 2.0 encryption and decryption\n";
355  }
356 
357  return pass;
358 }
359 
360 bool ValidateDH()
361 {
362  cout << "\nDH validation suite running...\n\n";
363 
364  FileSource f(CRYPTOPP_DATA_DIR "TestData/dh1024.dat", true, new HexDecoder());
365  DH dh(f);
366  return SimpleKeyAgreementValidate(dh);
367 }
368 
369 bool ValidateMQV()
370 {
371  cout << "\nMQV validation suite running...\n\n";
372 
373  FileSource f(CRYPTOPP_DATA_DIR "TestData/mqv1024.dat", true, new HexDecoder());
374  MQV mqv(f);
375  return AuthenticatedKeyAgreementValidate(mqv);
376 }
377 
378 bool ValidateLUC_DH()
379 {
380  cout << "\nLUC-DH validation suite running...\n\n";
381 
382  FileSource f(CRYPTOPP_DATA_DIR "TestData/lucd512.dat", true, new HexDecoder());
383  LUC_DH dh(f);
384  return SimpleKeyAgreementValidate(dh);
385 }
386 
387 bool ValidateXTR_DH()
388 {
389  cout << "\nXTR-DH validation suite running...\n\n";
390 
391  FileSource f(CRYPTOPP_DATA_DIR "TestData/xtrdh171.dat", true, new HexDecoder());
392  XTR_DH dh(f);
393  return SimpleKeyAgreementValidate(dh);
394 }
395 
396 bool ValidateElGamal()
397 {
398  cout << "\nElGamal validation suite running...\n\n";
399  bool pass = true;
400  {
401  FileSource fc(CRYPTOPP_DATA_DIR "TestData/elgc1024.dat", true, new HexDecoder);
402  ElGamalDecryptor privC(fc);
403  ElGamalEncryptor pubC(privC);
404  privC.AccessKey().Precompute();
405  ByteQueue queue;
406  privC.AccessKey().SavePrecomputation(queue);
407  privC.AccessKey().LoadPrecomputation(queue);
408 
409  pass = CryptoSystemValidate(privC, pubC) && pass;
410  }
411  return pass;
412 }
413 
414 bool ValidateDLIES()
415 {
416  cout << "\nDLIES validation suite running...\n\n";
417  bool pass = true;
418  {
419  FileSource fc(CRYPTOPP_DATA_DIR "TestData/dlie1024.dat", true, new HexDecoder);
420  DLIES<>::Decryptor privC(fc);
421  DLIES<>::Encryptor pubC(privC);
422  pass = CryptoSystemValidate(privC, pubC) && pass;
423  }
424  {
425  cout << "Generating new encryption key..." << endl;
427  gp.GenerateRandomWithKeySize(GlobalRNG(), 128);
428  DLIES<>::Decryptor decryptor;
429  decryptor.AccessKey().GenerateRandom(GlobalRNG(), gp);
430  DLIES<>::Encryptor encryptor(decryptor);
431 
432  pass = CryptoSystemValidate(decryptor, encryptor) && pass;
433  }
434  return pass;
435 }
436 
437 bool ValidateNR()
438 {
439  cout << "\nNR validation suite running...\n\n";
440  bool pass = true;
441  {
442  FileSource f(CRYPTOPP_DATA_DIR "TestData/nr2048.dat", true, new HexDecoder);
443  NR<SHA>::Signer privS(f);
444  privS.AccessKey().Precompute();
445  NR<SHA>::Verifier pubS(privS);
446 
447  pass = SignatureValidate(privS, pubS) && pass;
448  }
449  {
450  cout << "Generating new signature key..." << endl;
451  NR<SHA>::Signer privS(GlobalRNG(), 256);
452  NR<SHA>::Verifier pubS(privS);
453 
454  pass = SignatureValidate(privS, pubS) && pass;
455  }
456  return pass;
457 }
458 
459 bool ValidateDSA(bool thorough)
460 {
461  cout << "\nDSA validation suite running...\n\n";
462 
463  bool pass = true;
464  FileSource fs1(CRYPTOPP_DATA_DIR "TestData/dsa1024.dat", true, new HexDecoder());
465  DSA::Signer priv(fs1);
466  DSA::Verifier pub(priv);
467  FileSource fs2(CRYPTOPP_DATA_DIR "TestData/dsa1024b.dat", true, new HexDecoder());
468  DSA::Verifier pub1(fs2);
469  assert(pub.GetKey() == pub1.GetKey());
470  pass = SignatureValidate(priv, pub, thorough) && pass;
471  pass = RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/dsa.txt", g_nullNameValuePairs, thorough) && pass;
472 
473  return pass;
474 }
475 
476 bool ValidateLUC()
477 {
478  cout << "\nLUC validation suite running...\n\n";
479  bool pass=true;
480 
481  {
482  FileSource f(CRYPTOPP_DATA_DIR "TestData/luc1024.dat", true, new HexDecoder);
485  pass = SignatureValidate(priv, pub) && pass;
486  }
487  {
488  LUCES_OAEP_SHA_Decryptor priv(GlobalRNG(), 512);
489  LUCES_OAEP_SHA_Encryptor pub(priv);
490  pass = CryptoSystemValidate(priv, pub) && pass;
491  }
492  return pass;
493 }
494 
495 bool ValidateLUC_DL()
496 {
497  cout << "\nLUC-HMP validation suite running...\n\n";
498 
499  FileSource f(CRYPTOPP_DATA_DIR "TestData/lucs512.dat", true, new HexDecoder);
500  LUC_HMP<SHA>::Signer privS(f);
501  LUC_HMP<SHA>::Verifier pubS(privS);
502  bool pass = SignatureValidate(privS, pubS);
503 
504  cout << "\nLUC-IES validation suite running...\n\n";
505 
506  FileSource fc(CRYPTOPP_DATA_DIR "TestData/lucc512.dat", true, new HexDecoder);
507  LUC_IES<>::Decryptor privC(fc);
508  LUC_IES<>::Encryptor pubC(privC);
509  pass = CryptoSystemValidate(privC, pubC) && pass;
510 
511  return pass;
512 }
513 
514 bool ValidateRabin()
515 {
516  cout << "\nRabin validation suite running...\n\n";
517  bool pass=true;
518 
519  {
520  FileSource f(CRYPTOPP_DATA_DIR "TestData/rabi1024.dat", true, new HexDecoder);
523  pass = SignatureValidate(priv, pub) && pass;
524  }
525  {
526  RabinES<OAEP<SHA> >::Decryptor priv(GlobalRNG(), 512);
527  RabinES<OAEP<SHA> >::Encryptor pub(priv);
528  pass = CryptoSystemValidate(priv, pub) && pass;
529  }
530  return pass;
531 }
532 
533 bool ValidateRW()
534 {
535  cout << "\nRW validation suite running...\n\n";
536 
537  FileSource f(CRYPTOPP_DATA_DIR "TestData/rw1024.dat", true, new HexDecoder);
538  RWSS<PSSR, SHA>::Signer priv(f);
539  RWSS<PSSR, SHA>::Verifier pub(priv);
540 
541  return SignatureValidate(priv, pub);
542 }
543 
544 /*
545 bool ValidateBlumGoldwasser()
546 {
547  cout << "\nBlumGoldwasser validation suite running...\n\n";
548 
549  FileSource f(CRYPTOPP_DATA_DIR "TestData/blum512.dat", true, new HexDecoder);
550  BlumGoldwasserPrivateKey priv(f);
551  BlumGoldwasserPublicKey pub(priv);
552 
553  return CryptoSystemValidate(priv, pub);
554 }
555 */
556 
557 #if !defined(NDEBUG) && !defined(CRYPTOPP_IMPORTS)
558 // Issue 64: "PolynomialMod2::operator<<=", http://github.com/weidai11/cryptopp/issues/64
559 bool TestPolynomialMod2()
560 {
561  bool pass1 = true, pass2 = true, pass3 = true;
562 
563  cout << "\nTesting PolynomialMod2 bit operations...\n\n";
564 
565  static const unsigned int start = 0;
566  static const unsigned int stop = 4 * WORD_BITS + 1;
567 
568  for (unsigned int i=start; i < stop; i++)
569  {
570  PolynomialMod2 p(1);
571  p <<= i;
572 
573  Integer n(Integer::One());
574  n <<= i;
575 
576  std::ostringstream oss1;
577  oss1 << p;
578 
579  std::string str1, str2;
580 
581  // str1 needs the commas removed used for grouping
582  str1 = oss1.str();
583  str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
584 
585  // str1 needs the trailing 'b' removed
586  str1.erase(str1.end() - 1);
587 
588  // str2 is fine as-is
589  str2 = IntToString(n, 2);
590 
591  pass1 &= (str1 == str2);
592  }
593 
594  for (unsigned int i=start; i < stop; i++)
595  {
596  const word w((word)SIZE_MAX);
597 
598  PolynomialMod2 p(w);
599  p <<= i;
600 
601  Integer n(Integer::POSITIVE, static_cast<lword>(w));
602  n <<= i;
603 
604  std::ostringstream oss1;
605  oss1 << p;
606 
607  std::string str1, str2;
608 
609  // str1 needs the commas removed used for grouping
610  str1 = oss1.str();
611  str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
612 
613  // str1 needs the trailing 'b' removed
614  str1.erase(str1.end() - 1);
615 
616  // str2 is fine as-is
617  str2 = IntToString(n, 2);
618 
619  pass2 &= (str1 == str2);
620  }
621 
622  RandomNumberGenerator& prng = GlobalRNG();
623  for (unsigned int i=start; i < stop; i++)
624  {
625  word w; // Cast to lword due to Visual Studio
626  prng.GenerateBlock((byte*)&w, sizeof(w));
627 
628  PolynomialMod2 p(w);
629  p <<= i;
630 
631  Integer n(Integer::POSITIVE, static_cast<lword>(w));
632  n <<= i;
633 
634  std::ostringstream oss1;
635  oss1 << p;
636 
637  std::string str1, str2;
638 
639  // str1 needs the commas removed used for grouping
640  str1 = oss1.str();
641  str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
642 
643  // str1 needs the trailing 'b' removed
644  str1.erase(str1.end() - 1);
645 
646  // str2 is fine as-is
647  str2 = IntToString(n, 2);
648 
649  if (str1 != str2)
650  {
651  cout << " Oops..." << "\n";
652  cout << " random: " << std::hex << n << std::dec << "\n";
653  cout << " str1: " << str1 << "\n";
654  cout << " str2: " << str2 << "\n";
655  }
656 
657  pass3 &= (str1 == str2);
658  }
659 
660  cout << (!pass1 ? "FAILED" : "passed") << " " << "1 shifted over range [" << dec << start << "," << stop << "]" << "\n";
661  cout << (!pass2 ? "FAILED" : "passed") << " " << "0x" << hex << word(SIZE_MAX) << dec << " shifted over range [" << start << "," << stop << "]" << "\n";
662  cout << (!pass3 ? "FAILED" : "passed") << " " << "random values shifted over range [" << dec << start << "," << stop << "]" << "\n";
663 
664  if (!(pass1 && pass2 && pass3))
665  cout.flush();
666 
667  return pass1 && pass2 && pass3;
668 }
669 #endif
670 
671 bool ValidateECP()
672 {
673  cout << "\nECP validation suite running...\n\n";
674 
675  ECIES<ECP>::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1());
676  ECIES<ECP>::Encryptor cpub(cpriv);
677  ByteQueue bq;
678  cpriv.GetKey().DEREncode(bq);
679  cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
680  cpub.GetKey().DEREncode(bq);
681  ECDSA<ECP, SHA>::Signer spriv(bq);
682  ECDSA<ECP, SHA>::Verifier spub(bq);
683  ECDH<ECP>::Domain ecdhc(ASN1::secp192r1());
684  ECMQV<ECP>::Domain ecmqvc(ASN1::secp192r1());
685 
686  spriv.AccessKey().Precompute();
687  ByteQueue queue;
688  spriv.AccessKey().SavePrecomputation(queue);
689  spriv.AccessKey().LoadPrecomputation(queue);
690 
691  bool pass = SignatureValidate(spriv, spub);
692  cpub.AccessKey().Precompute();
693  cpriv.AccessKey().Precompute();
694  pass = CryptoSystemValidate(cpriv, cpub) && pass;
695  pass = SimpleKeyAgreementValidate(ecdhc) && pass;
696  pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
697 
698  cout << "Turning on point compression..." << endl;
699  cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
700  cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
701  ecdhc.AccessGroupParameters().SetPointCompression(true);
702  ecmqvc.AccessGroupParameters().SetPointCompression(true);
703  pass = CryptoSystemValidate(cpriv, cpub) && pass;
704  pass = SimpleKeyAgreementValidate(ecdhc) && pass;
705  pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
706 
707  cout << "Testing SEC 2, NIST, and Brainpool recommended curves..." << endl;
708  OID oid;
709  while (!(oid = DL_GroupParameters_EC<ECP>::GetNextRecommendedParametersOID(oid)).m_values.empty())
710  {
711  DL_GroupParameters_EC<ECP> params(oid);
712  bool fail = !params.Validate(GlobalRNG(), 2);
713  cout << (fail ? "FAILED" : "passed") << " " << dec << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
714  pass = pass && !fail;
715  }
716 
717  return pass;
718 }
719 
720 bool ValidateEC2N()
721 {
722  cout << "\nEC2N validation suite running...\n\n";
723 
724  ECIES<EC2N>::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1());
725  ECIES<EC2N>::Encryptor cpub(cpriv);
726  ByteQueue bq;
727  cpriv.DEREncode(bq);
728  cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
729  cpub.DEREncode(bq);
730  ECDSA<EC2N, SHA>::Signer spriv(bq);
732  ECDH<EC2N>::Domain ecdhc(ASN1::sect193r1());
733  ECMQV<EC2N>::Domain ecmqvc(ASN1::sect193r1());
734 
735  spriv.AccessKey().Precompute();
736  ByteQueue queue;
737  spriv.AccessKey().SavePrecomputation(queue);
738  spriv.AccessKey().LoadPrecomputation(queue);
739 
740  bool pass = SignatureValidate(spriv, spub);
741  pass = CryptoSystemValidate(cpriv, cpub) && pass;
742  pass = SimpleKeyAgreementValidate(ecdhc) && pass;
743  pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
744 
745  cout << "Turning on point compression..." << endl;
746  cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
747  cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
748  ecdhc.AccessGroupParameters().SetPointCompression(true);
749  ecmqvc.AccessGroupParameters().SetPointCompression(true);
750  pass = CryptoSystemValidate(cpriv, cpub) && pass;
751  pass = SimpleKeyAgreementValidate(ecdhc) && pass;
752  pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
753 
754 #if 0 // TODO: turn this back on when I make EC2N faster for pentanomial basis
755  cout << "Testing SEC 2 recommended curves..." << endl;
756  OID oid;
757  while (!(oid = DL_GroupParameters_EC<EC2N>::GetNextRecommendedParametersOID(oid)).m_values.empty())
758  {
759  DL_GroupParameters_EC<EC2N> params(oid);
760  bool fail = !params.Validate(GlobalRNG(), 2);
761  cout << (fail ? "FAILED" : "passed") << " " << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
762  pass = pass && !fail;
763  }
764 #endif
765 
766  return pass;
767 }
768 
769 bool ValidateECDSA()
770 {
771  cout << "\nECDSA validation suite running...\n\n";
772 
773  // from Sample Test Vectors for P1363
774  GF2NT gf2n(191, 9, 0);
775  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";
776  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";
777  EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24));
778 
779  EC2N::Point P;
780  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"
781  "\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());
782  Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H");
783  Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH");
784  EC2N::Point Q(ec.Multiply(d, P));
785  ECDSA<EC2N, SHA>::Signer priv(ec, P, n, d);
786  ECDSA<EC2N, SHA>::Verifier pub(priv);
787 
788  Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH");
789  Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H");
790  static const 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"
791  "\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e";
792  Integer r(sig, 24);
793  Integer s(sig+24, 24);
794 
795  Integer rOut, sOut;
796  bool fail, pass=true;
797 
798  priv.RawSign(k, h, rOut, sOut);
799  fail = (rOut != r) || (sOut != s);
800  pass = pass && !fail;
801 
802  cout << (fail ? "FAILED " : "passed ");
803  cout << "signature check against test vector\n";
804 
805  fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig));
806  pass = pass && !fail;
807 
808  cout << (fail ? "FAILED " : "passed ");
809  cout << "verification check against test vector\n";
810 
811  fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig));
812  pass = pass && !fail;
813 
814  pass = SignatureValidate(priv, pub) && pass;
815 
816  return pass;
817 }
818 
819 bool ValidateESIGN()
820 {
821  cout << "\nESIGN validation suite running...\n\n";
822 
823  bool pass = true, fail;
824 
825  static const char plain[] = "test";
826  static const byte signature[] =
827  "\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"
828  "\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"
829  "\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"
830  "\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"
831  "\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";
832 
833  FileSource keys(CRYPTOPP_DATA_DIR "TestData/esig1536.dat", true, new HexDecoder);
834  ESIGN<SHA>::Signer signer(keys);
835  ESIGN<SHA>::Verifier verifier(signer);
836 
837  fail = !SignatureValidate(signer, verifier);
838  pass = pass && !fail;
839 
840  fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength());
841  pass = pass && !fail;
842 
843  cout << (fail ? "FAILED " : "passed ");
844  cout << "verification check against test vector\n";
845 
846  cout << "Generating signature key from seed..." << endl;
847  signer.AccessKey().GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512));
848  verifier = signer;
849 
850  fail = !SignatureValidate(signer, verifier);
851  pass = pass && !fail;
852 
853  return pass;
854 }
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:29
virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
Generate private/public key pair.
Definition: cryptlib.cpp:933
Classes for Rabin encryption and signature schemes.
virtual unsigned int StaticPublicKeyLength() const =0
Provides the size of the static public key.
virtual size_t SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const
Sign a recoverable message.
Definition: cryptlib.cpp:882
virtual bool VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLen) const
Check whether input signature is a valid signature for input message.
Definition: cryptlib.cpp:897
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: validat2.cpp:57
Classes and functions for ElGamal key agreement and encryption schemes.
virtual DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters=g_nullNameValuePairs) const =0
Decrypt a byte string.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:329
This file contains helper classes/functions for implementing public key algorithms.
GF(2^n) with Trinomial Basis.
Definition: gf2n.h:318
virtual unsigned int AgreedValueLength() const =0
Provides the size of the agreed value.
file-based implementation of Source interface
Definition: files.h:55
Classes for Elliptic Curves over prime fields.
Interface for public-key signers.
Definition: cryptlib.h:2524
Interface for public-key encryptors.
Definition: cryptlib.h:2332
Decode base 16 data back to bytes.
Definition: hex.h:28
Abstract base classes that provide a uniform interface to this library.
virtual bool Agree(byte *agreedValue, const byte *staticPrivateKey, const byte *ephemeralPrivateKey, const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, bool validateStaticOtherPublicKey=true) const =0
Derive agreed value.
GF(p) group parameters that default to same primes.
Definition: gfpcrypt.h:170
Object identifiers for algorthms and schemes.
Classes for automatic resource management.
STL namespace.
Interface for random number generators.
Definition: cryptlib.h:1176
size_t messageLength
Recovered message length if isValidCoding is true, undefined otherwise.
Definition: cryptlib.h:259
SecBlock typedef.
Definition: secblock.h:723
Interface for buffered transformations.
Definition: cryptlib.h:1342
const CryptoMaterial & GetMaterial() const
Retrieves a reference to a Private Key.
Definition: cryptlib.h:2249
static const Integer & One()
Integer representing 1.
Definition: integer.cpp:2944
This file contains classes that implement the ESIGN signature schemes as defined in IEEE P1363a...
Polynomial with Coefficients in GF(2)
Definition: gf2n.h:18
virtual unsigned int EphemeralPublicKeyLength() const =0
Provides the size of ephemeral public key.
Classes for Elliptic Curves over binary fields.
Rabin encryption.
Definition: rabin.h:94
virtual size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const =0
Provides the length of longest message that can be recovered from a signature of given length...
Interface for domains of simple key agreement protocols.
Definition: cryptlib.h:2665
Returns a decoding results.
Definition: cryptlib.h:236
Classes for Rabin-Williams signature schemes.
Interface for public-key decryptors.
Definition: cryptlib.h:2368
MQV domain for performing authenticated key agreement.
Definition: mqv.h:26
XTR-DH with key validation.
Definition: xtrcrypt.h:16
virtual size_t MaxRecoverableLength() const =0
Provides the length of longest message that can be recovered.
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1363
virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
Generate a private/public key pair.
Definition: cryptlib.cpp:921
virtual unsigned int AgreedValueLength() const =0
Provides the size of the agreed value.
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:554
Classes for Diffie-Hellman key exchange.
Classes for HexEncoder and HexDecoder.
virtual size_t MaxSignatureLength(size_t recoverablePartLength=0) const
Provides the maximum signature length produced given the length of the recoverable message part...
Definition: cryptlib.h:2463
virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
Generate a static private/public key pair.
Definition: cryptlib.cpp:927
virtual size_t MaxPlaintextLength(size_t ciphertextLength) const =0
Provides the maximum length of plaintext for a given ciphertext length.
Multiple precision integer with arithmetic operations.
Definition: integer.h:31
Elliptic Curve over GF(2^n)
Definition: ec2n.h:44
virtual size_t CiphertextLength(size_t plaintextLength) const =0
Calculate the length of ciphertext given length of plaintext.
virtual DecodingResult RecoverMessage(byte *recoveredMessage, const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, const byte *signature, size_t signatureLength) const
Recover a message from its signature.
Definition: cryptlib.cpp:911
virtual const CryptoParameters & GetCryptoParameters() const
Retrieves a reference to Crypto Parameters.
Definition: cryptlib.h:2279
const CryptoMaterial & GetMaterial() const
Retrieves a reference to a Public Key.
Definition: cryptlib.h:2224
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Definition: cryptlib.cpp:79
Implementation of schemes based on DL over GF(p)
Classes for the DSA signature algorithm.
Miscellaneous classes for RNGs.
virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const
Sign a message.
Definition: cryptlib.cpp:875
Diffie-Hellman domain.
Definition: dh.h:23
Data structure used to store byte strings.
Definition: queue.h:20
virtual unsigned int PrivateKeyLength() const =0
Provides the size of the private key.
Classes and functions for working with ANS.1 objects.
virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0
Derive agreed value.
Elliptic Curve Parameters.
Definition: eccrypto.h:29
Implementation of BufferedTransformation's attachment interface.
"The XTR public key system" by Arjen K.
Classes for the RSA cryptosystem.
virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0
Check this object for errors.
Interface for public-key signature verifiers.
Definition: cryptlib.h:2591
BlumBlumShub with factorization of the modulus.
Definition: blumshub.h:42
Classes for Blum Blum Shub generator.
virtual unsigned int StaticPrivateKeyLength() const =0
Provides the size of the static private key.
void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
Generate a random key or crypto parameters.
Definition: cryptlib.cpp:771
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:460
RSA cryptosystem
Definition: rsa.h:134
virtual unsigned int PublicKeyLength() const =0
Provides the size of the public key.
virtual unsigned int EphemeralPrivateKeyLength() const =0
Provides the size of ephemeral private key.
bool isValidCoding
Flag to indicate the decoding is valid.
Definition: cryptlib.h:257
Classes and functions for Elliptic Curves over prime and binary fields.
Crypto++ library namespace.
Interface for domains of authenticated key agreement protocols.
Definition: cryptlib.h:2730
Elliptic Curve Point.
Definition: ec2n.h:22
virtual void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters=g_nullNameValuePairs) const =0
Encrypt a byte string.
Classes for Menezes–Qu–Vanstone (MQV) key agreement.
Object Identifier.
Definition: asn.h:91
Classes for access to the operating system's random number generators.
the value is positive or 0
Definition: integer.h:57
#define SIZE_MAX
The maximum value of a machine word.
Definition: misc.h:74