Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

852 lines
25 KiB

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