diff --git a/bench2.cpp b/bench2.cpp index 60bc9f9b..42159698 100644 --- a/bench2.cpp +++ b/bench2.cpp @@ -325,15 +325,15 @@ void BenchmarkAll2(double t, double hertz) BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/mqv2048.dat", "MQV 2048", t); #if 0 - BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/hmqv160.dat", "HMQV P-160", t); - BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/hmqv256.dat", "HMQV P-256", t); - BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/hmqv384.dat", "HMQV P-384", t); - BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/hmqv512.dat", "HMQV P-512", t); + BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/hmqv160.dat", "HMQV P-160", t); + BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/hmqv256.dat", "HMQV P-256", t); + BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/hmqv384.dat", "HMQV P-384", t); + BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/hmqv512.dat", "HMQV P-512", t); - BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/fhmqv160.dat", "FHMQV P-160", t); - BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/fhmqv256.dat", "FHMQV P-256", t); - BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/fhmqv384.dat", "FHMQV P-384", t); - BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/fhmqv512.dat", "FHMQV P-512", t); + BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/fhmqv160.dat", "FHMQV P-160", t); + BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/fhmqv256.dat", "FHMQV P-256", t); + BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/fhmqv384.dat", "FHMQV P-384", t); + BenchMarkKeyAgreement(CRYPTOPP_DATA_DIR "TestData/fhmqv512.dat", "FHMQV P-512", t); #endif cout << "\n"; diff --git a/eccrypto.h b/eccrypto.h index ae4ad227..41aa5b51 100644 --- a/eccrypto.h +++ b/eccrypto.h @@ -219,38 +219,38 @@ struct ECMQV //! \details This implementation follows Hugo Krawczyk's HMQV: A High-Performance //! Secure Diffie-Hellman Protocol. Note: this implements HMQV only. HMQV-C with Key Confirmation is not provided. template ::DefaultCofactorOption, class HASH = SHA256> -struct HMQV +struct ECHMQV { typedef HMQV_Domain, COFACTOR_OPTION, HASH> Domain; #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~HMQV() {} + virtual ~ECHMQV() {} #endif }; -typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain HMQV160; -typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain HMQV256; -typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain HMQV384; -typedef HMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain HMQV512; +typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain ECHMQV160; +typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain ECHMQV256; +typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain ECHMQV384; +typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain ECHMQV512; //! \brief Fully Hashed Menezes-Qu-Vanstone in ECP or EC2N //! \details This implementation follows Augustin P. Sarr and Philippe Elbaz–Vincent, and Jean–Claude Bajard's //! A Secure and Efficient Authenticated Diffie-Hellman Protocol. //! Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. template ::DefaultCofactorOption, class HASH = SHA256> -struct FHMQV +struct ECFHMQV { typedef FHMQV_Domain, COFACTOR_OPTION, HASH> Domain; #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~FHMQV() {} + virtual ~ECFHMQV() {} #endif }; -typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain FHMQV160; -typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain FHMQV256; -typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain FHMQV384; -typedef FHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain FHMQV512; +typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain ECFHMQV160; +typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain ECFHMQV256; +typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain ECFHMQV384; +typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain ECFHMQV512; //! EC keys template diff --git a/hmqv.h b/hmqv.h index fd728b84..87866e1b 100644 --- a/hmqv.h +++ b/hmqv.h @@ -300,7 +300,7 @@ private: //! \brief Hashed Menezes-Qu-Vanstone in GF(p) //! \details This implementation follows Hugo Krawczyk's HMQV: A High-Performance //! Secure Diffie-Hellman Protocol. Note: this implements HMQV only. HMQV-C with Key Confirmation is not provided. -typedef HMQV_Domain HMQV_GFP; +typedef HMQV_Domain HMQV; NAMESPACE_END diff --git a/validat2.cpp b/validat2.cpp index ec553a28..c13a8638 100644 --- a/validat2.cpp +++ b/validat2.cpp @@ -386,239 +386,239 @@ bool ValidateMQV() return AuthenticatedKeyAgreementValidate(mqv); } -bool ValidateHMQV() -{ - std::cout << "\nHMQV validation suite running...\n\n"; - - //HMQV< ECP >::Domain hmqvB(false /*server*/); - HMQV256 hmqvB(false); - FileSource f256("TestData/hmqv256.dat", true, new HexDecoder()); - FileSource f384("TestData/hmqv384.dat", true, new HexDecoder()); - FileSource f512("TestData/hmqv512.dat", true, new HexDecoder()); - hmqvB.AccessGroupParameters().BERDecode(f256); - - std::cout << "HMQV with NIST P-256 and SHA-256:" << std::endl; - - if (hmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; - } - - const OID oid = ASN1::secp256r1(); - HMQV< ECP >::Domain hmqvA(oid, true /*client*/); - - if (hmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; - } - - SecByteBlock sprivA(hmqvA.StaticPrivateKeyLength()), sprivB(hmqvB.StaticPrivateKeyLength()); - SecByteBlock eprivA(hmqvA.EphemeralPrivateKeyLength()), eprivB(hmqvB.EphemeralPrivateKeyLength()); - SecByteBlock spubA(hmqvA.StaticPublicKeyLength()), spubB(hmqvB.StaticPublicKeyLength()); - SecByteBlock epubA(hmqvA.EphemeralPublicKeyLength()), epubB(hmqvB.EphemeralPublicKeyLength()); - SecByteBlock valA(hmqvA.AgreedValueLength()), valB(hmqvB.AgreedValueLength()); - - hmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); - hmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); - hmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); - hmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); - - memset(valA.begin(), 0x00, valA.size()); - memset(valB.begin(), 0x11, valB.size()); - - if (!(hmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && hmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) - { - std::cout << "FAILED authenticated key agreement failed" << std::endl; - return false; - } - - if (memcmp(valA.begin(), valB.begin(), hmqvA.AgreedValueLength())) - { - std::cout << "FAILED authenticated agreed values not equal" << std::endl; - return false; - } - - std::cout << "passed authenticated key agreement" << std::endl; - - // Now test HMQV with NIST P-384 curve and SHA384 hash - std::cout << endl; - std::cout << "HMQV with NIST P-384 and SHA-384:" << std::endl; - - HMQV384 hmqvB384(false); - hmqvB384.AccessGroupParameters().BERDecode(f384); - - if (hmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; - } - - const OID oid384 = ASN1::secp384r1(); - HMQV384 hmqvA384(oid384, true /*client*/); - - if (hmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; - } - - SecByteBlock sprivA384(hmqvA384.StaticPrivateKeyLength()), sprivB384(hmqvB384.StaticPrivateKeyLength()); - SecByteBlock eprivA384(hmqvA384.EphemeralPrivateKeyLength()), eprivB384(hmqvB384.EphemeralPrivateKeyLength()); - SecByteBlock spubA384(hmqvA384.StaticPublicKeyLength()), spubB384(hmqvB384.StaticPublicKeyLength()); - SecByteBlock epubA384(hmqvA384.EphemeralPublicKeyLength()), epubB384(hmqvB384.EphemeralPublicKeyLength()); - SecByteBlock valA384(hmqvA384.AgreedValueLength()), valB384(hmqvB384.AgreedValueLength()); - - hmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); - hmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); - hmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); - hmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); - - memset(valA384.begin(), 0x00, valA384.size()); - memset(valB384.begin(), 0x11, valB384.size()); - - if (!(hmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && hmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) - { - std::cout << "FAILED authenticated key agreement failed" << std::endl; - return false; - } - - if (memcmp(valA384.begin(), valB384.begin(), hmqvA384.AgreedValueLength())) - { - std::cout << "FAILED authenticated agreed values not equal" << std::endl; - return false; - } - - std::cout << "passed authenticated key agreement" << std::endl; - - return true; -} - -bool ValidateFHMQV() -{ - std::cout << "\nFHMQV validation suite running...\n\n"; - - //FHMQV< ECP >::Domain fhmqvB(false /*server*/); - FHMQV256 fhmqvB(false); - FileSource f256("TestData/fhmqv256.dat", true, new HexDecoder()); - FileSource f384("TestData/fhmqv384.dat", true, new HexDecoder()); - FileSource f512("TestData/fhmqv512.dat", true, new HexDecoder()); - fhmqvB.AccessGroupParameters().BERDecode(f256); - - std::cout << "FHMQV with NIST P-256 and SHA-256:" << std::endl; - - if (fhmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; - } - - const OID oid = ASN1::secp256r1(); - FHMQV< ECP >::Domain fhmqvA(oid, true /*client*/); - - if (fhmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; - } - - SecByteBlock sprivA(fhmqvA.StaticPrivateKeyLength()), sprivB(fhmqvB.StaticPrivateKeyLength()); - SecByteBlock eprivA(fhmqvA.EphemeralPrivateKeyLength()), eprivB(fhmqvB.EphemeralPrivateKeyLength()); - SecByteBlock spubA(fhmqvA.StaticPublicKeyLength()), spubB(fhmqvB.StaticPublicKeyLength()); - SecByteBlock epubA(fhmqvA.EphemeralPublicKeyLength()), epubB(fhmqvB.EphemeralPublicKeyLength()); - SecByteBlock valA(fhmqvA.AgreedValueLength()), valB(fhmqvB.AgreedValueLength()); - - fhmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); - fhmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); - fhmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); - fhmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); - - memset(valA.begin(), 0x00, valA.size()); - memset(valB.begin(), 0x11, valB.size()); - - if (!(fhmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && fhmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) - { - std::cout << "FAILED authenticated key agreement failed" << std::endl; - return false; - } - - if (memcmp(valA.begin(), valB.begin(), fhmqvA.AgreedValueLength())) - { - std::cout << "FAILED authenticated agreed values not equal" << std::endl; - return false; - } - - std::cout << "passed authenticated key agreement" << std::endl; - - // Now test FHMQV with NIST P-384 curve and SHA384 hash - std::cout << endl; - std::cout << "FHMQV with NIST P-384 and SHA-384:" << std::endl; - - FHMQV384 fhmqvB384(false); - fhmqvB384.AccessGroupParameters().BERDecode(f384); - - if (fhmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; - return false; - } - - const OID oid384 = ASN1::secp384r1(); - FHMQV384 fhmqvA384(oid384, true /*client*/); - - if (fhmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) - std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; - else - { - std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; - return false; - } - - SecByteBlock sprivA384(fhmqvA384.StaticPrivateKeyLength()), sprivB384(fhmqvB384.StaticPrivateKeyLength()); - SecByteBlock eprivA384(fhmqvA384.EphemeralPrivateKeyLength()), eprivB384(fhmqvB384.EphemeralPrivateKeyLength()); - SecByteBlock spubA384(fhmqvA384.StaticPublicKeyLength()), spubB384(fhmqvB384.StaticPublicKeyLength()); - SecByteBlock epubA384(fhmqvA384.EphemeralPublicKeyLength()), epubB384(fhmqvB384.EphemeralPublicKeyLength()); - SecByteBlock valA384(fhmqvA384.AgreedValueLength()), valB384(fhmqvB384.AgreedValueLength()); - - fhmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); - fhmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); - fhmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); - fhmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); - - memset(valA384.begin(), 0x00, valA384.size()); - memset(valB384.begin(), 0x11, valB384.size()); - - if (!(fhmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && fhmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) - { - std::cout << "FAILED authenticated key agreement failed" << std::endl; - return false; - } - - if (memcmp(valA384.begin(), valB384.begin(), fhmqvA384.AgreedValueLength())) - { - std::cout << "FAILED authenticated agreed values not equal" << std::endl; - return false; - } - - std::cout << "passed authenticated key agreement" << std::endl; - - return true; -} +bool ValidateHMQV() +{ + std::cout << "\nHMQV validation suite running...\n\n"; + + //ECHMQV< ECP >::Domain hmqvB(false /*server*/); + ECHMQV256 hmqvB(false); + FileSource f256("TestData/hmqv256.dat", true, new HexDecoder()); + FileSource f384("TestData/hmqv384.dat", true, new HexDecoder()); + FileSource f512("TestData/hmqv512.dat", true, new HexDecoder()); + hmqvB.AccessGroupParameters().BERDecode(f256); + + std::cout << "HMQV with NIST P-256 and SHA-256:" << std::endl; + + if (hmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid = ASN1::secp256r1(); + ECHMQV< ECP >::Domain hmqvA(oid, true /*client*/); + + if (hmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA(hmqvA.StaticPrivateKeyLength()), sprivB(hmqvB.StaticPrivateKeyLength()); + SecByteBlock eprivA(hmqvA.EphemeralPrivateKeyLength()), eprivB(hmqvB.EphemeralPrivateKeyLength()); + SecByteBlock spubA(hmqvA.StaticPublicKeyLength()), spubB(hmqvB.StaticPublicKeyLength()); + SecByteBlock epubA(hmqvA.EphemeralPublicKeyLength()), epubB(hmqvB.EphemeralPublicKeyLength()); + SecByteBlock valA(hmqvA.AgreedValueLength()), valB(hmqvB.AgreedValueLength()); + + hmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); + hmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); + hmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); + hmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); + + memset(valA.begin(), 0x00, valA.size()); + memset(valB.begin(), 0x11, valB.size()); + + if (!(hmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && hmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA.begin(), valB.begin(), hmqvA.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + // Now test HMQV with NIST P-384 curve and SHA384 hash + std::cout << endl; + std::cout << "HMQV with NIST P-384 and SHA-384:" << std::endl; + + ECHMQV384 hmqvB384(false); + hmqvB384.AccessGroupParameters().BERDecode(f384); + + if (hmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid384 = ASN1::secp384r1(); + ECHMQV384 hmqvA384(oid384, true /*client*/); + + if (hmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA384(hmqvA384.StaticPrivateKeyLength()), sprivB384(hmqvB384.StaticPrivateKeyLength()); + SecByteBlock eprivA384(hmqvA384.EphemeralPrivateKeyLength()), eprivB384(hmqvB384.EphemeralPrivateKeyLength()); + SecByteBlock spubA384(hmqvA384.StaticPublicKeyLength()), spubB384(hmqvB384.StaticPublicKeyLength()); + SecByteBlock epubA384(hmqvA384.EphemeralPublicKeyLength()), epubB384(hmqvB384.EphemeralPublicKeyLength()); + SecByteBlock valA384(hmqvA384.AgreedValueLength()), valB384(hmqvB384.AgreedValueLength()); + + hmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); + hmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); + hmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); + hmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); + + memset(valA384.begin(), 0x00, valA384.size()); + memset(valB384.begin(), 0x11, valB384.size()); + + if (!(hmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && hmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA384.begin(), valB384.begin(), hmqvA384.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + return true; +} + +bool ValidateFHMQV() +{ + std::cout << "\nFHMQV validation suite running...\n\n"; + + //ECFHMQV< ECP >::Domain fhmqvB(false /*server*/); + ECFHMQV256 fhmqvB(false); + FileSource f256("TestData/fhmqv256.dat", true, new HexDecoder()); + FileSource f384("TestData/fhmqv384.dat", true, new HexDecoder()); + FileSource f512("TestData/fhmqv512.dat", true, new HexDecoder()); + fhmqvB.AccessGroupParameters().BERDecode(f256); + + std::cout << "FHMQV with NIST P-256 and SHA-256:" << std::endl; + + if (fhmqvB.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid = ASN1::secp256r1(); + ECFHMQV< ECP >::Domain fhmqvA(oid, true /*client*/); + + if (fhmqvA.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA(fhmqvA.StaticPrivateKeyLength()), sprivB(fhmqvB.StaticPrivateKeyLength()); + SecByteBlock eprivA(fhmqvA.EphemeralPrivateKeyLength()), eprivB(fhmqvB.EphemeralPrivateKeyLength()); + SecByteBlock spubA(fhmqvA.StaticPublicKeyLength()), spubB(fhmqvB.StaticPublicKeyLength()); + SecByteBlock epubA(fhmqvA.EphemeralPublicKeyLength()), epubB(fhmqvB.EphemeralPublicKeyLength()); + SecByteBlock valA(fhmqvA.AgreedValueLength()), valB(fhmqvB.AgreedValueLength()); + + fhmqvA.GenerateStaticKeyPair(GlobalRNG(), sprivA, spubA); + fhmqvB.GenerateStaticKeyPair(GlobalRNG(), sprivB, spubB); + fhmqvA.GenerateEphemeralKeyPair(GlobalRNG(), eprivA, epubA); + fhmqvB.GenerateEphemeralKeyPair(GlobalRNG(), eprivB, epubB); + + memset(valA.begin(), 0x00, valA.size()); + memset(valB.begin(), 0x11, valB.size()); + + if (!(fhmqvA.Agree(valA, sprivA, eprivA, spubB, epubB) && fhmqvB.Agree(valB, sprivB, eprivB, spubA, epubA))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA.begin(), valB.begin(), fhmqvA.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + // Now test FHMQV with NIST P-384 curve and SHA384 hash + std::cout << endl; + std::cout << "FHMQV with NIST P-384 and SHA-384:" << std::endl; + + ECHMQV384 fhmqvB384(false); + fhmqvB384.AccessGroupParameters().BERDecode(f384); + + if (fhmqvB384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (server)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (server)" << std::endl; + return false; + } + + const OID oid384 = ASN1::secp384r1(); + ECHMQV384 fhmqvA384(oid384, true /*client*/); + + if (fhmqvA384.GetCryptoParameters().Validate(GlobalRNG(), 3)) + std::cout << "passed authenticated key agreement domain parameters validation (client)" << std::endl; + else + { + std::cout << "FAILED authenticated key agreement domain parameters invalid (client)" << std::endl; + return false; + } + + SecByteBlock sprivA384(fhmqvA384.StaticPrivateKeyLength()), sprivB384(fhmqvB384.StaticPrivateKeyLength()); + SecByteBlock eprivA384(fhmqvA384.EphemeralPrivateKeyLength()), eprivB384(fhmqvB384.EphemeralPrivateKeyLength()); + SecByteBlock spubA384(fhmqvA384.StaticPublicKeyLength()), spubB384(fhmqvB384.StaticPublicKeyLength()); + SecByteBlock epubA384(fhmqvA384.EphemeralPublicKeyLength()), epubB384(fhmqvB384.EphemeralPublicKeyLength()); + SecByteBlock valA384(fhmqvA384.AgreedValueLength()), valB384(fhmqvB384.AgreedValueLength()); + + fhmqvA384.GenerateStaticKeyPair(GlobalRNG(), sprivA384, spubA384); + fhmqvB384.GenerateStaticKeyPair(GlobalRNG(), sprivB384, spubB384); + fhmqvA384.GenerateEphemeralKeyPair(GlobalRNG(), eprivA384, epubA384); + fhmqvB384.GenerateEphemeralKeyPair(GlobalRNG(), eprivB384, epubB384); + + memset(valA384.begin(), 0x00, valA384.size()); + memset(valB384.begin(), 0x11, valB384.size()); + + if (!(fhmqvA384.Agree(valA384, sprivA384, eprivA384, spubB384, epubB384) && fhmqvB384.Agree(valB384, sprivB384, eprivB384, spubA384, epubA384))) + { + std::cout << "FAILED authenticated key agreement failed" << std::endl; + return false; + } + + if (memcmp(valA384.begin(), valB384.begin(), fhmqvA384.AgreedValueLength())) + { + std::cout << "FAILED authenticated agreed values not equal" << std::endl; + return false; + } + + std::cout << "passed authenticated key agreement" << std::endl; + + return true; +} bool ValidateLUC_DH() {