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