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