From b21162cf8e06f40baa1f58be6a8c17435cebc34d Mon Sep 17 00:00:00 2001 From: weidai Date: Fri, 4 Oct 2002 17:31:41 +0000 Subject: Initial revision git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- validat2.cpp | 740 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 740 insertions(+) create mode 100644 validat2.cpp (limited to 'validat2.cpp') diff --git a/validat2.cpp b/validat2.cpp new file mode 100644 index 0000000..783f7be --- /dev/null +++ b/validat2.cpp @@ -0,0 +1,740 @@ +// validat2.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#include "blumshub.h" +#include "rsa.h" +#include "md2.h" +#include "elgamal.h" +#include "nr.h" +#include "dsa.h" +#include "dh.h" +#include "mqv.h" +#include "luc.h" +#include "xtrcrypt.h" +#include "rabin.h" +#include "rw.h" +#include "eccrypto.h" +#include "ecp.h" +#include "ec2n.h" +#include "asn.h" +#include "rng.h" +#include "files.h" +#include "hex.h" +#include "oids.h" +#include "esign.h" +#include "osrng.h" + +#include +#include + +#include "validate.h" + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +class FixedRNG : public RandomNumberGenerator +{ +public: + FixedRNG(BufferedTransformation &source) : m_source(source) {} + + byte GenerateByte() + { + byte b; + m_source.Get(b); + return b; + } + +private: + BufferedTransformation &m_source; +}; + +bool ValidateBBS() +{ + cout << "\nBlumBlumShub validation suite running...\n\n"; + + Integer p("212004934506826557583707108431463840565872545889679278744389317666981496005411448865750399674653351"); + Integer q("100677295735404212434355574418077394581488455772477016953458064183204108039226017738610663984508231"); + Integer seed("63239752671357255800299643604761065219897634268887145610573595874544114193025997412441121667211431"); + BlumBlumShub bbs(p, q, seed); + bool pass = true, fail; + int j; + + const byte output1[] = { + 0x49,0xEA,0x2C,0xFD,0xB0,0x10,0x64,0xA0,0xBB,0xB9, + 0x2A,0xF1,0x01,0xDA,0xC1,0x8A,0x94,0xF7,0xB7,0xCE}; + const byte output2[] = { + 0x74,0x45,0x48,0xAE,0xAC,0xB7,0x0E,0xDF,0xAF,0xD7, + 0xD5,0x0E,0x8E,0x29,0x83,0x75,0x6B,0x27,0x46,0xA1}; + + byte buf[20]; + + bbs.GenerateBlock(buf, 20); + fail = memcmp(output1, buf, 20) != 0; + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + for (j=0;j<20;j++) + cout << setw(2) << setfill('0') << hex << (int)buf[j]; + cout << endl; + + bbs.Seek(10); + bbs.GenerateBlock(buf, 10); + fail = memcmp(output1+10, buf, 10) != 0; + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + for (j=0;j<10;j++) + cout << setw(2) << setfill('0') << hex << (int)buf[j]; + cout << endl; + + bbs.Seek(1234567); + bbs.GenerateBlock(buf, 20); + fail = memcmp(output2, buf, 20) != 0; + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + for (j=0;j<20;j++) + cout << setw(2) << setfill('0') << hex << (int)buf[j]; + cout << endl; + + return pass; +} + +bool SignatureValidate(PK_Signer &priv, PK_Verifier &pub, bool thorough = false) +{ + bool pass = true, fail; + + fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature key validation\n"; + + const byte *message = (byte *)"test message"; + const int messageLen = 12; + byte buffer[512]; + + memset(buffer, 0, sizeof(buffer)); + priv.SignMessage(GlobalRNG(), message, messageLen, buffer); + fail = !pub.VerifyMessage(message, messageLen, buffer); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature and verification\n"; + + ++buffer[0]; + fail = pub.VerifyMessage(message, messageLen, buffer); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "checking invalid signature" << endl; + + return pass; +} + +bool CryptoSystemValidate(PK_Decryptor &priv, PK_Encryptor &pub, bool thorough = false) +{ + bool pass = true, fail; + + fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "cryptosystem key validation\n"; + + const byte *message = (byte *)"test message"; + const int messageLen = 12; + SecByteBlock ciphertext(priv.CiphertextLength(messageLen)); + SecByteBlock plaintext(priv.MaxPlaintextLength(ciphertext.size())); + + pub.Encrypt(GlobalRNG(), message, messageLen, ciphertext); + fail = priv.Decrypt(ciphertext, priv.CiphertextLength(messageLen), plaintext) != DecodingResult(messageLen); + fail = fail || memcmp(message, plaintext, messageLen); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "encryption and decryption\n"; + + return pass; +} + +bool SimpleKeyAgreementValidate(SimpleKeyAgreementDomain &d) +{ + if (d.GetCryptoParameters().Validate(GlobalRNG(), 3)) + cout << "passed simple key agreement domain parameters validation" << endl; + else + { + cout << "FAILED simple key agreement domain parameters invalid" << endl; + return false; + } + + SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength()); + SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength()); + SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength()); + + d.GenerateKeyPair(GlobalRNG(), priv1, pub1); + d.GenerateKeyPair(GlobalRNG(), priv2, pub2); + + memset(val1.begin(), 0x10, val1.size()); + memset(val2.begin(), 0x11, val2.size()); + + if (!(d.Agree(val1, priv1, pub2) && d.Agree(val2, priv2, pub1))) + { + cout << "FAILED simple key agreement failed" << endl; + return false; + } + + if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength())) + { + cout << "FAILED simple agreed values not equal" << endl; + return false; + } + + cout << "passed simple key agreement" << endl; + return true; +} + +bool AuthenticatedKeyAgreementValidate(AuthenticatedKeyAgreementDomain &d) +{ + if (d.GetCryptoParameters().Validate(GlobalRNG(), 3)) + cout << "passed authenticated key agreement domain parameters validation" << endl; + else + { + cout << "FAILED authenticated key agreement domain parameters invalid" << endl; + return false; + } + + SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength()); + SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength()); + SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength()); + SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength()); + SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength()); + + d.GenerateStaticKeyPair(GlobalRNG(), spriv1, spub1); + d.GenerateStaticKeyPair(GlobalRNG(), spriv2, spub2); + d.GenerateEphemeralKeyPair(GlobalRNG(), epriv1, epub1); + d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2); + + memset(val1.begin(), 0x10, val1.size()); + memset(val2.begin(), 0x11, val2.size()); + + if (!(d.Agree(val1, spriv1, epriv1, spub2, epub2) && d.Agree(val2, spriv2, epriv2, spub1, epub1))) + { + cout << "FAILED authenticated key agreement failed" << endl; + return false; + } + + if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength())) + { + cout << "FAILED authenticated agreed values not equal" << endl; + return false; + } + + cout << "passed authenticated key agreement" << endl; + return true; +} + +bool ValidateRSA() +{ + cout << "\nRSA validation suite running...\n\n"; + + byte out[100], outPlain[100]; + bool pass = true, fail; + + { + char *plain = "Everyone gets Friday off."; + byte *signature = (byte *) + "\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84" + "\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21" + "\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b" + "\x5c\x77\xdf\xd9\xb1\x5b\xfc\x3d\x55\x93\x53\x50\x34\x10\xc1\xe1"; + + FileSource keys("rsa512a.dat", true, new HexDecoder); + RSASSA_PKCS1v15_MD2_Signer rsaPriv(keys); + RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv); + + rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out); + fail = memcmp(signature, out, 64) != 0; + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature check against test vector\n"; + + fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "verification check against test vector\n"; + + out[10]++; + fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "invalid signature verification\n"; + } + { + FileSource keys("rsa1024.dat", true, new HexDecoder); + RSAES_PKCS1v15_Decryptor rsaPriv(keys); + RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv); + + pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass; + } + { + byte *plain = (byte *) + "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; + byte *encrypted = (byte *) + "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a" + "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4" + "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52" + "\x62\x51"; + byte *oaepSeed = (byte *) + "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2" + "\xf0\x6c\xb5\x8f"; + ByteQueue bq; + bq.Put(oaepSeed, 20); + FixedRNG rng(bq); + + FileSource privFile("rsa400pv.dat", true, new HexDecoder); + FileSource pubFile("rsa400pb.dat", true, new HexDecoder); + RSAES_OAEP_SHA_Decryptor rsaPriv; + rsaPriv.AccessKey().BERDecodeKey(privFile); + RSAES_OAEP_SHA_Encryptor rsaPub(pubFile); + + memset(out, 0, 50); + memset(outPlain, 0, 8); + rsaPub.Encrypt(rng, plain, 8, out); + DecodingResult result = rsaPriv.FixedLengthDecrypt(encrypted, outPlain); + fail = !result.isValidCoding || (result.messageLength!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "PKCS 2.0 encryption and decryption\n"; + } + + return pass; +} + +bool ValidateDH() +{ + cout << "\nDH validation suite running...\n\n"; + + FileSource f("dh1024.dat", true, new HexDecoder()); + DH dh(f); + return SimpleKeyAgreementValidate(dh); +} + +bool ValidateMQV() +{ + cout << "\nMQV validation suite running...\n\n"; + + FileSource f("mqv1024.dat", true, new HexDecoder()); + MQV mqv(f); + return AuthenticatedKeyAgreementValidate(mqv); +} + +bool ValidateLUC_DH() +{ + cout << "\nLUC-DH validation suite running...\n\n"; + + FileSource f("lucd512.dat", true, new HexDecoder()); + LUC_DH dh(f); + return SimpleKeyAgreementValidate(dh); +} + +bool ValidateXTR_DH() +{ + cout << "\nXTR-DH validation suite running...\n\n"; + + FileSource f("xtrdh171.dat", true, new HexDecoder()); + XTR_DH dh(f); + return SimpleKeyAgreementValidate(dh); +} + +bool ValidateElGamal() +{ + cout << "\nElGamal validation suite running...\n\n"; + bool pass = true; + { + FileSource fc("elgc1024.dat", true, new HexDecoder); + ElGamalDecryptor privC(fc); + ElGamalEncryptor pubC(privC); + privC.AccessKey().Precompute(); + ByteQueue queue; + privC.AccessKey().SavePrecomputation(queue); + privC.AccessKey().LoadPrecomputation(queue); + + pass = CryptoSystemValidate(privC, pubC) && pass; + } + return pass; +} + +bool ValidateDLIES() +{ + cout << "\nDLIES validation suite running...\n\n"; + bool pass = true; + { + FileSource fc("dlie1024.dat", true, new HexDecoder); + DLIES<>::Decryptor privC(fc); + DLIES<>::Encryptor pubC(privC); + pass = CryptoSystemValidate(privC, pubC) && pass; + } + { + cout << "Generating new encryption key..." << endl; + DLIES<>::GroupParameters gp; + gp.GenerateRandomWithKeySize(GlobalRNG(), 128); + DLIES<>::Decryptor decryptor; + decryptor.AccessKey().GenerateRandom(GlobalRNG(), gp); + DLIES<>::Encryptor encryptor(decryptor); + + pass = CryptoSystemValidate(decryptor, encryptor) && pass; + } + return pass; +} + +bool ValidateNR() +{ + cout << "\nNR validation suite running...\n\n"; + bool pass = true; + { + FileSource f("nr2048.dat", true, new HexDecoder); + NR::Signer privS(f); + privS.AccessKey().Precompute(); + NR::Verifier pubS(privS); + + pass = SignatureValidate(privS, pubS) && pass; + } + { + cout << "Generating new signature key..." << endl; + NR::Signer privS(GlobalRNG(), 256); + NR::Verifier pubS(privS); + + pass = SignatureValidate(privS, pubS) && pass; + } + return pass; +} + +bool ValidateDSA(bool thorough) +{ + cout << "\nDSA validation suite running...\n\n"; + + bool pass = true, fail; + { + FileSource fs("dsa512.dat", true, new HexDecoder()); + GDSA::Signer priv(fs); + priv.AccessKey().Precompute(16); + GDSA::Verifier pub(priv); + + byte seed[]={0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, + 0x1b, 0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3}; + Integer k("358dad57 1462710f 50e254cf 1a376b2b deaadfbfh"); + Integer h("a9993e36 4706816a ba3e2571 7850c26c 9cd0d89dh"); + byte sig[]={0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43, 0x5c, 0xb7, 0x18, + 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3, 0x41, 0xc0, + 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf, 0x24, 0x58, 0xf4, + 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc, 0xd8, 0xc8}; + Integer r(sig, 20); + Integer s(sig+20, 20); + + Integer pGen, qGen, rOut, sOut; + int c; + + fail = !DSA::GeneratePrimes(seed, 160, c, pGen, 512, qGen); + fail = fail || (pGen != pub.GetKey().GetGroupParameters().GetModulus()) || (qGen != pub.GetKey().GetGroupParameters().GetSubgroupOrder()); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "prime generation test\n"; + + priv.GetDigestSignatureScheme().RawSign(k, h, rOut, sOut); + fail = (rOut != r) || (sOut != s); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature check against test vector\n"; + + fail = !pub.VerifyMessage((byte *)"abc", 3, sig); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "verification check against test vector\n"; + + fail = pub.VerifyMessage((byte *)"xyz", 3, sig); + pass = pass && !fail; + } + FileSource fs1("dsa1024.dat", true, new HexDecoder()); + DSA::Signer priv(fs1); + DSA::Verifier pub(priv); + FileSource fs2("dsa1024b.dat", true, new HexDecoder()); + DSA::Verifier pub1(fs2); + assert(pub.GetKey() == pub1.GetKey()); + pass = SignatureValidate(priv, pub, thorough) && pass; + return pass; +} + +bool ValidateLUC() +{ + cout << "\nLUC validation suite running...\n\n"; + bool pass=true; + + { + FileSource f("luc1024.dat", true, new HexDecoder); + LUCSSA_PKCS1v15_SHA_Signer priv(f); + LUCSSA_PKCS1v15_SHA_Verifier pub(priv); + pass = SignatureValidate(priv, pub) && pass; + } + { + LUCES_OAEP_SHA_Decryptor priv(GlobalRNG(), 512); + LUCES_OAEP_SHA_Encryptor pub(priv); + pass = CryptoSystemValidate(priv, pub) && pass; + } + return pass; +} + +bool ValidateLUC_DL() +{ + cout << "\nLUC-HMP validation suite running...\n\n"; + + FileSource f("lucs512.dat", true, new HexDecoder); + LUC_HMP::Signer privS(f); + LUC_HMP::Verifier pubS(privS); + bool pass = SignatureValidate(privS, pubS); + + cout << "\nLUC-IES validation suite running...\n\n"; + + FileSource fc("lucc512.dat", true, new HexDecoder); + LUC_IES<>::Decryptor privC(fc); + LUC_IES<>::Encryptor pubC(privC); + pass = CryptoSystemValidate(privC, pubC) && pass; + + return pass; +} + +bool ValidateRabin() +{ + cout << "\nRabin validation suite running...\n\n"; + bool pass=true; + + { + FileSource f("rabi1024.dat", true, new HexDecoder); + RabinPSSR::Signer priv(f); + RabinPSSR::Verifier pub(priv); + pass = SignatureValidate(priv, pub) && pass; + } + { + RabinES >::Decryptor priv(GlobalRNG(), 512); + RabinES >::Encryptor pub(priv); + pass = CryptoSystemValidate(priv, pub) && pass; + } + return pass; +} + +bool ValidateRW() +{ + cout << "\nRW validation suite running...\n\n"; + + FileSource f("rw1024.dat", true, new HexDecoder); + RWSSA::Signer priv(f); + RWSSA::Verifier pub(priv); + + return SignatureValidate(priv, pub); +} + +/* +bool ValidateBlumGoldwasser() +{ + cout << "\nBlumGoldwasser validation suite running...\n\n"; + + FileSource f("blum512.dat", true, new HexDecoder); + BlumGoldwasserPrivateKey priv(f); + BlumGoldwasserPublicKey pub(priv); + + return CryptoSystemValidate(priv, pub); +} +*/ + +bool ValidateECP() +{ + cout << "\nECP validation suite running...\n\n"; + + ECIES::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1()); + ECIES::Encryptor cpub(cpriv); + ByteQueue bq; + cpriv.GetKey().DEREncode(bq); + cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); + cpub.GetKey().DEREncode(bq); + ECDSA::Signer spriv(bq); + ECDSA::Verifier spub(bq); + ECDH::Domain ecdhc(ASN1::secp192r1()); + ECMQV::Domain ecmqvc(ASN1::secp192r1()); + + spriv.AccessKey().Precompute(); + ByteQueue queue; + spriv.AccessKey().SavePrecomputation(queue); + spriv.AccessKey().LoadPrecomputation(queue); + + bool pass = SignatureValidate(spriv, spub); + cpub.AccessKey().Precompute(); + cpriv.AccessKey().Precompute(); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + pass = SimpleKeyAgreementValidate(ecdhc) && pass; + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + + cout << "Turning on point compression..." << endl; + cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); + cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); + ecdhc.AccessGroupParameters().SetPointCompression(true); + ecmqvc.AccessGroupParameters().SetPointCompression(true); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + pass = SimpleKeyAgreementValidate(ecdhc) && pass; + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + + cout << "Testing SEC 2 recommended curves..." << endl; + OID oid; + while (!(oid = DL_GroupParameters_EC::GetNextRecommendedParametersOID(oid)).m_values.empty()) + { + DL_GroupParameters_EC params(oid); + bool fail = !params.Validate(GlobalRNG(), 2); + cout << (fail ? "FAILED" : "passed") << " " << dec << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl; + pass = pass && !fail; + } + + return pass; +} + +bool ValidateEC2N() +{ + cout << "\nEC2N validation suite running...\n\n"; + + ECIES::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1()); + ECIES::Encryptor cpub(cpriv); + ByteQueue bq; + cpriv.DEREncode(bq); + cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); + cpub.DEREncode(bq); + ECDSA::Signer spriv(bq); + ECDSA::Verifier spub(bq); + ECDH::Domain ecdhc(ASN1::sect193r1()); + ECMQV::Domain ecmqvc(ASN1::sect193r1()); + + spriv.AccessKey().Precompute(); + ByteQueue queue; + spriv.AccessKey().SavePrecomputation(queue); + spriv.AccessKey().LoadPrecomputation(queue); + + bool pass = SignatureValidate(spriv, spub); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + pass = SimpleKeyAgreementValidate(ecdhc) && pass; + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + + cout << "Turning on point compression..." << endl; + cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); + cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); + ecdhc.AccessGroupParameters().SetPointCompression(true); + ecmqvc.AccessGroupParameters().SetPointCompression(true); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + pass = SimpleKeyAgreementValidate(ecdhc) && pass; + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + +#if 0 // TODO: turn this back on when I make EC2N faster for pentanomial basis + cout << "Testing SEC 2 recommended curves..." << endl; + OID oid; + while (!(oid = ECParameters::GetNextRecommendedParametersOID(oid)).m_values.empty()) + { + ECParameters params(oid); + bool fail = !params.ValidateParameters(GlobalRNG()); + cout << (fail ? "FAILED" : "passed") << " " << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl; + pass = pass && !fail; + } +#endif + + return pass; +} + +bool ValidateECDSA() +{ + cout << "\nECDSA validation suite running...\n\n"; + + // from Sample Test Vectors for P1363 + GF2NT gf2n(191, 9, 0); + 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"; + 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"; + EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24)); + + EC2N::Point P; + 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" + "\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()); + Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H"); + Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH"); + EC2N::Point Q(ec.Multiply(d, P)); + ECDSA::Signer priv(ec, P, n, d); + ECDSA::Verifier pub(priv); + + Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH"); + Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H"); + 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" + "\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e"; + Integer r(sig, 24); + Integer s(sig+24, 24); + + Integer rOut, sOut; + bool fail, pass=true; + + priv.GetDigestSignatureScheme().RawSign(k, h, rOut, sOut); + fail = (rOut != r) || (sOut != s); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature check against test vector\n"; + + fail = !pub.VerifyMessage((byte *)"abc", 3, sig); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "verification check against test vector\n"; + + fail = pub.VerifyMessage((byte *)"xyz", 3, sig); + pass = pass && !fail; + + pass = SignatureValidate(priv, pub) && pass; + + return pass; +} + +bool ValidateESIGN() +{ + cout << "\nESIGN validation suite running...\n\n"; + + bool pass = true, fail; + + const char *plain = "test"; + const byte *signature = (byte *) + "\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" + "\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" + "\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" + "\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" + "\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"; + + FileSource keys("esig1536.dat", true, new HexDecoder); + ESIGN::Signer signer(keys); + ESIGN::Verifier verifier(signer); + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + + fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "verification check against test vector\n"; + + cout << "Generating signature key from seed..." << endl; + InvertibleESIGNFunction priv; + priv.GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512)); + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + + return pass; +} -- cgit v1.2.1