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 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("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("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 byte *plain = (byte *)
00304 "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
00305 byte *encrypted = (byte *)
00306 "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
00307 "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
00308 "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
00309 "\x62\x51";
00310 byte *oaepSeed = (byte *)
00311 "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2"
00312 "\xf0\x6c\xb5\x8f";
00313 ByteQueue bq;
00314 bq.Put(oaepSeed, 20);
00315 FixedRNG rng(bq);
00316
00317 FileSource privFile("rsa400pv.dat", true, new HexDecoder);
00318 FileSource pubFile("rsa400pb.dat", true, new HexDecoder);
00319 RSAES_OAEP_SHA_Decryptor rsaPriv;
00320 rsaPriv.AccessKey().BERDecodePrivateKey(privFile, false, 0);
00321 RSAES_OAEP_SHA_Encryptor rsaPub(pubFile);
00322
00323 memset(out, 0, 50);
00324 memset(outPlain, 0, 8);
00325 rsaPub.Encrypt(rng, plain, 8, out);
00326 DecodingResult result = rsaPriv.FixedLengthDecrypt(GlobalRNG(), encrypted, outPlain);
00327 fail = !result.isValidCoding || (result.messageLength!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8);
00328 pass = pass && !fail;
00329
00330 cout << (fail ? "FAILED " : "passed ");
00331 cout << "PKCS 2.0 encryption and decryption\n";
00332 }
00333
00334 return pass;
00335 }
00336
00337 bool ValidateDH()
00338 {
00339 cout << "\nDH validation suite running...\n\n";
00340
00341 FileSource f("dh1024.dat", true, new HexDecoder());
00342 DH dh(f);
00343 return SimpleKeyAgreementValidate(dh);
00344 }
00345
00346 bool ValidateMQV()
00347 {
00348 cout << "\nMQV validation suite running...\n\n";
00349
00350 FileSource f("mqv1024.dat", true, new HexDecoder());
00351 MQV mqv(f);
00352 return AuthenticatedKeyAgreementValidate(mqv);
00353 }
00354
00355 bool ValidateLUC_DH()
00356 {
00357 cout << "\nLUC-DH validation suite running...\n\n";
00358
00359 FileSource f("lucd512.dat", true, new HexDecoder());
00360 LUC_DH dh(f);
00361 return SimpleKeyAgreementValidate(dh);
00362 }
00363
00364 bool ValidateXTR_DH()
00365 {
00366 cout << "\nXTR-DH validation suite running...\n\n";
00367
00368 FileSource f("xtrdh171.dat", true, new HexDecoder());
00369 XTR_DH dh(f);
00370 return SimpleKeyAgreementValidate(dh);
00371 }
00372
00373 bool ValidateElGamal()
00374 {
00375 cout << "\nElGamal validation suite running...\n\n";
00376 bool pass = true;
00377 {
00378 FileSource fc("elgc1024.dat", true, new HexDecoder);
00379 ElGamalDecryptor privC(fc);
00380 ElGamalEncryptor pubC(privC);
00381 privC.AccessKey().Precompute();
00382 ByteQueue queue;
00383 privC.AccessKey().SavePrecomputation(queue);
00384 privC.AccessKey().LoadPrecomputation(queue);
00385
00386 pass = CryptoSystemValidate(privC, pubC) && pass;
00387 }
00388 return pass;
00389 }
00390
00391 bool ValidateDLIES()
00392 {
00393 cout << "\nDLIES validation suite running...\n\n";
00394 bool pass = true;
00395 {
00396 FileSource fc("dlie1024.dat", true, new HexDecoder);
00397 DLIES<>::Decryptor privC(fc);
00398 DLIES<>::Encryptor pubC(privC);
00399 pass = CryptoSystemValidate(privC, pubC) && pass;
00400 }
00401 {
00402 cout << "Generating new encryption key..." << endl;
00403 DLIES<>::GroupParameters gp;
00404 gp.GenerateRandomWithKeySize(GlobalRNG(), 128);
00405 DLIES<>::Decryptor decryptor;
00406 decryptor.AccessKey().GenerateRandom(GlobalRNG(), gp);
00407 DLIES<>::Encryptor encryptor(decryptor);
00408
00409 pass = CryptoSystemValidate(decryptor, encryptor) && pass;
00410 }
00411 return pass;
00412 }
00413
00414 bool ValidateNR()
00415 {
00416 cout << "\nNR validation suite running...\n\n";
00417 bool pass = true;
00418 {
00419 FileSource f("nr2048.dat", true, new HexDecoder);
00420 NR<SHA>::Signer privS(f);
00421 privS.AccessKey().Precompute();
00422 NR<SHA>::Verifier pubS(privS);
00423
00424 pass = SignatureValidate(privS, pubS) && pass;
00425 }
00426 {
00427 cout << "Generating new signature key..." << endl;
00428 NR<SHA>::Signer privS(GlobalRNG(), 256);
00429 NR<SHA>::Verifier pubS(privS);
00430
00431 pass = SignatureValidate(privS, pubS) && pass;
00432 }
00433 return pass;
00434 }
00435
00436 bool ValidateDSA(bool thorough)
00437 {
00438 cout << "\nDSA validation suite running...\n\n";
00439
00440 bool pass = true, fail;
00441 {
00442 FileSource fs("dsa512.dat", true, new HexDecoder());
00443 GDSA<SHA>::Signer priv(fs);
00444 priv.AccessKey().Precompute(16);
00445 GDSA<SHA>::Verifier pub(priv);
00446
00447 byte seed[]={0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21,
00448 0x1b, 0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3};
00449 Integer k("358dad57 1462710f 50e254cf 1a376b2b deaadfbfh");
00450 Integer h("a9993e36 4706816a ba3e2571 7850c26c 9cd0d89dh");
00451 byte sig[]={0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43, 0x5c, 0xb7, 0x18,
00452 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3, 0x41, 0xc0,
00453 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf, 0x24, 0x58, 0xf4,
00454 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc, 0xd8, 0xc8};
00455 Integer r(sig, 20);
00456 Integer s(sig+20, 20);
00457
00458 Integer pGen, qGen, rOut, sOut;
00459 int c;
00460
00461 fail = !DSA::GeneratePrimes(seed, 160, c, pGen, 512, qGen);
00462 fail = fail || (pGen != pub.GetKey().GetGroupParameters().GetModulus()) || (qGen != pub.GetKey().GetGroupParameters().GetSubgroupOrder());
00463 pass = pass && !fail;
00464
00465 cout << (fail ? "FAILED " : "passed ");
00466 cout << "prime generation test\n";
00467
00468 priv.RawSign(k, h, rOut, sOut);
00469 fail = (rOut != r) || (sOut != s);
00470 pass = pass && !fail;
00471
00472 cout << (fail ? "FAILED " : "passed ");
00473 cout << "signature check against test vector\n";
00474
00475 fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig));
00476 pass = pass && !fail;
00477
00478 cout << (fail ? "FAILED " : "passed ");
00479 cout << "verification check against test vector\n";
00480
00481 fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig));
00482 pass = pass && !fail;
00483 }
00484 FileSource fs1("dsa1024.dat", true, new HexDecoder());
00485 DSA::Signer priv(fs1);
00486 DSA::Verifier pub(priv);
00487 FileSource fs2("dsa1024b.dat", true, new HexDecoder());
00488 DSA::Verifier pub1(fs2);
00489 assert(pub.GetKey() == pub1.GetKey());
00490 pass = SignatureValidate(priv, pub, thorough) && pass;
00491 return pass;
00492 }
00493
00494 bool ValidateLUC()
00495 {
00496 cout << "\nLUC validation suite running...\n\n";
00497 bool pass=true;
00498
00499 {
00500 FileSource f("luc1024.dat", true, new HexDecoder);
00501 LUCSSA_PKCS1v15_SHA_Signer priv(f);
00502 LUCSSA_PKCS1v15_SHA_Verifier pub(priv);
00503 pass = SignatureValidate(priv, pub) && pass;
00504 }
00505 {
00506 LUCES_OAEP_SHA_Decryptor priv(GlobalRNG(), 512);
00507 LUCES_OAEP_SHA_Encryptor pub(priv);
00508 pass = CryptoSystemValidate(priv, pub) && pass;
00509 }
00510 return pass;
00511 }
00512
00513 bool ValidateLUC_DL()
00514 {
00515 cout << "\nLUC-HMP validation suite running...\n\n";
00516
00517 FileSource f("lucs512.dat", true, new HexDecoder);
00518 LUC_HMP<SHA>::Signer privS(f);
00519 LUC_HMP<SHA>::Verifier pubS(privS);
00520 bool pass = SignatureValidate(privS, pubS);
00521
00522 cout << "\nLUC-IES validation suite running...\n\n";
00523
00524 FileSource fc("lucc512.dat", true, new HexDecoder);
00525 LUC_IES<>::Decryptor privC(fc);
00526 LUC_IES<>::Encryptor pubC(privC);
00527 pass = CryptoSystemValidate(privC, pubC) && pass;
00528
00529 return pass;
00530 }
00531
00532 bool ValidateRabin()
00533 {
00534 cout << "\nRabin validation suite running...\n\n";
00535 bool pass=true;
00536
00537 {
00538 FileSource f("rabi1024.dat", true, new HexDecoder);
00539 RabinSS<PSSR, SHA>::Signer priv(f);
00540 RabinSS<PSSR, SHA>::Verifier pub(priv);
00541 pass = SignatureValidate(priv, pub) && pass;
00542 }
00543 {
00544 RabinES<OAEP<SHA> >::Decryptor priv(GlobalRNG(), 512);
00545 RabinES<OAEP<SHA> >::Encryptor pub(priv);
00546 pass = CryptoSystemValidate(priv, pub) && pass;
00547 }
00548 return pass;
00549 }
00550
00551 bool ValidateRW()
00552 {
00553 cout << "\nRW validation suite running...\n\n";
00554
00555 FileSource f("rw1024.dat", true, new HexDecoder);
00556 RWSS<PSSR, SHA>::Signer priv(f);
00557 RWSS<PSSR, SHA>::Verifier pub(priv);
00558
00559 return SignatureValidate(priv, pub);
00560 }
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 bool ValidateECP()
00576 {
00577 cout << "\nECP validation suite running...\n\n";
00578
00579 ECIES<ECP>::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1());
00580 ECIES<ECP>::Encryptor cpub(cpriv);
00581 ByteQueue bq;
00582 cpriv.GetKey().DEREncode(bq);
00583 cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
00584 cpub.GetKey().DEREncode(bq);
00585 ECDSA<ECP, SHA>::Signer spriv(bq);
00586 ECDSA<ECP, SHA>::Verifier spub(bq);
00587 ECDH<ECP>::Domain ecdhc(ASN1::secp192r1());
00588 ECMQV<ECP>::Domain ecmqvc(ASN1::secp192r1());
00589
00590 spriv.AccessKey().Precompute();
00591 ByteQueue queue;
00592 spriv.AccessKey().SavePrecomputation(queue);
00593 spriv.AccessKey().LoadPrecomputation(queue);
00594
00595 bool pass = SignatureValidate(spriv, spub);
00596 cpub.AccessKey().Precompute();
00597 cpriv.AccessKey().Precompute();
00598 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00599 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00600 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00601
00602 cout << "Turning on point compression..." << endl;
00603 cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
00604 cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
00605 ecdhc.AccessGroupParameters().SetPointCompression(true);
00606 ecmqvc.AccessGroupParameters().SetPointCompression(true);
00607 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00608 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00609 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00610
00611 cout << "Testing SEC 2 recommended curves..." << endl;
00612 OID oid;
00613 while (!(oid = DL_GroupParameters_EC<ECP>::GetNextRecommendedParametersOID(oid)).m_values.empty())
00614 {
00615 DL_GroupParameters_EC<ECP> params(oid);
00616 bool fail = !params.Validate(GlobalRNG(), 2);
00617 cout << (fail ? "FAILED" : "passed") << " " << dec << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
00618 pass = pass && !fail;
00619 }
00620
00621 return pass;
00622 }
00623
00624 bool ValidateEC2N()
00625 {
00626 cout << "\nEC2N validation suite running...\n\n";
00627
00628 ECIES<EC2N>::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1());
00629 ECIES<EC2N>::Encryptor cpub(cpriv);
00630 ByteQueue bq;
00631 cpriv.DEREncode(bq);
00632 cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
00633 cpub.DEREncode(bq);
00634 ECDSA<EC2N, SHA>::Signer spriv(bq);
00635 ECDSA<EC2N, SHA>::Verifier spub(bq);
00636 ECDH<EC2N>::Domain ecdhc(ASN1::sect193r1());
00637 ECMQV<EC2N>::Domain ecmqvc(ASN1::sect193r1());
00638
00639 spriv.AccessKey().Precompute();
00640 ByteQueue queue;
00641 spriv.AccessKey().SavePrecomputation(queue);
00642 spriv.AccessKey().LoadPrecomputation(queue);
00643
00644 bool pass = SignatureValidate(spriv, spub);
00645 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00646 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00647 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00648
00649 cout << "Turning on point compression..." << endl;
00650 cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
00651 cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
00652 ecdhc.AccessGroupParameters().SetPointCompression(true);
00653 ecmqvc.AccessGroupParameters().SetPointCompression(true);
00654 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00655 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00656 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00657
00658 #if 0 // TODO: turn this back on when I make EC2N faster for pentanomial basis
00659 cout << "Testing SEC 2 recommended curves..." << endl;
00660 OID oid;
00661 while (!(oid = ECParameters<EC2N>::GetNextRecommendedParametersOID(oid)).m_values.empty())
00662 {
00663 ECParameters<EC2N> params(oid);
00664 bool fail = !params.ValidateParameters(GlobalRNG());
00665 cout << (fail ? "FAILED" : "passed") << " " << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
00666 pass = pass && !fail;
00667 }
00668 #endif
00669
00670 return pass;
00671 }
00672
00673 bool ValidateECDSA()
00674 {
00675 cout << "\nECDSA validation suite running...\n\n";
00676
00677
00678 GF2NT gf2n(191, 9, 0);
00679 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";
00680 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";
00681 EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24));
00682
00683 EC2N::Point P;
00684 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"
00685 "\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());
00686 Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H");
00687 Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH");
00688 EC2N::Point Q(ec.Multiply(d, P));
00689 ECDSA<EC2N, SHA>::Signer priv(ec, P, n, d);
00690 ECDSA<EC2N, SHA>::Verifier pub(priv);
00691
00692 Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH");
00693 Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H");
00694 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"
00695 "\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e";
00696 Integer r(sig, 24);
00697 Integer s(sig+24, 24);
00698
00699 Integer rOut, sOut;
00700 bool fail, pass=true;
00701
00702 priv.RawSign(k, h, rOut, sOut);
00703 fail = (rOut != r) || (sOut != s);
00704 pass = pass && !fail;
00705
00706 cout << (fail ? "FAILED " : "passed ");
00707 cout << "signature check against test vector\n";
00708
00709 fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig));
00710 pass = pass && !fail;
00711
00712 cout << (fail ? "FAILED " : "passed ");
00713 cout << "verification check against test vector\n";
00714
00715 fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig));
00716 pass = pass && !fail;
00717
00718 pass = SignatureValidate(priv, pub) && pass;
00719
00720 return pass;
00721 }
00722
00723 bool ValidateESIGN()
00724 {
00725 cout << "\nESIGN validation suite running...\n\n";
00726
00727 bool pass = true, fail;
00728
00729 const char *plain = "test";
00730 const byte *signature = (byte *)
00731 "\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"
00732 "\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"
00733 "\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"
00734 "\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"
00735 "\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";
00736
00737 FileSource keys("esig1536.dat", true, new HexDecoder);
00738 ESIGN<SHA>::Signer signer(keys);
00739 ESIGN<SHA>::Verifier verifier(signer);
00740
00741 fail = !SignatureValidate(signer, verifier);
00742 pass = pass && !fail;
00743
00744 fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength());
00745 pass = pass && !fail;
00746
00747 cout << (fail ? "FAILED " : "passed ");
00748 cout << "verification check against test vector\n";
00749
00750 cout << "Generating signature key from seed..." << endl;
00751 InvertibleESIGNFunction priv;
00752 priv.GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512));
00753
00754 fail = !SignatureValidate(signer, verifier);
00755 pass = pass && !fail;
00756
00757 return pass;
00758 }