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