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