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