00001
00002
00003 #include "pch.h"
00004
00005 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
00006
00007 #include "cryptlib.h"
00008 #include "pubkey.h"
00009 #include "gfpcrypt.h"
00010 #include "eccrypto.h"
00011 #include "blumshub.h"
00012 #include "filters.h"
00013 #include "files.h"
00014 #include "rsa.h"
00015 #include "md2.h"
00016 #include "elgamal.h"
00017 #include "nr.h"
00018 #include "dsa.h"
00019 #include "dh.h"
00020 #include "mqv.h"
00021 #include "luc.h"
00022 #include "xtrcrypt.h"
00023 #include "rabin.h"
00024 #include "rw.h"
00025 #include "eccrypto.h"
00026 #include "integer.h"
00027 #include "gf2n.h"
00028 #include "ecp.h"
00029 #include "ec2n.h"
00030 #include "asn.h"
00031 #include "rng.h"
00032 #include "hex.h"
00033 #include "oids.h"
00034 #include "esign.h"
00035 #include "osrng.h"
00036 #include "smartptr.h"
00037
00038 #include <iostream>
00039 #include <sstream>
00040 #include <iomanip>
00041
00042 #include "validate.h"
00043
00044
00045 #if (CRYPTOPP_MSC_VERSION >= 1410)
00046 # pragma strict_gs_check (on)
00047 #endif
00048
00049 USING_NAMESPACE(CryptoPP)
00050 USING_NAMESPACE(std)
00051
00052 class FixedRNG : public RandomNumberGenerator
00053 {
00054 public:
00055 FixedRNG(BufferedTransformation &source) : m_source(source) {}
00056
00057 void GenerateBlock(byte *output, size_t size)
00058 {
00059 m_source.Get(output, size);
00060 }
00061
00062 private:
00063 BufferedTransformation &m_source;
00064 };
00065
00066 bool ValidateBBS()
00067 {
00068 cout << "\nBlumBlumShub validation suite running...\n\n";
00069
00070 Integer p("212004934506826557583707108431463840565872545889679278744389317666981496005411448865750399674653351");
00071 Integer q("100677295735404212434355574418077394581488455772477016953458064183204108039226017738610663984508231");
00072 Integer seed("63239752671357255800299643604761065219897634268887145610573595874544114193025997412441121667211431");
00073 BlumBlumShub bbs(p, q, seed);
00074 bool pass = true, fail;
00075 int j;
00076
00077 const byte output1[] = {
00078 0x49,0xEA,0x2C,0xFD,0xB0,0x10,0x64,0xA0,0xBB,0xB9,
00079 0x2A,0xF1,0x01,0xDA,0xC1,0x8A,0x94,0xF7,0xB7,0xCE};
00080 const byte output2[] = {
00081 0x74,0x45,0x48,0xAE,0xAC,0xB7,0x0E,0xDF,0xAF,0xD7,
00082 0xD5,0x0E,0x8E,0x29,0x83,0x75,0x6B,0x27,0x46,0xA1};
00083
00084 byte buf[20];
00085
00086 bbs.GenerateBlock(buf, 20);
00087 fail = memcmp(output1, buf, 20) != 0;
00088 pass = pass && !fail;
00089
00090 cout << (fail ? "FAILED " : "passed ");
00091 for (j=0;j<20;j++)
00092 cout << setw(2) << setfill('0') << hex << (int)buf[j];
00093 cout << endl;
00094
00095 bbs.Seek(10);
00096 bbs.GenerateBlock(buf, 10);
00097 fail = memcmp(output1+10, buf, 10) != 0;
00098 pass = pass && !fail;
00099
00100 cout << (fail ? "FAILED " : "passed ");
00101 for (j=0;j<10;j++)
00102 cout << setw(2) << setfill('0') << hex << (int)buf[j];
00103 cout << endl;
00104
00105 bbs.Seek(1234567);
00106 bbs.GenerateBlock(buf, 20);
00107 fail = memcmp(output2, buf, 20) != 0;
00108 pass = pass && !fail;
00109
00110 cout << (fail ? "FAILED " : "passed ");
00111 for (j=0;j<20;j++)
00112 cout << setw(2) << setfill('0') << hex << (int)buf[j];
00113 cout << endl;
00114
00115 return pass;
00116 }
00117
00118 bool SignatureValidate(PK_Signer &priv, PK_Verifier &pub, bool thorough = false)
00119 {
00120 bool pass = true, fail;
00121
00122 fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2);
00123 pass = pass && !fail;
00124
00125 cout << (fail ? "FAILED " : "passed ");
00126 cout << "signature key validation\n";
00127
00128 const byte *message = (byte *)"test message";
00129 const int messageLen = 12;
00130
00131 SecByteBlock signature(priv.MaxSignatureLength());
00132 size_t signatureLength = priv.SignMessage(GlobalRNG(), message, messageLen, signature);
00133 fail = !pub.VerifyMessage(message, messageLen, signature, signatureLength);
00134 pass = pass && !fail;
00135
00136 cout << (fail ? "FAILED " : "passed ");
00137 cout << "signature and verification\n";
00138
00139 ++signature[0];
00140 fail = pub.VerifyMessage(message, messageLen, signature, signatureLength);
00141 pass = pass && !fail;
00142
00143 cout << (fail ? "FAILED " : "passed ");
00144 cout << "checking invalid signature" << endl;
00145
00146 if (priv.MaxRecoverableLength() > 0)
00147 {
00148 signatureLength = priv.SignMessageWithRecovery(GlobalRNG(), message, messageLen, NULL, 0, signature);
00149 SecByteBlock recovered(priv.MaxRecoverableLengthFromSignatureLength(signatureLength));
00150 DecodingResult result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength);
00151 fail = !(result.isValidCoding && result.messageLength == messageLen && memcmp(recovered, message, messageLen) == 0);
00152 pass = pass && !fail;
00153
00154 cout << (fail ? "FAILED " : "passed ");
00155 cout << "signature and verification with recovery" << endl;
00156
00157 ++signature[0];
00158 result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength);
00159 fail = result.isValidCoding;
00160 pass = pass && !fail;
00161
00162 cout << (fail ? "FAILED " : "passed ");
00163 cout << "recovery with invalid signature" << endl;
00164 }
00165
00166 return pass;
00167 }
00168
00169 bool CryptoSystemValidate(PK_Decryptor &priv, PK_Encryptor &pub, bool thorough = false)
00170 {
00171 bool pass = true, fail;
00172
00173 fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2);
00174 pass = pass && !fail;
00175
00176 cout << (fail ? "FAILED " : "passed ");
00177 cout << "cryptosystem key validation\n";
00178
00179 const byte *message = (byte *)"test message";
00180 const int messageLen = 12;
00181 SecByteBlock ciphertext(priv.CiphertextLength(messageLen));
00182 SecByteBlock plaintext(priv.MaxPlaintextLength(ciphertext.size()));
00183
00184 pub.Encrypt(GlobalRNG(), message, messageLen, ciphertext);
00185 fail = priv.Decrypt(GlobalRNG(), ciphertext, priv.CiphertextLength(messageLen), plaintext) != DecodingResult(messageLen);
00186 fail = fail || memcmp(message, plaintext, messageLen);
00187 pass = pass && !fail;
00188
00189 cout << (fail ? "FAILED " : "passed ");
00190 cout << "encryption and decryption\n";
00191
00192 return pass;
00193 }
00194
00195 bool SimpleKeyAgreementValidate(SimpleKeyAgreementDomain &d)
00196 {
00197 if (d.GetCryptoParameters().Validate(GlobalRNG(), 3))
00198 cout << "passed simple key agreement domain parameters validation" << endl;
00199 else
00200 {
00201 cout << "FAILED simple key agreement domain parameters invalid" << endl;
00202 return false;
00203 }
00204
00205 SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength());
00206 SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength());
00207 SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength());
00208
00209 d.GenerateKeyPair(GlobalRNG(), priv1, pub1);
00210 d.GenerateKeyPair(GlobalRNG(), priv2, pub2);
00211
00212 memset(val1.begin(), 0x10, val1.size());
00213 memset(val2.begin(), 0x11, val2.size());
00214
00215 if (!(d.Agree(val1, priv1, pub2) && d.Agree(val2, priv2, pub1)))
00216 {
00217 cout << "FAILED simple key agreement failed" << endl;
00218 return false;
00219 }
00220
00221 if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength()))
00222 {
00223 cout << "FAILED simple agreed values not equal" << endl;
00224 return false;
00225 }
00226
00227 cout << "passed simple key agreement" << endl;
00228 return true;
00229 }
00230
00231 bool AuthenticatedKeyAgreementValidate(AuthenticatedKeyAgreementDomain &d)
00232 {
00233 if (d.GetCryptoParameters().Validate(GlobalRNG(), 3))
00234 cout << "passed authenticated key agreement domain parameters validation" << endl;
00235 else
00236 {
00237 cout << "FAILED authenticated key agreement domain parameters invalid" << endl;
00238 return false;
00239 }
00240
00241 SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength());
00242 SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength());
00243 SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength());
00244 SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength());
00245 SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength());
00246
00247 d.GenerateStaticKeyPair(GlobalRNG(), spriv1, spub1);
00248 d.GenerateStaticKeyPair(GlobalRNG(), spriv2, spub2);
00249 d.GenerateEphemeralKeyPair(GlobalRNG(), epriv1, epub1);
00250 d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2);
00251
00252 memset(val1.begin(), 0x10, val1.size());
00253 memset(val2.begin(), 0x11, val2.size());
00254
00255 if (!(d.Agree(val1, spriv1, epriv1, spub2, epub2) && d.Agree(val2, spriv2, epriv2, spub1, epub1)))
00256 {
00257 cout << "FAILED authenticated key agreement failed" << endl;
00258 return false;
00259 }
00260
00261 if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength()))
00262 {
00263 cout << "FAILED authenticated agreed values not equal" << endl;
00264 return false;
00265 }
00266
00267 cout << "passed authenticated key agreement" << endl;
00268 return true;
00269 }
00270
00271 bool ValidateRSA()
00272 {
00273 cout << "\nRSA validation suite running...\n\n";
00274
00275 byte out[100], outPlain[100];
00276 bool pass = true, fail;
00277
00278 {
00279 const char *plain = "Everyone gets Friday off.";
00280 static const byte signature[] =
00281 "\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84"
00282 "\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21"
00283 "\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b"
00284 "\x5c\x77\xdf\xd9\xb1\x5b\xfc\x3d\x55\x93\x53\x50\x34\x10\xc1\xe1";
00285
00286 FileSource keys(PACKAGE_DATA_DIR "TestData/rsa512a.dat", true, new HexDecoder);
00287 Weak::RSASSA_PKCS1v15_MD2_Signer rsaPriv(keys);
00288 Weak::RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv);
00289
00290 size_t signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out);
00291 fail = memcmp(signature, out, 64) != 0;
00292 pass = pass && !fail;
00293
00294 cout << (fail ? "FAILED " : "passed ");
00295 cout << "signature check against test vector\n";
00296
00297 fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
00298 pass = pass && !fail;
00299
00300 cout << (fail ? "FAILED " : "passed ");
00301 cout << "verification check against test vector\n";
00302
00303 out[10]++;
00304 fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
00305 pass = pass && !fail;
00306
00307 cout << (fail ? "FAILED " : "passed ");
00308 cout << "invalid signature verification\n";
00309 }
00310 {
00311 FileSource keys(PACKAGE_DATA_DIR "TestData/rsa1024.dat", true, new HexDecoder);
00312 RSAES_PKCS1v15_Decryptor rsaPriv(keys);
00313 RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv);
00314
00315 pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass;
00316 }
00317 {
00318 RSAES<OAEP<SHA> >::Decryptor rsaPriv(GlobalRNG(), 512);
00319 RSAES<OAEP<SHA> >::Encryptor rsaPub(rsaPriv);
00320
00321 pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass;
00322 }
00323 {
00324 byte *plain = (byte *)
00325 "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
00326 static const byte encrypted[] =
00327 "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
00328 "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
00329 "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
00330 "\x62\x51";
00331 static const byte oaepSeed[] =
00332 "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2"
00333 "\xf0\x6c\xb5\x8f";
00334 ByteQueue bq;
00335 bq.Put(oaepSeed, 20);
00336 FixedRNG rng(bq);
00337
00338 FileSource privFile(PACKAGE_DATA_DIR "TestData/rsa400pv.dat", true, new HexDecoder);
00339 FileSource pubFile(PACKAGE_DATA_DIR "TestData/rsa400pb.dat", true, new HexDecoder);
00340 RSAES_OAEP_SHA_Decryptor rsaPriv;
00341 rsaPriv.AccessKey().BERDecodePrivateKey(privFile, false, 0);
00342 RSAES_OAEP_SHA_Encryptor rsaPub(pubFile);
00343
00344 memset(out, 0, 50);
00345 memset(outPlain, 0, 8);
00346 rsaPub.Encrypt(rng, plain, 8, out);
00347 DecodingResult result = rsaPriv.FixedLengthDecrypt(GlobalRNG(), encrypted, outPlain);
00348 fail = !result.isValidCoding || (result.messageLength!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8);
00349 pass = pass && !fail;
00350
00351 cout << (fail ? "FAILED " : "passed ");
00352 cout << "PKCS 2.0 encryption and decryption\n";
00353 }
00354
00355 return pass;
00356 }
00357
00358 bool ValidateDH()
00359 {
00360 cout << "\nDH validation suite running...\n\n";
00361
00362 FileSource f(PACKAGE_DATA_DIR "TestData/dh1024.dat", true, new HexDecoder());
00363 DH dh(f);
00364 return SimpleKeyAgreementValidate(dh);
00365 }
00366
00367 bool ValidateMQV()
00368 {
00369 cout << "\nMQV validation suite running...\n\n";
00370
00371 FileSource f(PACKAGE_DATA_DIR "TestData/mqv1024.dat", true, new HexDecoder());
00372 MQV mqv(f);
00373 return AuthenticatedKeyAgreementValidate(mqv);
00374 }
00375
00376 bool ValidateLUC_DH()
00377 {
00378 cout << "\nLUC-DH validation suite running...\n\n";
00379
00380 FileSource f(PACKAGE_DATA_DIR "TestData/lucd512.dat", true, new HexDecoder());
00381 LUC_DH dh(f);
00382 return SimpleKeyAgreementValidate(dh);
00383 }
00384
00385 bool ValidateXTR_DH()
00386 {
00387 cout << "\nXTR-DH validation suite running...\n\n";
00388
00389 FileSource f(PACKAGE_DATA_DIR "TestData/xtrdh171.dat", true, new HexDecoder());
00390 XTR_DH dh(f);
00391 return SimpleKeyAgreementValidate(dh);
00392 }
00393
00394 bool ValidateElGamal()
00395 {
00396 cout << "\nElGamal validation suite running...\n\n";
00397 bool pass = true;
00398 {
00399 FileSource fc(PACKAGE_DATA_DIR "TestData/elgc1024.dat", true, new HexDecoder);
00400 ElGamalDecryptor privC(fc);
00401 ElGamalEncryptor pubC(privC);
00402 privC.AccessKey().Precompute();
00403 ByteQueue queue;
00404 privC.AccessKey().SavePrecomputation(queue);
00405 privC.AccessKey().LoadPrecomputation(queue);
00406
00407 pass = CryptoSystemValidate(privC, pubC) && pass;
00408 }
00409 return pass;
00410 }
00411
00412 bool ValidateDLIES()
00413 {
00414 cout << "\nDLIES validation suite running...\n\n";
00415 bool pass = true;
00416 {
00417 FileSource fc(PACKAGE_DATA_DIR "TestData/dlie1024.dat", true, new HexDecoder);
00418 DLIES<>::Decryptor privC(fc);
00419 DLIES<>::Encryptor pubC(privC);
00420 pass = CryptoSystemValidate(privC, pubC) && pass;
00421 }
00422 {
00423 cout << "Generating new encryption key..." << endl;
00424 DLIES<>::GroupParameters gp;
00425 gp.GenerateRandomWithKeySize(GlobalRNG(), 128);
00426 DLIES<>::Decryptor decryptor;
00427 decryptor.AccessKey().GenerateRandom(GlobalRNG(), gp);
00428 DLIES<>::Encryptor encryptor(decryptor);
00429
00430 pass = CryptoSystemValidate(decryptor, encryptor) && pass;
00431 }
00432 return pass;
00433 }
00434
00435 bool ValidateNR()
00436 {
00437 cout << "\nNR validation suite running...\n\n";
00438 bool pass = true;
00439 {
00440 FileSource f(PACKAGE_DATA_DIR "TestData/nr2048.dat", true, new HexDecoder);
00441 NR<SHA>::Signer privS(f);
00442 privS.AccessKey().Precompute();
00443 NR<SHA>::Verifier pubS(privS);
00444
00445 pass = SignatureValidate(privS, pubS) && pass;
00446 }
00447 {
00448 cout << "Generating new signature key..." << endl;
00449 NR<SHA>::Signer privS(GlobalRNG(), 256);
00450 NR<SHA>::Verifier pubS(privS);
00451
00452 pass = SignatureValidate(privS, pubS) && pass;
00453 }
00454 return pass;
00455 }
00456
00457 bool ValidateDSA(bool thorough)
00458 {
00459 cout << "\nDSA validation suite running...\n\n";
00460
00461 bool pass = true;
00462 FileSource fs1(PACKAGE_DATA_DIR "TestData/dsa1024.dat", true, new HexDecoder());
00463 DSA::Signer priv(fs1);
00464 DSA::Verifier pub(priv);
00465 FileSource fs2(PACKAGE_DATA_DIR "TestData/dsa1024b.dat", true, new HexDecoder());
00466 DSA::Verifier pub1(fs2);
00467 assert(pub.GetKey() == pub1.GetKey());
00468 pass = SignatureValidate(priv, pub, thorough) && pass;
00469 pass = RunTestDataFile("TestVectors/dsa.txt", g_nullNameValuePairs, thorough) && pass;
00470
00471 return pass;
00472 }
00473
00474 bool ValidateLUC()
00475 {
00476 cout << "\nLUC validation suite running...\n\n";
00477 bool pass=true;
00478
00479 {
00480 FileSource f(PACKAGE_DATA_DIR "TestData/luc1024.dat", true, new HexDecoder);
00481 LUCSSA_PKCS1v15_SHA_Signer priv(f);
00482 LUCSSA_PKCS1v15_SHA_Verifier pub(priv);
00483 pass = SignatureValidate(priv, pub) && pass;
00484 }
00485 {
00486 LUCES_OAEP_SHA_Decryptor priv(GlobalRNG(), 512);
00487 LUCES_OAEP_SHA_Encryptor pub(priv);
00488 pass = CryptoSystemValidate(priv, pub) && pass;
00489 }
00490 return pass;
00491 }
00492
00493 bool ValidateLUC_DL()
00494 {
00495 cout << "\nLUC-HMP validation suite running...\n\n";
00496
00497 FileSource f(PACKAGE_DATA_DIR "TestData/lucs512.dat", true, new HexDecoder);
00498 LUC_HMP<SHA>::Signer privS(f);
00499 LUC_HMP<SHA>::Verifier pubS(privS);
00500 bool pass = SignatureValidate(privS, pubS);
00501
00502 cout << "\nLUC-IES validation suite running...\n\n";
00503
00504 FileSource fc(PACKAGE_DATA_DIR "TestData/lucc512.dat", true, new HexDecoder);
00505 LUC_IES<>::Decryptor privC(fc);
00506 LUC_IES<>::Encryptor pubC(privC);
00507 pass = CryptoSystemValidate(privC, pubC) && pass;
00508
00509 return pass;
00510 }
00511
00512 bool ValidateRabin()
00513 {
00514 cout << "\nRabin validation suite running...\n\n";
00515 bool pass=true;
00516
00517 {
00518 FileSource f(PACKAGE_DATA_DIR "TestData/rabi1024.dat", true, new HexDecoder);
00519 RabinSS<PSSR, SHA>::Signer priv(f);
00520 RabinSS<PSSR, SHA>::Verifier pub(priv);
00521 pass = SignatureValidate(priv, pub) && pass;
00522 }
00523 {
00524 RabinES<OAEP<SHA> >::Decryptor priv(GlobalRNG(), 512);
00525 RabinES<OAEP<SHA> >::Encryptor pub(priv);
00526 pass = CryptoSystemValidate(priv, pub) && pass;
00527 }
00528 return pass;
00529 }
00530
00531 bool ValidateRW()
00532 {
00533 cout << "\nRW validation suite running...\n\n";
00534
00535 FileSource f(PACKAGE_DATA_DIR "TestData/rw1024.dat", true, new HexDecoder);
00536 RWSS<PSSR, SHA>::Signer priv(f);
00537 RWSS<PSSR, SHA>::Verifier pub(priv);
00538
00539 return SignatureValidate(priv, pub);
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 #if !defined(NDEBUG) && !defined(CRYPTOPP_IMPORTS)
00556
00557 bool TestPolynomialMod2()
00558 {
00559 bool pass1 = true, pass2 = true, pass3 = true;
00560
00561 cout << "\nTesting PolynomialMod2 bit operations...\n\n";
00562
00563 static const unsigned int start = 0;
00564 static const unsigned int stop = 4 * WORD_BITS + 1;
00565
00566 for (unsigned int i=start; i < stop; i++)
00567 {
00568 PolynomialMod2 p(1);
00569 p <<= i;
00570
00571 Integer n(Integer::One());
00572 n <<= i;
00573
00574 std::ostringstream oss1;
00575 oss1 << p;
00576
00577 std::string str1, str2;
00578
00579
00580 str1 = oss1.str();
00581 str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
00582
00583
00584 str1.erase(str1.end() - 1);
00585
00586
00587 str2 = IntToString(n, 2);
00588
00589 pass1 &= (str1 == str2);
00590 }
00591
00592 for (unsigned int i=start; i < stop; i++)
00593 {
00594 const word w(SIZE_MAX);
00595
00596 PolynomialMod2 p(w);
00597 p <<= i;
00598
00599 Integer n(Integer::POSITIVE, static_cast<lword>(w));
00600 n <<= i;
00601
00602 std::ostringstream oss1;
00603 oss1 << p;
00604
00605 std::string str1, str2;
00606
00607
00608 str1 = oss1.str();
00609 str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
00610
00611
00612 str1.erase(str1.end() - 1);
00613
00614
00615 str2 = IntToString(n, 2);
00616
00617 pass2 &= (str1 == str2);
00618 }
00619
00620 RandomNumberGenerator& prng = GlobalRNG();
00621 for (unsigned int i=start; i < stop; i++)
00622 {
00623 word w;
00624 prng.GenerateBlock((byte*)&w, sizeof(w));
00625
00626 PolynomialMod2 p(w);
00627 p <<= i;
00628
00629 Integer n(Integer::POSITIVE, static_cast<lword>(w));
00630 n <<= i;
00631
00632 std::ostringstream oss1;
00633 oss1 << p;
00634
00635 std::string str1, str2;
00636
00637
00638 str1 = oss1.str();
00639 str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
00640
00641
00642 str1.erase(str1.end() - 1);
00643
00644
00645 str2 = IntToString(n, 2);
00646
00647 if (str1 != str2)
00648 {
00649 cout << " Oops..." << "\n";
00650 cout << " random: " << std::hex << n << std::dec << "\n";
00651 cout << " str1: " << str1 << "\n";
00652 cout << " str2: " << str2 << "\n";
00653 }
00654
00655 pass3 &= (str1 == str2);
00656 }
00657
00658 cout << (!pass1 ? "FAILED" : "passed") << " " << "1 shifted over range [" << dec << start << "," << stop << "]" << "\n";
00659 cout << (!pass2 ? "FAILED" : "passed") << " " << "0x" << hex << word(SIZE_MAX) << dec << " shifted over range [" << start << "," << stop << "]" << "\n";
00660 cout << (!pass3 ? "FAILED" : "passed") << " " << "random values shifted over range [" << dec << start << "," << stop << "]" << "\n";
00661
00662 if (!(pass1 && pass2 && pass3))
00663 cout.flush();
00664
00665 return pass1 && pass2 && pass3;
00666 }
00667 #endif
00668
00669 bool ValidateECP()
00670 {
00671 cout << "\nECP validation suite running...\n\n";
00672
00673 ECIES<ECP>::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1());
00674 ECIES<ECP>::Encryptor cpub(cpriv);
00675 ByteQueue bq;
00676 cpriv.GetKey().DEREncode(bq);
00677 cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
00678 cpub.GetKey().DEREncode(bq);
00679 ECDSA<ECP, SHA>::Signer spriv(bq);
00680 ECDSA<ECP, SHA>::Verifier spub(bq);
00681 ECDH<ECP>::Domain ecdhc(ASN1::secp192r1());
00682 ECMQV<ECP>::Domain ecmqvc(ASN1::secp192r1());
00683
00684 spriv.AccessKey().Precompute();
00685 ByteQueue queue;
00686 spriv.AccessKey().SavePrecomputation(queue);
00687 spriv.AccessKey().LoadPrecomputation(queue);
00688
00689 bool pass = SignatureValidate(spriv, spub);
00690 cpub.AccessKey().Precompute();
00691 cpriv.AccessKey().Precompute();
00692 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00693 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00694 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00695
00696 cout << "Turning on point compression..." << endl;
00697 cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
00698 cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
00699 ecdhc.AccessGroupParameters().SetPointCompression(true);
00700 ecmqvc.AccessGroupParameters().SetPointCompression(true);
00701 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00702 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00703 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00704
00705 cout << "Testing SEC 2, NIST, and Brainpool recommended curves..." << endl;
00706 OID oid;
00707 while (!(oid = DL_GroupParameters_EC<ECP>::GetNextRecommendedParametersOID(oid)).m_values.empty())
00708 {
00709 DL_GroupParameters_EC<ECP> params(oid);
00710 bool fail = !params.Validate(GlobalRNG(), 2);
00711 cout << (fail ? "FAILED" : "passed") << " " << dec << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
00712 pass = pass && !fail;
00713 }
00714
00715 return pass;
00716 }
00717
00718 bool ValidateEC2N()
00719 {
00720 cout << "\nEC2N validation suite running...\n\n";
00721
00722 ECIES<EC2N>::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1());
00723 ECIES<EC2N>::Encryptor cpub(cpriv);
00724 ByteQueue bq;
00725 cpriv.DEREncode(bq);
00726 cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
00727 cpub.DEREncode(bq);
00728 ECDSA<EC2N, SHA>::Signer spriv(bq);
00729 ECDSA<EC2N, SHA>::Verifier spub(bq);
00730 ECDH<EC2N>::Domain ecdhc(ASN1::sect193r1());
00731 ECMQV<EC2N>::Domain ecmqvc(ASN1::sect193r1());
00732
00733 spriv.AccessKey().Precompute();
00734 ByteQueue queue;
00735 spriv.AccessKey().SavePrecomputation(queue);
00736 spriv.AccessKey().LoadPrecomputation(queue);
00737
00738 bool pass = SignatureValidate(spriv, spub);
00739 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00740 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00741 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00742
00743 cout << "Turning on point compression..." << endl;
00744 cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
00745 cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
00746 ecdhc.AccessGroupParameters().SetPointCompression(true);
00747 ecmqvc.AccessGroupParameters().SetPointCompression(true);
00748 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00749 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00750 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00751
00752 #if 0 // TODO: turn this back on when I make EC2N faster for pentanomial basis
00753 cout << "Testing SEC 2 recommended curves..." << endl;
00754 OID oid;
00755 while (!(oid = DL_GroupParameters_EC<EC2N>::GetNextRecommendedParametersOID(oid)).m_values.empty())
00756 {
00757 DL_GroupParameters_EC<EC2N> params(oid);
00758 bool fail = !params.Validate(GlobalRNG(), 2);
00759 cout << (fail ? "FAILED" : "passed") << " " << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
00760 pass = pass && !fail;
00761 }
00762 #endif
00763
00764 return pass;
00765 }
00766
00767 bool ValidateECDSA()
00768 {
00769 cout << "\nECDSA validation suite running...\n\n";
00770
00771
00772 GF2NT gf2n(191, 9, 0);
00773 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";
00774 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";
00775 EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24));
00776
00777 EC2N::Point P;
00778 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"
00779 "\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());
00780 Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H");
00781 Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH");
00782 EC2N::Point Q(ec.Multiply(d, P));
00783 ECDSA<EC2N, SHA>::Signer priv(ec, P, n, d);
00784 ECDSA<EC2N, SHA>::Verifier pub(priv);
00785
00786 Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH");
00787 Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H");
00788 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"
00789 "\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e";
00790 Integer r(sig, 24);
00791 Integer s(sig+24, 24);
00792
00793 Integer rOut, sOut;
00794 bool fail, pass=true;
00795
00796 priv.RawSign(k, h, rOut, sOut);
00797 fail = (rOut != r) || (sOut != s);
00798 pass = pass && !fail;
00799
00800 cout << (fail ? "FAILED " : "passed ");
00801 cout << "signature check against test vector\n";
00802
00803 fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig));
00804 pass = pass && !fail;
00805
00806 cout << (fail ? "FAILED " : "passed ");
00807 cout << "verification check against test vector\n";
00808
00809 fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig));
00810 pass = pass && !fail;
00811
00812 pass = SignatureValidate(priv, pub) && pass;
00813
00814 return pass;
00815 }
00816
00817 bool ValidateESIGN()
00818 {
00819 cout << "\nESIGN validation suite running...\n\n";
00820
00821 bool pass = true, fail;
00822
00823 static const char plain[] = "test";
00824 static const byte signature[] =
00825 "\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"
00826 "\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"
00827 "\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"
00828 "\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"
00829 "\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";
00830
00831 FileSource keys(PACKAGE_DATA_DIR "TestData/esig1536.dat", true, new HexDecoder);
00832 ESIGN<SHA>::Signer signer(keys);
00833 ESIGN<SHA>::Verifier verifier(signer);
00834
00835 fail = !SignatureValidate(signer, verifier);
00836 pass = pass && !fail;
00837
00838 fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength());
00839 pass = pass && !fail;
00840
00841 cout << (fail ? "FAILED " : "passed ");
00842 cout << "verification check against test vector\n";
00843
00844 cout << "Generating signature key from seed..." << endl;
00845 signer.AccessKey().GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512));
00846 verifier = signer;
00847
00848 fail = !SignatureValidate(signer, verifier);
00849 pass = pass && !fail;
00850
00851 return pass;
00852 }