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(PACKAGE_DATA_DIR "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(PACKAGE_DATA_DIR "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(PACKAGE_DATA_DIR "TestData/rsa400pv.dat", true, new HexDecoder);
00324 FileSource pubFile(PACKAGE_DATA_DIR "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(PACKAGE_DATA_DIR "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(PACKAGE_DATA_DIR "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(PACKAGE_DATA_DIR "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(PACKAGE_DATA_DIR "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(PACKAGE_DATA_DIR "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(PACKAGE_DATA_DIR "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(PACKAGE_DATA_DIR "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;
00447 FileSource fs1(PACKAGE_DATA_DIR "TestData/dsa1024.dat", true, new HexDecoder());
00448 DSA::Signer priv(fs1);
00449 DSA::Verifier pub(priv);
00450 FileSource fs2(PACKAGE_DATA_DIR "TestData/dsa1024b.dat", true, new HexDecoder());
00451 DSA::Verifier pub1(fs2);
00452 assert(pub.GetKey() == pub1.GetKey());
00453 pass = SignatureValidate(priv, pub, thorough) && pass;
00454 pass = RunTestDataFile(PACKAGE_DATA_DIR "TestVectors/dsa.txt", g_nullNameValuePairs, thorough) && pass;
00455 return pass;
00456 }
00457
00458 bool ValidateLUC()
00459 {
00460 cout << "\nLUC validation suite running...\n\n";
00461 bool pass=true;
00462
00463 {
00464 FileSource f(PACKAGE_DATA_DIR "TestData/luc1024.dat", true, new HexDecoder);
00465 LUCSSA_PKCS1v15_SHA_Signer priv(f);
00466 LUCSSA_PKCS1v15_SHA_Verifier pub(priv);
00467 pass = SignatureValidate(priv, pub) && pass;
00468 }
00469 {
00470 LUCES_OAEP_SHA_Decryptor priv(GlobalRNG(), 512);
00471 LUCES_OAEP_SHA_Encryptor pub(priv);
00472 pass = CryptoSystemValidate(priv, pub) && pass;
00473 }
00474 return pass;
00475 }
00476
00477 bool ValidateLUC_DL()
00478 {
00479 cout << "\nLUC-HMP validation suite running...\n\n";
00480
00481 FileSource f(PACKAGE_DATA_DIR "TestData/lucs512.dat", true, new HexDecoder);
00482 LUC_HMP<SHA>::Signer privS(f);
00483 LUC_HMP<SHA>::Verifier pubS(privS);
00484 bool pass = SignatureValidate(privS, pubS);
00485
00486 cout << "\nLUC-IES validation suite running...\n\n";
00487
00488 FileSource fc(PACKAGE_DATA_DIR "TestData/lucc512.dat", true, new HexDecoder);
00489 LUC_IES<>::Decryptor privC(fc);
00490 LUC_IES<>::Encryptor pubC(privC);
00491 pass = CryptoSystemValidate(privC, pubC) && pass;
00492
00493 return pass;
00494 }
00495
00496 bool ValidateRabin()
00497 {
00498 cout << "\nRabin validation suite running...\n\n";
00499 bool pass=true;
00500
00501 {
00502 FileSource f(PACKAGE_DATA_DIR "TestData/rabi1024.dat", true, new HexDecoder);
00503 RabinSS<PSSR, SHA>::Signer priv(f);
00504 RabinSS<PSSR, SHA>::Verifier pub(priv);
00505 pass = SignatureValidate(priv, pub) && pass;
00506 }
00507 {
00508 RabinES<OAEP<SHA> >::Decryptor priv(GlobalRNG(), 512);
00509 RabinES<OAEP<SHA> >::Encryptor pub(priv);
00510 pass = CryptoSystemValidate(priv, pub) && pass;
00511 }
00512 return pass;
00513 }
00514
00515 bool ValidateRW()
00516 {
00517 cout << "\nRW validation suite running...\n\n";
00518
00519 FileSource f(PACKAGE_DATA_DIR "TestData/rw1024.dat", true, new HexDecoder);
00520 RWSS<PSSR, SHA>::Signer priv(f);
00521 RWSS<PSSR, SHA>::Verifier pub(priv);
00522
00523 return SignatureValidate(priv, pub);
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 bool ValidateECP()
00540 {
00541 cout << "\nECP validation suite running...\n\n";
00542
00543 ECIES<ECP>::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1());
00544 ECIES<ECP>::Encryptor cpub(cpriv);
00545 ByteQueue bq;
00546 cpriv.GetKey().DEREncode(bq);
00547 cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
00548 cpub.GetKey().DEREncode(bq);
00549 ECDSA<ECP, SHA>::Signer spriv(bq);
00550 ECDSA<ECP, SHA>::Verifier spub(bq);
00551 ECDH<ECP>::Domain ecdhc(ASN1::secp192r1());
00552 ECMQV<ECP>::Domain ecmqvc(ASN1::secp192r1());
00553
00554 spriv.AccessKey().Precompute();
00555 ByteQueue queue;
00556 spriv.AccessKey().SavePrecomputation(queue);
00557 spriv.AccessKey().LoadPrecomputation(queue);
00558
00559 bool pass = SignatureValidate(spriv, spub);
00560 cpub.AccessKey().Precompute();
00561 cpriv.AccessKey().Precompute();
00562 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00563 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00564 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00565
00566 cout << "Turning on point compression..." << endl;
00567 cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
00568 cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
00569 ecdhc.AccessGroupParameters().SetPointCompression(true);
00570 ecmqvc.AccessGroupParameters().SetPointCompression(true);
00571 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00572 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00573 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00574
00575 cout << "Testing SEC 2, NIST, and Brainpool recommended curves..." << endl;
00576 OID oid;
00577 while (!(oid = DL_GroupParameters_EC<ECP>::GetNextRecommendedParametersOID(oid)).m_values.empty())
00578 {
00579 DL_GroupParameters_EC<ECP> params(oid);
00580 bool fail = !params.Validate(GlobalRNG(), 2);
00581 cout << (fail ? "FAILED" : "passed") << " " << dec << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
00582 pass = pass && !fail;
00583 }
00584
00585 return pass;
00586 }
00587
00588 bool ValidateEC2N()
00589 {
00590 cout << "\nEC2N validation suite running...\n\n";
00591
00592 ECIES<EC2N>::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1());
00593 ECIES<EC2N>::Encryptor cpub(cpriv);
00594 ByteQueue bq;
00595 cpriv.DEREncode(bq);
00596 cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
00597 cpub.DEREncode(bq);
00598 ECDSA<EC2N, SHA>::Signer spriv(bq);
00599 ECDSA<EC2N, SHA>::Verifier spub(bq);
00600 ECDH<EC2N>::Domain ecdhc(ASN1::sect193r1());
00601 ECMQV<EC2N>::Domain ecmqvc(ASN1::sect193r1());
00602
00603 spriv.AccessKey().Precompute();
00604 ByteQueue queue;
00605 spriv.AccessKey().SavePrecomputation(queue);
00606 spriv.AccessKey().LoadPrecomputation(queue);
00607
00608 bool pass = SignatureValidate(spriv, spub);
00609 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00610 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00611 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00612
00613 cout << "Turning on point compression..." << endl;
00614 cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
00615 cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
00616 ecdhc.AccessGroupParameters().SetPointCompression(true);
00617 ecmqvc.AccessGroupParameters().SetPointCompression(true);
00618 pass = CryptoSystemValidate(cpriv, cpub) && pass;
00619 pass = SimpleKeyAgreementValidate(ecdhc) && pass;
00620 pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
00621
00622 #if 0 // TODO: turn this back on when I make EC2N faster for pentanomial basis
00623 cout << "Testing SEC 2 recommended curves..." << endl;
00624 OID oid;
00625 while (!(oid = DL_GroupParameters_EC<EC2N>::GetNextRecommendedParametersOID(oid)).m_values.empty())
00626 {
00627 DL_GroupParameters_EC<EC2N> params(oid);
00628 bool fail = !params.Validate(GlobalRNG(), 2);
00629 cout << (fail ? "FAILED" : "passed") << " " << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
00630 pass = pass && !fail;
00631 }
00632 #endif
00633
00634 return pass;
00635 }
00636
00637 bool ValidateECDSA()
00638 {
00639 cout << "\nECDSA validation suite running...\n\n";
00640
00641
00642 GF2NT gf2n(191, 9, 0);
00643 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";
00644 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";
00645 EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24));
00646
00647 EC2N::Point P;
00648 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"
00649 "\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());
00650 Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H");
00651 Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH");
00652 EC2N::Point Q(ec.Multiply(d, P));
00653 ECDSA<EC2N, SHA>::Signer priv(ec, P, n, d);
00654 ECDSA<EC2N, SHA>::Verifier pub(priv);
00655
00656 Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH");
00657 Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H");
00658 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"
00659 "\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e";
00660 Integer r(sig, 24);
00661 Integer s(sig+24, 24);
00662
00663 Integer rOut, sOut;
00664 bool fail, pass=true;
00665
00666 priv.RawSign(k, h, rOut, sOut);
00667 fail = (rOut != r) || (sOut != s);
00668 pass = pass && !fail;
00669
00670 cout << (fail ? "FAILED " : "passed ");
00671 cout << "signature check against test vector\n";
00672
00673 fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig));
00674 pass = pass && !fail;
00675
00676 cout << (fail ? "FAILED " : "passed ");
00677 cout << "verification check against test vector\n";
00678
00679 fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig));
00680 pass = pass && !fail;
00681
00682 pass = SignatureValidate(priv, pub) && pass;
00683
00684 return pass;
00685 }
00686
00687 bool ValidateESIGN()
00688 {
00689 cout << "\nESIGN validation suite running...\n\n";
00690
00691 bool pass = true, fail;
00692
00693 const char *plain = "test";
00694 const byte *signature = (byte *)
00695 "\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"
00696 "\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"
00697 "\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"
00698 "\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"
00699 "\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";
00700
00701 FileSource keys(PACKAGE_DATA_DIR "TestData/esig1536.dat", true, new HexDecoder);
00702 ESIGN<SHA>::Signer signer(keys);
00703 ESIGN<SHA>::Verifier verifier(signer);
00704
00705 fail = !SignatureValidate(signer, verifier);
00706 pass = pass && !fail;
00707
00708 fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength());
00709 pass = pass && !fail;
00710
00711 cout << (fail ? "FAILED " : "passed ");
00712 cout << "verification check against test vector\n";
00713
00714 cout << "Generating signature key from seed..." << endl;
00715 signer.AccessKey().GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512));
00716 verifier = signer;
00717
00718 fail = !SignatureValidate(signer, verifier);
00719 pass = pass && !fail;
00720
00721 return pass;
00722 }