Fabcoin Core  0.16.2
P2P Digital Currency
datatest.cpp
Go to the documentation of this file.
1 // datatest.cpp - written and placed in the public domain by Wei Dai
2 
3 #define CRYPTOPP_DEFAULT_NO_DLL
4 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
5 
6 #include "cryptlib.h"
7 #include "factory.h"
8 #include "integer.h"
9 #include "filters.h"
10 #include "hex.h"
11 #include "randpool.h"
12 #include "files.h"
13 #include "trunhash.h"
14 #include "queue.h"
15 #include "smartptr.h"
16 #include "validate.h"
17 #include "hkdf.h"
18 #include "stdcpp.h"
19 #include <iostream>
20 
21 // Aggressive stack checking with VS2005 SP1 and above.
22 #if (CRYPTOPP_MSC_VERSION >= 1410)
23 # pragma strict_gs_check (on)
24 #endif
25 
26 #if defined(__COVERITY__)
27 extern "C" void __coverity_tainted_data_sanitize__(void *);
28 #endif
29 
32 
33 typedef std::map<std::string, std::string> TestData;
34 static bool s_thorough = false;
35 
36 class TestFailure : public Exception
37 {
38 public:
39  TestFailure() : Exception(OTHER_ERROR, "Validation test failed") {}
40 };
41 
42 static const TestData *s_currentTestData = NULL;
43 
44 static void OutputTestData(const TestData &v)
45 {
46  for (TestData::const_iterator i = v.begin(); i != v.end(); ++i)
47  {
48  cerr << i->first << ": " << i->second << endl;
49  }
50 }
51 
52 static void SignalTestFailure()
53 {
54  OutputTestData(*s_currentTestData);
55  throw TestFailure();
56 }
57 
58 static void SignalUnknownAlgorithmError(const std::string& algType)
59 {
60  OutputTestData(*s_currentTestData);
61  throw Exception(Exception::OTHER_ERROR, "Unknown algorithm " + algType + " during validation test");
62 }
63 
64 static void SignalTestError()
65 {
66  OutputTestData(*s_currentTestData);
67  throw Exception(Exception::OTHER_ERROR, "Unexpected error during validation test");
68 }
69 
70 bool DataExists(const TestData &data, const char *name)
71 {
72  TestData::const_iterator i = data.find(name);
73  return (i != data.end());
74 }
75 
76 const std::string & GetRequiredDatum(const TestData &data, const char *name)
77 {
78  TestData::const_iterator i = data.find(name);
79  if (i == data.end())
80  SignalTestError();
81  return i->second;
82 }
83 
84 void RandomizedTransfer(BufferedTransformation &source, BufferedTransformation &target, bool finish, const std::string &channel=DEFAULT_CHANNEL)
85 {
86  while (source.MaxRetrievable() > (finish ? 0 : 4096))
87  {
88  byte buf[4096+64];
89  size_t start = GlobalRNG().GenerateWord32(0, 63);
90  size_t len = GlobalRNG().GenerateWord32(1, UnsignedMin(4096U, 3*source.MaxRetrievable()/2));
91  len = source.Get(buf+start, len);
92  target.ChannelPut(channel, buf+start, len);
93  }
94 }
95 
96 void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target)
97 {
98  std::string s1 = GetRequiredDatum(data, name), s2;
99  ByteQueue q;
100 
101  while (!s1.empty())
102  {
103  while (s1[0] == ' ')
104  {
105  s1 = s1.substr(1);
106  if (s1.empty())
107  goto end; // avoid invalid read if s1 is empty
108  }
109 
110  int repeat = 1;
111  if (s1[0] == 'r')
112  {
113  repeat = atoi(s1.c_str()+1);
114  s1 = s1.substr(s1.find(' ')+1);
115  }
116 
117  s2 = ""; // MSVC 6 doesn't have clear();
118 
119  if (s1[0] == '\"')
120  {
121  s2 = s1.substr(1, s1.find('\"', 1)-1);
122  s1 = s1.substr(s2.length() + 2);
123  }
124  else if (s1.substr(0, 2) == "0x")
125  {
126  StringSource(s1.substr(2, s1.find(' ')), true, new HexDecoder(new StringSink(s2)));
127  s1 = s1.substr(STDMIN(s1.find(' '), s1.length()));
128  }
129  else
130  {
131  StringSource(s1.substr(0, s1.find(' ')), true, new HexDecoder(new StringSink(s2)));
132  s1 = s1.substr(STDMIN(s1.find(' '), s1.length()));
133  }
134 
135  while (repeat--)
136  {
137  q.Put((const byte *)s2.data(), s2.size());
138  RandomizedTransfer(q, target, false);
139  }
140  }
141 
142 end:
143  RandomizedTransfer(q, target, true);
144 }
145 
146 std::string GetDecodedDatum(const TestData &data, const char *name)
147 {
148  std::string s;
149  PutDecodedDatumInto(data, name, StringSink(s).Ref());
150  return s;
151 }
152 
153 std::string GetOptionalDecodedDatum(const TestData &data, const char *name)
154 {
155  std::string s;
156  if (DataExists(data, name))
157  PutDecodedDatumInto(data, name, StringSink(s).Ref());
158  return s;
159 }
160 
162 {
163 public:
165 
166  virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
167  {
168  TestData::const_iterator i = m_data.find(name);
169  if (i == m_data.end())
170  {
171  if (std::string(name) == Name::DigestSize() && valueType == typeid(int))
172  {
173  i = m_data.find("MAC");
174  if (i == m_data.end())
175  i = m_data.find("Digest");
176  if (i == m_data.end())
177  return false;
178 
179  m_temp.resize(0);
180  PutDecodedDatumInto(m_data, i->first.c_str(), StringSink(m_temp).Ref());
181  *reinterpret_cast<int *>(pValue) = (int)m_temp.size();
182  return true;
183  }
184  else
185  return false;
186  }
187 
188  const std::string &value = i->second;
189 
190  if (valueType == typeid(int))
191  *reinterpret_cast<int *>(pValue) = atoi(value.c_str());
192  else if (valueType == typeid(Integer))
193  *reinterpret_cast<Integer *>(pValue) = Integer((std::string(value) + "h").c_str());
194  else if (valueType == typeid(ConstByteArrayParameter))
195  {
196  m_temp.resize(0);
198  reinterpret_cast<ConstByteArrayParameter *>(pValue)->Assign((const byte *)m_temp.data(), m_temp.size(), false);
199  }
200  else
201  throw ValueTypeMismatch(name, typeid(std::string), valueType);
202 
203  return true;
204  }
205 
206 private:
207  const TestData &m_data;
208  mutable std::string m_temp;
209 };
210 
212 {
213  // "!!" converts between bool <-> integral.
214  if (!pub.Validate(GlobalRNG(), 2U+!!s_thorough))
215  SignalTestFailure();
216  if (!priv.Validate(GlobalRNG(), 2U+!!s_thorough))
217  SignalTestFailure();
218 
219  ByteQueue bq1, bq2;
220  pub.Save(bq1);
221  pub.AssignFrom(priv);
222  pub.Save(bq2);
223  if (bq1 != bq2)
224  SignalTestFailure();
225 }
226 
228 {
229  std::string name = GetRequiredDatum(v, "Name");
230  std::string test = GetRequiredDatum(v, "Test");
231 
232  member_ptr<PK_Signer> signer(ObjectFactoryRegistry<PK_Signer>::Registry().CreateObject(name.c_str()));
233  member_ptr<PK_Verifier> verifier(ObjectFactoryRegistry<PK_Verifier>::Registry().CreateObject(name.c_str()));
234 
235  TestDataNameValuePairs pairs(v);
236 
237  if (test == "GenerateKey")
238  {
239  signer->AccessPrivateKey().GenerateRandom(GlobalRNG(), pairs);
240  verifier->AccessPublicKey().AssignFrom(signer->AccessPrivateKey());
241  }
242  else
243  {
244  std::string keyFormat = GetRequiredDatum(v, "KeyFormat");
245 
246  if (keyFormat == "DER")
247  verifier->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref());
248  else if (keyFormat == "Component")
249  verifier->AccessMaterial().AssignFrom(pairs);
250 
251  if (test == "Verify" || test == "NotVerify")
252  {
253  VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN);
254  PutDecodedDatumInto(v, "Signature", verifierFilter);
255  PutDecodedDatumInto(v, "Message", verifierFilter);
256  verifierFilter.MessageEnd();
257  if (verifierFilter.GetLastResult() == (test == "NotVerify"))
258  SignalTestFailure();
259  return;
260  }
261  else if (test == "PublicKeyValid")
262  {
263  if (!verifier->GetMaterial().Validate(GlobalRNG(), 3))
264  SignalTestFailure();
265  return;
266  }
267 
268  if (keyFormat == "DER")
269  signer->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref());
270  else if (keyFormat == "Component")
271  signer->AccessMaterial().AssignFrom(pairs);
272  }
273 
274  if (test == "GenerateKey" || test == "KeyPairValidAndConsistent")
275  {
277  VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::THROW_EXCEPTION);
278  verifierFilter.Put((const byte *)"abc", 3);
279  StringSource ss("abc", true, new SignerFilter(GlobalRNG(), *signer, new Redirector(verifierFilter)));
280  }
281  else if (test == "Sign")
282  {
283  SignerFilter f(GlobalRNG(), *signer, new HexEncoder(new FileSink(cout)));
284  StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f));
285  SignalTestFailure();
286  }
287  else if (test == "DeterministicSign")
288  {
289  // This test is specialized for RFC 6979. The RFC is a drop-in replacement
290  // for DSA and ECDSA, and access to the seed or secret is not needed. If
291  // additional determinsitic signatures are added, then the test harness will
292  // likely need to be extended.
293  string signature;
294  SignerFilter f(GlobalRNG(), *signer, new StringSink(signature));
295  StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f));
296 
297  if (GetDecodedDatum(v, "Signature") != signature)
298  SignalTestFailure();
299 
300  return;
301  }
302  else if (test == "RandomSign")
303  {
304  SignalTestError();
305  CRYPTOPP_ASSERT(false); // TODO: implement
306  }
307  else
308  {
309  SignalTestError();
310  CRYPTOPP_ASSERT(false);
311  }
312 }
313 
315 {
316  std::string name = GetRequiredDatum(v, "Name");
317  std::string test = GetRequiredDatum(v, "Test");
318 
319  member_ptr<PK_Encryptor> encryptor(ObjectFactoryRegistry<PK_Encryptor>::Registry().CreateObject(name.c_str()));
320  member_ptr<PK_Decryptor> decryptor(ObjectFactoryRegistry<PK_Decryptor>::Registry().CreateObject(name.c_str()));
321 
322  std::string keyFormat = GetRequiredDatum(v, "KeyFormat");
323 
324  if (keyFormat == "DER")
325  {
326  decryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref());
327  encryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref());
328  }
329  else if (keyFormat == "Component")
330  {
331  TestDataNameValuePairs pairs(v);
332  decryptor->AccessMaterial().AssignFrom(pairs);
333  encryptor->AccessMaterial().AssignFrom(pairs);
334  }
335 
336  if (test == "DecryptMatch")
337  {
338  std::string decrypted, expected = GetDecodedDatum(v, "Plaintext");
339  StringSource ss(GetDecodedDatum(v, "Ciphertext"), true, new PK_DecryptorFilter(GlobalRNG(), *decryptor, new StringSink(decrypted)));
340  if (decrypted != expected)
341  SignalTestFailure();
342  }
343  else if (test == "KeyPairValidAndConsistent")
344  {
345  TestKeyPairValidAndConsistent(encryptor->AccessMaterial(), decryptor->GetMaterial());
346  }
347  else
348  {
349  SignalTestError();
350  CRYPTOPP_ASSERT(false);
351  }
352 }
353 
354 void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
355 {
356  std::string name = GetRequiredDatum(v, "Name");
357  std::string test = GetRequiredDatum(v, "Test");
358 
359  std::string key = GetDecodedDatum(v, "Key");
360  std::string plaintext = GetDecodedDatum(v, "Plaintext");
361 
362  TestDataNameValuePairs testDataPairs(v);
363  CombinedNameValuePairs pairs(overrideParameters, testDataPairs);
364 
365  if (test == "Encrypt" || test == "EncryptXorDigest" || test == "Resync" || test == "EncryptionMCT" || test == "DecryptionMCT")
366  {
367  static member_ptr<SymmetricCipher> encryptor, decryptor;
368  static std::string lastName;
369 
370  if (name != lastName)
371  {
372  encryptor.reset(ObjectFactoryRegistry<SymmetricCipher, ENCRYPTION>::Registry().CreateObject(name.c_str()));
373  decryptor.reset(ObjectFactoryRegistry<SymmetricCipher, DECRYPTION>::Registry().CreateObject(name.c_str()));
374  lastName = name;
375  }
376 
378  if (pairs.GetValue(Name::IV(), iv) && iv.size() != encryptor->IVSize())
379  SignalTestFailure();
380 
381  if (test == "Resync")
382  {
383  encryptor->Resynchronize(iv.begin(), (int)iv.size());
384  decryptor->Resynchronize(iv.begin(), (int)iv.size());
385  }
386  else
387  {
388  encryptor->SetKey((const byte *)key.data(), key.size(), pairs);
389  decryptor->SetKey((const byte *)key.data(), key.size(), pairs);
390  }
391 
392  int seek = pairs.GetIntValueWithDefault("Seek", 0);
393  if (seek)
394  {
395  encryptor->Seek(seek);
396  decryptor->Seek(seek);
397  }
398 
399  std::string encrypted, xorDigest, ciphertext, ciphertextXorDigest;
400  if (test == "EncryptionMCT" || test == "DecryptionMCT")
401  {
402  SymmetricCipher *cipher = encryptor.get();
403  SecByteBlock buf((byte *)plaintext.data(), plaintext.size()), keybuf((byte *)key.data(), key.size());
404 
405  if (test == "DecryptionMCT")
406  {
407  cipher = decryptor.get();
408  ciphertext = GetDecodedDatum(v, "Ciphertext");
409  buf.Assign((byte *)ciphertext.data(), ciphertext.size());
410  }
411 
412  for (int i=0; i<400; i++)
413  {
414  encrypted.reserve(10000 * plaintext.size());
415  for (int j=0; j<10000; j++)
416  {
417  cipher->ProcessString(buf.begin(), buf.size());
418  encrypted.append((char *)buf.begin(), buf.size());
419  }
420 
421  encrypted.erase(0, encrypted.size() - keybuf.size());
422  xorbuf(keybuf.begin(), (const byte *)encrypted.data(), keybuf.size());
423  cipher->SetKey(keybuf, keybuf.size());
424  }
425  encrypted.assign((char *)buf.begin(), buf.size());
426  ciphertext = GetDecodedDatum(v, test == "EncryptionMCT" ? "Ciphertext" : "Plaintext");
427  if (encrypted != ciphertext)
428  {
429  std::cout << "incorrectly encrypted: ";
430  StringSource xx(encrypted, false, new HexEncoder(new FileSink(std::cout)));
431  xx.Pump(256); xx.Flush(false);
432  std::cout << "\n";
433  SignalTestFailure();
434  }
435  return;
436  }
437 
439  RandomizedTransfer(StringStore(plaintext).Ref(), encFilter, true);
440  encFilter.MessageEnd();
441  /*{
442  std::string z;
443  encryptor->Seek(seek);
444  StringSource ss(plaintext, false, new StreamTransformationFilter(*encryptor, new StringSink(z), StreamTransformationFilter::NO_PADDING));
445  while (ss.Pump(64)) {}
446  ss.PumpAll();
447  for (int i=0; i<z.length(); i++)
448  CRYPTOPP_ASSERT(encrypted[i] == z[i]);
449  }*/
450  if (test != "EncryptXorDigest")
451  ciphertext = GetDecodedDatum(v, "Ciphertext");
452  else
453  {
454  ciphertextXorDigest = GetDecodedDatum(v, "CiphertextXorDigest");
455  xorDigest.append(encrypted, 0, 64);
456  for (size_t i=64; i<encrypted.size(); i++)
457  xorDigest[i%64] ^= encrypted[i];
458  }
459  if (test != "EncryptXorDigest" ? encrypted != ciphertext : xorDigest != ciphertextXorDigest)
460  {
461  std::cout << "incorrectly encrypted: ";
462  StringSource xx(encrypted, false, new HexEncoder(new FileSink(std::cout)));
463  xx.Pump(2048); xx.Flush(false);
464  std::cout << "\n";
465  SignalTestFailure();
466  }
467  std::string decrypted;
469  RandomizedTransfer(StringStore(encrypted).Ref(), decFilter, true);
470  decFilter.MessageEnd();
471  if (decrypted != plaintext)
472  {
473  std::cout << "incorrectly decrypted: ";
474  StringSource xx(decrypted, false, new HexEncoder(new FileSink(std::cout)));
475  xx.Pump(256); xx.Flush(false);
476  std::cout << "\n";
477  SignalTestFailure();
478  }
479  }
480  else
481  {
482  std::cout << "unexpected test name\n";
483  SignalTestError();
484  }
485 }
486 
487 void TestAuthenticatedSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
488 {
489  std::string type = GetRequiredDatum(v, "AlgorithmType");
490  std::string name = GetRequiredDatum(v, "Name");
491  std::string test = GetRequiredDatum(v, "Test");
492  std::string key = GetDecodedDatum(v, "Key");
493 
494  std::string plaintext = GetOptionalDecodedDatum(v, "Plaintext");
495  std::string ciphertext = GetOptionalDecodedDatum(v, "Ciphertext");
496  std::string header = GetOptionalDecodedDatum(v, "Header");
497  std::string footer = GetOptionalDecodedDatum(v, "Footer");
498  std::string mac = GetOptionalDecodedDatum(v, "MAC");
499 
500  TestDataNameValuePairs testDataPairs(v);
501  CombinedNameValuePairs pairs(overrideParameters, testDataPairs);
502 
503  if (test == "Encrypt" || test == "EncryptXorDigest" || test == "NotVerify")
504  {
508  asc1->SetKey((const byte *)key.data(), key.size(), pairs);
509  asc2->SetKey((const byte *)key.data(), key.size(), pairs);
510 
511  std::string encrypted, decrypted;
512  AuthenticatedEncryptionFilter ef(*asc1, new StringSink(encrypted));
513  bool macAtBegin = !mac.empty() && !GlobalRNG().GenerateBit(); // test both ways randomly
515 
516  if (asc1->NeedsPrespecifiedDataLengths())
517  {
518  asc1->SpecifyDataLengths(header.size(), plaintext.size(), footer.size());
519  asc2->SpecifyDataLengths(header.size(), plaintext.size(), footer.size());
520  }
521 
522  StringStore sh(header), sp(plaintext), sc(ciphertext), sf(footer), sm(mac);
523 
524  if (macAtBegin)
525  RandomizedTransfer(sm, df, true);
526  sh.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
527  RandomizedTransfer(sc, df, true);
528  sf.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
529  if (!macAtBegin)
530  RandomizedTransfer(sm, df, true);
531  df.MessageEnd();
532 
533  RandomizedTransfer(sh, ef, true, AAD_CHANNEL);
534  RandomizedTransfer(sp, ef, true);
535  RandomizedTransfer(sf, ef, true, AAD_CHANNEL);
536  ef.MessageEnd();
537 
538  if (test == "Encrypt" && encrypted != ciphertext+mac)
539  {
540  std::cout << "incorrectly encrypted: ";
541  StringSource xx(encrypted, false, new HexEncoder(new FileSink(std::cout)));
542  xx.Pump(2048); xx.Flush(false);
543  std::cout << "\n";
544  SignalTestFailure();
545  }
546  if (test == "Encrypt" && decrypted != plaintext)
547  {
548  std::cout << "incorrectly decrypted: ";
549  StringSource xx(decrypted, false, new HexEncoder(new FileSink(std::cout)));
550  xx.Pump(256); xx.Flush(false);
551  std::cout << "\n";
552  SignalTestFailure();
553  }
554 
555  if (ciphertext.size()+mac.size()-plaintext.size() != asc1->DigestSize())
556  {
557  std::cout << "bad MAC size\n";
558  SignalTestFailure();
559  }
560  if (df.GetLastResult() != (test == "Encrypt"))
561  {
562  std::cout << "MAC incorrectly verified\n";
563  SignalTestFailure();
564  }
565  }
566  else
567  {
568  std::cout << "unexpected test name\n";
569  SignalTestError();
570  }
571 }
572 
573 void TestDigestOrMAC(TestData &v, bool testDigest)
574 {
575  std::string name = GetRequiredDatum(v, "Name");
576  std::string test = GetRequiredDatum(v, "Test");
577  const char *digestName = testDigest ? "Digest" : "MAC";
578 
581  HashTransformation *pHash = NULL;
582 
583  TestDataNameValuePairs pairs(v);
584 
585  if (testDigest)
586  {
587  hash.reset(ObjectFactoryRegistry<HashTransformation>::Registry().CreateObject(name.c_str()));
588  pHash = hash.get();
589  }
590  else
591  {
592  mac.reset(ObjectFactoryRegistry<MessageAuthenticationCode>::Registry().CreateObject(name.c_str()));
593  pHash = mac.get();
594  std::string key = GetDecodedDatum(v, "Key");
595  mac->SetKey((const byte *)key.c_str(), key.size(), pairs);
596  }
597 
598  if (test == "Verify" || test == "VerifyTruncated" || test == "NotVerify")
599  {
600  int digestSize = -1;
601  if (test == "VerifyTruncated")
602  digestSize = pairs.GetIntValueWithDefault(Name::DigestSize(), digestSize);
603  HashVerificationFilter verifierFilter(*pHash, NULL, HashVerificationFilter::HASH_AT_BEGIN, digestSize);
604  PutDecodedDatumInto(v, digestName, verifierFilter);
605  PutDecodedDatumInto(v, "Message", verifierFilter);
606  verifierFilter.MessageEnd();
607  if (verifierFilter.GetLastResult() == (test == "NotVerify"))
608  SignalTestFailure();
609  }
610  else
611  {
612  SignalTestError();
613  CRYPTOPP_ASSERT(false);
614  }
615 }
616 
618 {
619  std::string name = GetRequiredDatum(v, "Name");
620  std::string test = GetRequiredDatum(v, "Test");
621 
622  if(test == "Skip") return;
623  CRYPTOPP_ASSERT(test == "Verify");
624 
625  std::string key = GetDecodedDatum(v, "Key");
626  std::string salt = GetDecodedDatum(v, "Salt");
627  std::string info = GetDecodedDatum(v, "Info");
628  std::string derived = GetDecodedDatum(v, "DerivedKey");
629  std::string t = GetDecodedDatum(v, "DerivedKeyLength");
630 
631  TestDataNameValuePairs pairs(v);
632  unsigned int length = pairs.GetIntValueWithDefault(Name::DerivedKeyLength(), (int)derived.size());
633 
635  kdf.reset(ObjectFactoryRegistry<KeyDerivationFunction>::Registry().CreateObject(name.c_str()));
636 
637  std::string calc; calc.resize(length);
638  unsigned int ret = kdf->DeriveKey(reinterpret_cast<byte*>(&calc[0]), calc.size(),
639  reinterpret_cast<const byte*>(key.data()), key.size(),
640  reinterpret_cast<const byte*>(salt.data()), salt.size(),
641  reinterpret_cast<const byte*>(info.data()), info.size());
642 
643  if(calc != derived || ret != length)
644  SignalTestFailure();
645 }
646 
647 bool GetField(std::istream &is, std::string &name, std::string &value)
648 {
649  name.resize(0); // GCC workaround: 2.95.3 doesn't have clear()
650  is >> name;
651 
652  if (name.empty())
653  return false;
654 
655  if (name[name.size()-1] != ':')
656  {
657  char c;
658  is >> skipws >> c;
659  if (c != ':')
660  SignalTestError();
661  }
662  else
663  name.erase(name.size()-1);
664 
665  while (is.peek() == ' ')
666  is.ignore(1);
667 
668  // VC60 workaround: getline bug
669  char buffer[128];
670  value.resize(0); // GCC workaround: 2.95.3 doesn't have clear()
671  bool continueLine, space = false;
672 
673  do
674  {
675  do
676  {
677  is.get(buffer, sizeof(buffer));
678  value += buffer;
679  if (buffer[0] == ' ')
680  space = true;
681  }
682  while (buffer[0] != 0);
683  is.clear();
684  is.ignore();
685 
686  if (!value.empty() && value[value.size()-1] == '\r')
687  value.resize(value.size()-1);
688 
689  if (!value.empty() && value[value.size()-1] == '\\')
690  {
691  value.resize(value.size()-1);
692  continueLine = true;
693  }
694  else
695  continueLine = false;
696 
697  std::string::size_type i = value.find('#');
698  if (i != std::string::npos)
699  value.erase(i);
700  }
701  while (continueLine);
702 
703  // Strip intermediate spaces for some values.
704  if (space && (name == "Modulus" || name == "SubgroupOrder" || name == "SubgroupGenerator" ||
705  name == "PublicElement" || name == "PrivateExponent" || name == "Signature"))
706  {
707  string temp;
708  temp.reserve(value.size());
709 
710  std::string::const_iterator it;
711  for(it = value.begin(); it != value.end(); it++)
712  {
713  if(*it != ' ')
714  temp.push_back(*it);
715  }
716 
717  std::swap(temp, value);
718  }
719 
720  return true;
721 }
722 
723 void OutputPair(const NameValuePairs &v, const char *name)
724 {
725  Integer x;
726  bool b = v.GetValue(name, x);
728  cout << name << ": \\\n ";
729  x.Encode(HexEncoder(new FileSink(cout), false, 64, "\\\n ").Ref(), x.MinEncodedSize());
730  cout << endl;
731 }
732 
734 {
735  std::string names = v.GetValueNames();
736  string::size_type i = 0;
737  while (i < names.size())
738  {
739  string::size_type j = names.find_first_of (';', i);
740 
741  if (j == string::npos)
742  return;
743  else
744  {
745  std::string name = names.substr(i, j-i);
746  if (name.find(':') == string::npos)
747  OutputPair(v, name.c_str());
748  }
749 
750  i = j + 1;
751  }
752 }
753 
754 void TestDataFile(std::string filename, const NameValuePairs &overrideParameters, unsigned int &totalTests, unsigned int &failedTests)
755 {
756  static const std::string dataDirectory(CRYPTOPP_DATA_DIR);
757  if (!dataDirectory.empty())
758  {
759  if(dataDirectory != filename.substr(0, dataDirectory.length()))
760  filename.insert(0, dataDirectory);
761  }
762 
763  std::ifstream file(filename.c_str());
764  if (!file.good())
765  throw Exception(Exception::OTHER_ERROR, "Can not open file " + filename + " for reading");
766  TestData v;
767  s_currentTestData = &v;
768  std::string name, value, lastAlgName;
769 
770  while (file)
771  {
772  while (file.peek() == '#')
773  file.ignore((std::numeric_limits<std::streamsize>::max)(), '\n');
774 
775  if (file.peek() == '\n' || file.peek() == '\r')
776  v.clear();
777 
778  if (!GetField(file, name, value))
779  break;
780  v[name] = value;
781 
782  if (name == "Test" && (s_thorough || v["SlowTest"] != "1"))
783  {
784  bool failed = true;
785  std::string algType = GetRequiredDatum(v, "AlgorithmType");
786 
787  if (lastAlgName != GetRequiredDatum(v, "Name"))
788  {
789  lastAlgName = GetRequiredDatum(v, "Name");
790  cout << "\nTesting " << algType.c_str() << " algorithm " << lastAlgName.c_str() << ".\n";
791  }
792 
793  try
794  {
795  if (algType == "Signature")
797  else if (algType == "SymmetricCipher")
798  TestSymmetricCipher(v, overrideParameters);
799  else if (algType == "AuthenticatedSymmetricCipher")
800  TestAuthenticatedSymmetricCipher(v, overrideParameters);
801  else if (algType == "AsymmetricCipher")
803  else if (algType == "MessageDigest")
804  TestDigestOrMAC(v, true);
805  else if (algType == "MAC")
806  TestDigestOrMAC(v, false);
807  else if (algType == "KDF")
809  else if (algType == "FileList")
810  TestDataFile(GetRequiredDatum(v, "Test"), g_nullNameValuePairs, totalTests, failedTests);
811  else
812  SignalUnknownAlgorithmError(algType);
813  failed = false;
814  }
815  catch (const TestFailure &)
816  {
817  cout << "\nTest failed.\n";
818  }
819  catch (const CryptoPP::Exception &e)
820  {
821  cout << "\nCryptoPP::Exception caught: " << e.what() << endl;
822  }
823  catch (const std::exception &e)
824  {
825  cout << "\nstd::exception caught: " << e.what() << endl;
826  }
827 
828  if (failed)
829  {
830  cout << "Skipping to next test.\n";
831  failedTests++;
832  }
833  else
834  cout << "." << flush;
835 
836  totalTests++;
837  }
838  }
839 }
840 
841 bool RunTestDataFile(const char *filename, const NameValuePairs &overrideParameters, bool thorough)
842 {
843  s_thorough = thorough;
844  unsigned int totalTests = 0, failedTests = 0;
845  TestDataFile((filename ? filename : ""), overrideParameters, totalTests, failedTests);
846  cout << dec << "\nTests complete. Total tests = " << totalTests << ". Failed tests = " << failedTests << "." << endl;
847  if (failedTests != 0)
848  cout << "SOME TESTS FAILED!\n";
849  return failedTests == 0;
850 }
851 
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:29
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:140
Append input to a string object.
virtual void AssignFrom(const NameValuePairs &source)=0
Assign values to this object.
virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: datatest.cpp:166
Indicates the hash is at the beginning of the message (i.e., concatenation of hash+message) ...
Definition: filters.h:571
bool GetField(std::istream &is, std::string &name, std::string &value)
Definition: datatest.cpp:647
Filter wrapper for PK_Verifier.
Definition: filters.h:745
uint8_t byte
Definition: Common.h:57
const lword LWORD_MAX
Definition: config.h:246
virtual void SetKey(const byte *key, size_t length, const NameValuePairs &params=g_nullNameValuePairs)
Sets or reset the key of this object.
Definition: cryptlib.cpp:97
void TestDataFile(std::string filename, const NameValuePairs &overrideParameters, unsigned int &totalTests, unsigned int &failedTests)
Definition: datatest.cpp:754
Class file for Randomness Pool.
void swap(dev::eth::Watch &_a, dev::eth::Watch &_b)
Definition: Interface.h:284
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition: integer.cpp:3369
virtual void Load(BufferedTransformation &bt)
Loads a key from a BufferedTransformation.
Definition: cryptlib.h:2109
size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true)
Input a byte for processing on a channel.
Definition: cryptlib.h:1864
virtual bool NeedsPrespecifiedDataLengths() const
Determines if data lengths must be specified prior to inputting data.
Definition: cryptlib.h:1150
static const std::string s2("AAD")
bool GetLastResult() const
Definition: filters.h:593
Converts given data to base 16.
Definition: hex.h:16
Classes for HKDF from RFC 5869.
virtual word32 GenerateWord32(word32 min=0, word32 max=0xffffffffUL)
Generate a random 32 bit word in the range min to max, inclusive.
Definition: cryptlib.cpp:298
void OutputPair(const NameValuePairs &v, const char *name)
Definition: datatest.cpp:723
Decode base 16 data back to bytes.
Definition: hex.h:36
virtual void Save(BufferedTransformation &bt) const
Saves a key to a BufferedTransformation.
Definition: cryptlib.h:2092
Abstract base classes that provide a uniform interface to this library.
Thrown when an unexpected type is encountered.
Definition: cryptlib.h:287
CryptoMaterial & AccessMaterial()
Retrieves a reference to a Private Key.
Definition: cryptlib.h:2256
const std::string & GetRequiredDatum(const TestData &data, const char *name)
Definition: datatest.cpp:76
Some other error occurred not belonging to other categories.
Definition: cryptlib.h:159
RandomNumberGenerator & GlobalRNG()
Definition: test.cpp:123
Indicates the filter should throw a HashVerificationFailed if a failure is encountered.
Definition: filters.h:771
std::string GetOptionalDecodedDatum(const TestData &data, const char *name)
Definition: datatest.cpp:153
Classes for automatic resource management.
Filter wrapper for PK_Signer.
Definition: filters.h:717
size_t size() const
Length of the memory block.
Definition: algparam.h:93
#define c(i)
std::hash for asio::adress
Definition: Common.h:323
void ProcessString(byte *inoutString, size_t length)
Encrypt or decrypt a string of bytes.
Definition: cryptlib.h:877
size_t MinEncodedSize(Signedness sign=UNSIGNED) const
Minimum number of bytes to encode this integer.
Definition: integer.cpp:3354
Combines two sets of NameValuePairs.
Definition: algparam.h:135
Interface for buffered transformations.
Definition: cryptlib.h:1352
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:89
const CryptoMaterial & GetMaterial() const
Retrieves a reference to a Private Key.
Definition: cryptlib.h:2259
void TestAsymmetricCipher(TestData &v)
Definition: datatest.cpp:314
Pointer that overloads operator ->
Definition: smartptr.h:39
TestDataNameValuePairs(const TestData &data)
Definition: datatest.cpp:164
const std::string DEFAULT_CHANNEL
Default channel for BufferedTransformation.
Definition: cryptlib.cpp:59
bool MessageEnd(int propagation=-1, bool blocking=true)
Signals the end of messages to the object.
Definition: cryptlib.h:1434
#define x(i)
Classes for an unlimited queue to store bytes.
const char * source
Definition: rpcconsole.cpp:60
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:337
bool GetLastResult() const
Definition: filters.h:692
Filter wrapper for HashTransformation.
Definition: filters.h:550
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1376
Filter wrapper for decrypting with AuthenticatedSymmetricCipher.
Definition: filters.h:659
virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0
Check this object for errors.
Filter wrapper for encrypting with AuthenticatedSymmetricCipher.
Definition: filters.h:617
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition: cryptlib.h:382
const char * name
Definition: rest.cpp:36
virtual void Resynchronize(const byte *iv, int ivLength=-1)
Resynchronize with an IV.
Definition: cryptlib.h:662
Classes for HexEncoder and HexDecoder.
ExecStats::duration max
Definition: ExecStats.cpp:36
rpc::SessionManager sm
Definition: shhrpc.cpp:60
void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target)
Definition: datatest.cpp:96
void TestDigestOrMAC(TestData &v, bool testDigest)
Definition: datatest.cpp:573
const TestData & m_data
Definition: datatest.cpp:207
Interface for one direction (encryption or decryption) of a stream cipher or cipher mode...
Definition: cryptlib.h:1103
Multiple precision integer with arithmetic operations.
Definition: integer.h:43
h256 kdf(Secret const &_priv, h256 const &_hash)
Key derivation.
Definition: Common.cpp:322
const std::string AAD_CHANNEL
Channel for additional authenticated data.
Definition: cryptlib.cpp:60
Filter wrapper for PK_Decryptor.
Definition: filters.h:1022
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
Definition: misc.h:512
const CryptoMaterial & GetMaterial() const
Retrieves a reference to a Public Key.
Definition: cryptlib.h:2236
lword Pump(lword pumpMax=(size_t) SIZE_MAX)
Pump data to attached transformation.
Definition: filters.h:1258
virtual PrivateKey & AccessPrivateKey()=0
Retrieves a reference to a Private Key.
Classes and functions for registering and locating library objects.
std::string GetDecodedDatum(const TestData &data, const char *name)
Definition: datatest.cpp:146
const T * get() const
Definition: smartptr.h:52
#define b(i, j)
bool DataExists(const TestData &data, const char *name)
Definition: datatest.cpp:70
String-based implementation of Store interface.
Definition: filters.h:1155
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:477
#define CRYPTOPP_ASSERT(exp)
Definition: trap.h:92
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Definition: cryptlib.cpp:76
Redirect input to another BufferedTransformation without owning it.
Definition: filters.h:808
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:28
void TestKeyPairValidAndConsistent(CryptoMaterial &pub, const CryptoMaterial &priv)
Definition: datatest.cpp:211
Data structure used to store byte strings.
Definition: queue.h:20
bool GetLastResult() const
Retrieves the result of the last verification.
Definition: filters.h:788
void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
Definition: datatest.cpp:354
void TestKeyDerivationFunction(TestData &v)
Definition: datatest.cpp:617
virtual unsigned int DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, const byte *salt, size_t saltLen, const byte *info=NULL, size_t infoLen=0) const =0
derive a key from secret
Implementation of BufferedTransformation&#39;s attachment interface.
#define f(x)
Definition: gost.cpp:57
#define USING_NAMESPACE(x)
Definition: config.h:206
Filter wrapper for StreamTransformation.
Definition: filters.h:491
virtual void Seek(lword pos)
Seek to an absolute position.
Definition: cryptlib.h:903
void TestSignatureScheme(TestData &v)
Definition: datatest.cpp:227
CryptoMaterial & AccessMaterial()
Retrieves a reference to a Public Key.
Definition: cryptlib.h:2232
virtual unsigned int GenerateBit()
Generate new random bit and return it.
Definition: cryptlib.cpp:286
PlatformStyle::TableColorType type
Definition: rpcconsole.cpp:61
virtual unsigned int DigestSize() const =0
Provides the digest size of the hash.
virtual PublicKey & AccessPublicKey()=0
Retrieves a reference to a Public Key.
#define CRYPTOPP_UNUSED(x)
Definition: config.h:741
Interface for hash functions and data processing part of MACs.
Definition: cryptlib.h:930
Interface for crypto material, such as public and private keys, and crypto parameters.
Definition: cryptlib.h:2042
virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params=g_nullNameValuePairs)
Generate a random key or crypto parameters.
Definition: cryptlib.h:2166
void TestAuthenticatedSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
Definition: datatest.cpp:487
std::map< std::string, std::string > TestData
Definition: datatest.cpp:33
virtual lword MaxRetrievable() const
Provides the number of bytes ready for retrieval.
Definition: cryptlib.cpp:496
Multiple precision integer with arithmetic operations.
void RandomizedTransfer(BufferedTransformation &source, BufferedTransformation &target, bool finish, const std::string &channel=DEFAULT_CHANNEL)
Definition: datatest.cpp:84
Classes providing file-based library services.
#define e(i)
Definition: sha.cpp:733
void SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength=0)
Prespecifies the data lengths.
Definition: cryptlib.cpp:254
No padding added to a block.
Definition: filters.h:476
virtual size_t Get(byte &outByte)
Retrieve a 8-bit byte.
Definition: cryptlib.cpp:515
bool RunTestDataFile(const char *filename, const NameValuePairs &overrideParameters, bool thorough)
Definition: datatest.cpp:841
CRYPTOPP_DLL std::string GetValueNames() const
Get a list of value names that can be retrieved.
Definition: cryptlib.h:362
Indicates the signature is at the beginning of the message (i.e., concatenation of signature+message)...
Definition: filters.h:763
Object factory registry.
Definition: factory.h:45
#define s1(x)
Definition: sha256.c:70
void OutputNameValuePairs(const NameValuePairs &v)
Definition: datatest.cpp:733
Implementation of Store interface.
Definition: files.h:125
Indicates the MAC is at the beginning of the message (i.e., concatenation of mac+message) ...
Definition: filters.h:669
#define CRYPTOPP_DATA_DIR
Definition: config.h:72
void reset(T *p=0)
Definition: smartptr.h:72
uint8_t const * data
Definition: sha3.h:19
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
Flush buffered input and/or output, with signal propagation.
Definition: filters.cpp:78
virtual unsigned int IVSize() const
Returns length of the IV accepted by this object.
Definition: cryptlib.h:640
int atoi(const std::string &str)
Interface for retrieving values given their names.
Definition: cryptlib.h:279