From e9b11b8e08e274ffa80ce2e921ca46b0ec6237f4 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Wed, 13 Jul 2016 15:47:58 -0400 Subject: [PATCH] Whitespace --- fhmqv.cpp | 28 +-- fhmqv.h | 588 ++++++++++++++++++++++++++-------------------------- hmqv.cpp | 28 +-- hmqv.h | 606 +++++++++++++++++++++++++++--------------------------- mqv.h | 8 +- 5 files changed, 629 insertions(+), 629 deletions(-) diff --git a/fhmqv.cpp b/fhmqv.cpp index e6403d49..ee6046c0 100644 --- a/fhmqv.cpp +++ b/fhmqv.cpp @@ -1,14 +1,14 @@ -// fhmqv.cpp - written and placed in the public domain by Jeffrey Walton -// Shamelessly based upon Wei Dai's MQV source files - -#include "pch.h" -#include "fhmqv.h" - -NAMESPACE_BEGIN(CryptoPP) - -void TestInstantiations_FHMQV() -{ - FullyHashedMQV fhmqv; -} - -NAMESPACE_END +// fhmqv.cpp - written and placed in the public domain by Jeffrey Walton +// Shamelessly based upon Wei Dai's MQV source files + +#include "pch.h" +#include "fhmqv.h" + +NAMESPACE_BEGIN(CryptoPP) + +void TestInstantiations_FHMQV() +{ + FullyHashedMQV fhmqv; +} + +NAMESPACE_END diff --git a/fhmqv.h b/fhmqv.h index 8bec5405..d777c342 100644 --- a/fhmqv.h +++ b/fhmqv.h @@ -1,294 +1,294 @@ -// fhmqv.h - written and placed in the public domain by Jeffrey Walton -// Shamelessly based upon Wei Dai's MQV source files - -#ifndef CRYPTOPP_FHMQV_H -#define CRYPTOPP_FHMQV_H - -/** \file -*/ - -#include "gfpcrypt.h" -#include "algebra.h" -#include "sha.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, -/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol - Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. -*/ -template -class FHMQV_Domain: public AuthenticatedKeyAgreementDomain -{ -public: - typedef GROUP_PARAMETERS GroupParameters; - typedef typename GroupParameters::Element Element; - typedef FHMQV_Domain Domain; - - FHMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} - - FHMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} - - FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.BERDecode(bt);} - - template - FHMQV_Domain(T1 v1, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1);} - - template - FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2);} - - template - FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2, v3);} - - template - FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2, v3, v4);} - -protected: - - inline void Hash(const Element* sigma, - const byte* e1, size_t e1len, const byte* e2, size_t e2len, - const byte* s1, size_t s1len, const byte* s2, size_t s2len, - byte* digest, size_t dlen) const - { - HASH hash; - size_t idx = 0, req = dlen; - size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE); - - if(sigma) - { - Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); - SecByteBlock sbb(x.MinEncodedSize()); - x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); - hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); - } - - hash.Update(e1, e1len); - hash.Update(e2, e2len); - hash.Update(s1, s1len); - hash.Update(s2, s2len); - - hash.TruncatedFinal(digest, blk); - req -= blk; - - // All this to catch tail bytes for large curves and small hashes - while(req != 0) - { - hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); - - idx += (size_t)HASH::DIGESTSIZE; - blk = std::min(req, (size_t)HASH::DIGESTSIZE); - hash.TruncatedFinal(&digest[idx], blk); - - req -= blk; - } - } - -public: - - const GroupParameters & GetGroupParameters() const {return m_groupParameters;} - GroupParameters & AccessGroupParameters(){return m_groupParameters;} - - CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();} - - //! return length of agreed value produced - unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} - //! return length of static private keys in this domain - unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} - //! return length of static public keys in this domain - unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} - - //! generate static private key - /*! \pre size of privateKey == PrivateStaticKeyLength() */ - void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); - x.Encode(privateKey, StaticPrivateKeyLength()); - } - - //! generate static public key - /*! \pre size of publicKey == PublicStaticKeyLength() */ - void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - Integer x(privateKey, StaticPrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, publicKey); - } - - unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} - unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} - - //! return length of ephemeral private keys in this domain - void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - Integer x(rng, Integer::One(), params.GetMaxExponent()); - x.Encode(privateKey, StaticPrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); - } - - //! return length of ephemeral public keys in this domain - void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); - } - - //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure - /*! \note The ephemeral public key will always be validated. - If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. - \pre size of agreedValue == AgreedValueLength() - \pre length of staticPrivateKey == StaticPrivateKeyLength() - \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() - \pre length of staticOtherPublicKey == StaticPublicKeyLength() - \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() - */ - bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey=true) const - { - byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL; - size_t xxs = 0, yys = 0, aas = 0, bbs = 0; - - // Depending on the role, this will hold either A's or B's static - // (long term) public key. AA or BB will then point into tt. - SecByteBlock tt(StaticPublicKeyLength()); - - try - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - - if(m_role == RoleServer) - { - Integer b(staticPrivateKey, StaticPrivateKeyLength()); - Element B = params.ExponentiateBase(b); - params.EncodeElement(true, B, tt); - - XX = const_cast(ephemeralOtherPublicKey); - xxs = EphemeralPublicKeyLength(); - YY = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); - yys = EphemeralPublicKeyLength(); - AA = const_cast(staticOtherPublicKey); - aas = StaticPublicKeyLength(); - BB = tt.BytePtr(); - bbs = tt.SizeInBytes(); - } - else if(m_role == RoleClient) - { - Integer a(staticPrivateKey, StaticPrivateKeyLength()); - Element A = params.ExponentiateBase(a); - params.EncodeElement(true, A, tt); - - XX = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); - xxs = EphemeralPublicKeyLength(); - YY = const_cast(ephemeralOtherPublicKey); - yys = EphemeralPublicKeyLength(); - AA = tt.BytePtr(); - aas = tt.SizeInBytes(); - BB = const_cast(staticOtherPublicKey); - bbs = StaticPublicKeyLength(); - } - else - { - assert(0); - return false; - } - - // DecodeElement calls ValidateElement at level 1. Level 1 only calls - // VerifyPoint to ensure the element is in G*. If the other's PublicKey is - // requested to be validated, we manually call ValidateElement at level 3. - Element VV1 = params.DecodeElement(staticOtherPublicKey, false); - if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL)) - return false; - - // DecodeElement calls ValidateElement at level 1. Level 1 only calls - // VerifyPoint to ensure the element is in G*. Crank it up. - Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false); - if(!params.ValidateElement(3, VV2, NULL)) - return false; - - const Integer& p = params.GetGroupOrder(); - const Integer& q = params.GetSubgroupOrder(); - const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); - - Integer d, e; - SecByteBlock dd(len), ee(len); - - Hash(NULL, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); - d.Decode(dd.BytePtr(), dd.SizeInBytes()); - - Hash(NULL, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes()); - e.Decode(ee.BytePtr(), ee.SizeInBytes()); - - Element sigma; - if(m_role == RoleServer) - { - Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); - Integer b(staticPrivateKey, StaticPrivateKeyLength()); - Integer s_B = (y + e * b) % q; - - Element A = params.DecodeElement(AA, false); - Element X = params.DecodeElement(XX, false); - - Element t1 = params.ExponentiateElement(A, d); - Element t2 = m_groupParameters.MultiplyElements(X, t1); - - sigma = params.ExponentiateElement(t2, s_B); - } - else - { - Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); - Integer a(staticPrivateKey, StaticPrivateKeyLength()); - Integer s_A = (x + d * a) % q; - - Element B = params.DecodeElement(BB, false); - Element Y = params.DecodeElement(YY, false); - - Element t1 = params.ExponentiateElement(B, e); - Element t2 = m_groupParameters.MultiplyElements(Y, t1); - - sigma = params.ExponentiateElement(t2, s_A); - } - - Hash(&sigma, XX, xxs, YY, yys, AA, aas, BB, bbs, agreedValue, AgreedValueLength()); - } - catch (DL_BadElement &) - { - return false; - } - return true; - } - -private: - - // The paper uses Initiator and Recipient - make it classical. - enum KeyAgreementRole{ RoleServer = 1, RoleClient }; - - DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} - const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} - - KeyAgreementRole m_role; - GroupParameters m_groupParameters; -}; - -//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, -/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol - Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. -*/ -typedef FHMQV_Domain FullyHashedMQV; - -NAMESPACE_END - -#endif +// fhmqv.h - written and placed in the public domain by Jeffrey Walton +// Shamelessly based upon Wei Dai's MQV source files + +#ifndef CRYPTOPP_FHMQV_H +#define CRYPTOPP_FHMQV_H + +/** \file +*/ + +#include "gfpcrypt.h" +#include "algebra.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol + Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +*/ +template +class FHMQV_Domain: public AuthenticatedKeyAgreementDomain +{ +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef FHMQV_Domain Domain; + + FHMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} + + FHMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} + + FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.BERDecode(bt);} + + template + FHMQV_Domain(T1 v1, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1);} + + template + FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2);} + + template + FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3);} + + template + FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + +protected: + + inline void Hash(const Element* sigma, + const byte* e1, size_t e1len, const byte* e2, size_t e2len, + const byte* s1, size_t s1len, const byte* s2, size_t s2len, + byte* digest, size_t dlen) const + { + HASH hash; + size_t idx = 0, req = dlen; + size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE); + + if(sigma) + { + Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); + SecByteBlock sbb(x.MinEncodedSize()); + x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); + hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); + } + + hash.Update(e1, e1len); + hash.Update(e2, e2len); + hash.Update(s1, s1len); + hash.Update(s2, s2len); + + hash.TruncatedFinal(digest, blk); + req -= blk; + + // All this to catch tail bytes for large curves and small hashes + while(req != 0) + { + hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); + + idx += (size_t)HASH::DIGESTSIZE; + blk = std::min(req, (size_t)HASH::DIGESTSIZE); + hash.TruncatedFinal(&digest[idx], blk); + + req -= blk; + } + } + +public: + + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + GroupParameters & AccessGroupParameters(){return m_groupParameters;} + + CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();} + + //! return length of agreed value produced + unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + //! return length of static private keys in this domain + unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + //! return length of static public keys in this domain + unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + //! generate static private key + /*! \pre size of privateKey == PrivateStaticKeyLength() */ + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + } + + //! generate static public key + /*! \pre size of publicKey == PublicStaticKeyLength() */ + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} + unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} + + //! return length of ephemeral private keys in this domain + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(rng, Integer::One(), params.GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); + } + + //! return length of ephemeral public keys in this domain + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); + } + + //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure + /*! \note The ephemeral public key will always be validated. + If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. + \pre size of agreedValue == AgreedValueLength() + \pre length of staticPrivateKey == StaticPrivateKeyLength() + \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() + \pre length of staticOtherPublicKey == StaticPublicKeyLength() + \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() + */ + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const + { + byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL; + size_t xxs = 0, yys = 0, aas = 0, bbs = 0; + + // Depending on the role, this will hold either A's or B's static + // (long term) public key. AA or BB will then point into tt. + SecByteBlock tt(StaticPublicKeyLength()); + + try + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + + if(m_role == RoleServer) + { + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Element B = params.ExponentiateBase(b); + params.EncodeElement(true, B, tt); + + XX = const_cast(ephemeralOtherPublicKey); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + yys = EphemeralPublicKeyLength(); + AA = const_cast(staticOtherPublicKey); + aas = StaticPublicKeyLength(); + BB = tt.BytePtr(); + bbs = tt.SizeInBytes(); + } + else if(m_role == RoleClient) + { + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Element A = params.ExponentiateBase(a); + params.EncodeElement(true, A, tt); + + XX = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralOtherPublicKey); + yys = EphemeralPublicKeyLength(); + AA = tt.BytePtr(); + aas = tt.SizeInBytes(); + BB = const_cast(staticOtherPublicKey); + bbs = StaticPublicKeyLength(); + } + else + { + assert(0); + return false; + } + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. If the other's PublicKey is + // requested to be validated, we manually call ValidateElement at level 3. + Element VV1 = params.DecodeElement(staticOtherPublicKey, false); + if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL)) + return false; + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. Crank it up. + Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false); + if(!params.ValidateElement(3, VV2, NULL)) + return false; + + const Integer& p = params.GetGroupOrder(); + const Integer& q = params.GetSubgroupOrder(); + const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); + + Integer d, e; + SecByteBlock dd(len), ee(len); + + Hash(NULL, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); + d.Decode(dd.BytePtr(), dd.SizeInBytes()); + + Hash(NULL, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes()); + e.Decode(ee.BytePtr(), ee.SizeInBytes()); + + Element sigma; + if(m_role == RoleServer) + { + Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_B = (y + e * b) % q; + + Element A = params.DecodeElement(AA, false); + Element X = params.DecodeElement(XX, false); + + Element t1 = params.ExponentiateElement(A, d); + Element t2 = m_groupParameters.MultiplyElements(X, t1); + + sigma = params.ExponentiateElement(t2, s_B); + } + else + { + Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_A = (x + d * a) % q; + + Element B = params.DecodeElement(BB, false); + Element Y = params.DecodeElement(YY, false); + + Element t1 = params.ExponentiateElement(B, e); + Element t2 = m_groupParameters.MultiplyElements(Y, t1); + + sigma = params.ExponentiateElement(t2, s_A); + } + + Hash(&sigma, XX, xxs, YY, yys, AA, aas, BB, bbs, agreedValue, AgreedValueLength()); + } + catch (DL_BadElement &) + { + return false; + } + return true; + } + +private: + + // The paper uses Initiator and Recipient - make it classical. + enum KeyAgreementRole{ RoleServer = 1, RoleClient }; + + DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} + const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} + + KeyAgreementRole m_role; + GroupParameters m_groupParameters; +}; + +//! Fully Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! A Secure and Efficient Authenticated Diffie–Hellman Protocol + Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. +*/ +typedef FHMQV_Domain FullyHashedMQV; + +NAMESPACE_END + +#endif diff --git a/hmqv.cpp b/hmqv.cpp index 86a8f97d..41e9dad6 100644 --- a/hmqv.cpp +++ b/hmqv.cpp @@ -1,14 +1,14 @@ -// hmqv.cpp - written and placed in the public domain by Uri Blumenthal -// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files - -#include "pch.h" -#include "hmqv.h" - -NAMESPACE_BEGIN(CryptoPP) - -void TestInstantiations_HMQV() -{ - HashedMQV hmqv; -} - -NAMESPACE_END +// hmqv.cpp - written and placed in the public domain by Uri Blumenthal +// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files + +#include "pch.h" +#include "hmqv.h" + +NAMESPACE_BEGIN(CryptoPP) + +void TestInstantiations_HMQV() +{ + HashedMQV hmqv; +} + +NAMESPACE_END diff --git a/hmqv.h b/hmqv.h index 241d4c66..d2c692a8 100644 --- a/hmqv.h +++ b/hmqv.h @@ -1,303 +1,303 @@ -// hmqv.h - written and placed in the public domain by Uri Blumenthal -// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files - -#ifndef CRYPTOPP_HMQV_H -#define CRYPTOPP_HMQV_H - -/** \file -*/ - -#include "gfpcrypt.h" -#include "algebra.h" -#include "sha.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, -/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol - Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. -*/ -template -class HMQV_Domain: public AuthenticatedKeyAgreementDomain -{ -public: - typedef GROUP_PARAMETERS GroupParameters; - typedef typename GroupParameters::Element Element; - typedef HMQV_Domain Domain; - - HMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} - - HMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} - - HMQV_Domain(BufferedTransformation &bt, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.BERDecode(bt);} - - template - HMQV_Domain(T1 v1, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1);} - - template - HMQV_Domain(T1 v1, T2 v2, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2);} - - template - HMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2, v3);} - - template - HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) - : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2, v3, v4);} - -protected: - // Hash invocation by client and server differ only in what keys - // each provides. - - inline void Hash(const Element* sigma, - const byte* e1, size_t e1len, // Ephemeral key and key length - const byte* s1, size_t s1len, // Static key and key length - byte* digest, size_t dlen) const - { - HASH hash; - size_t idx = 0, req = dlen; - size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE); - - if(sigma) - { - if (e1len != 0 || s1len != 0) { - assert(0); - } - Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); - SecByteBlock sbb(x.MinEncodedSize()); - x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); - hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); - } else { - if (e1len == 0 || s1len == 0) { - assert(0); - } - hash.Update(e1, e1len); - hash.Update(s1, s1len); - } - - hash.TruncatedFinal(digest, blk); - req -= blk; - - // All this to catch tail bytes for large curves and small hashes - while(req != 0) - { - hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); - - idx += (size_t)HASH::DIGESTSIZE; - blk = std::min(req, (size_t)HASH::DIGESTSIZE); - hash.TruncatedFinal(&digest[idx], blk); - - req -= blk; - } - } - -public: - - const GroupParameters & GetGroupParameters() const {return m_groupParameters;} - GroupParameters & AccessGroupParameters(){return m_groupParameters;} - - CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();} - - //! return length of agreed value produced - unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} - //! return length of static private keys in this domain - unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} - //! return length of static public keys in this domain - unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} - - //! generate static private key - /*! \pre size of privateKey == PrivateStaticKeyLength() */ - void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); - x.Encode(privateKey, StaticPrivateKeyLength()); - } - - //! generate static public key - /*! \pre size of publicKey == PublicStaticKeyLength() */ - void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - Integer x(privateKey, StaticPrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, publicKey); - } - - unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} - unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} - - //! return length of ephemeral private keys in this domain - void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - Integer x(rng, Integer::One(), params.GetMaxExponent()); - x.Encode(privateKey, StaticPrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); - } - - //! return length of ephemeral public keys in this domain - void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); - } - - //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure - /*! \note The ephemeral public key will always be validated. - If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. - \pre size of agreedValue == AgreedValueLength() - \pre length of staticPrivateKey == StaticPrivateKeyLength() - \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() - \pre length of staticOtherPublicKey == StaticPublicKeyLength() - \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() - */ - bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey=true) const - { - byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL; - size_t xxs = 0, yys = 0, aas = 0, bbs = 0; - - // Depending on the role, this will hold either A's or B's static - // (long term) public key. AA or BB will then point into tt. - SecByteBlock tt(StaticPublicKeyLength()); - - try - { - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - - if(m_role == RoleServer) - { - Integer b(staticPrivateKey, StaticPrivateKeyLength()); - Element B = params.ExponentiateBase(b); - params.EncodeElement(true, B, tt); - - XX = const_cast(ephemeralOtherPublicKey); - xxs = EphemeralPublicKeyLength(); - YY = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); - yys = EphemeralPublicKeyLength(); - AA = const_cast(staticOtherPublicKey); - aas = StaticPublicKeyLength(); - BB = tt.BytePtr(); - bbs = tt.SizeInBytes(); - } - else if(m_role == RoleClient) - { - Integer a(staticPrivateKey, StaticPrivateKeyLength()); - Element A = params.ExponentiateBase(a); - params.EncodeElement(true, A, tt); - - XX = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); - xxs = EphemeralPublicKeyLength(); - YY = const_cast(ephemeralOtherPublicKey); - yys = EphemeralPublicKeyLength(); - AA = tt.BytePtr(); - aas = tt.SizeInBytes(); - BB = const_cast(staticOtherPublicKey); - bbs = StaticPublicKeyLength(); - } - else - { - assert(0); - return false; - } - - // DecodeElement calls ValidateElement at level 1. Level 1 only calls - // VerifyPoint to ensure the element is in G*. If the other's PublicKey is - // requested to be validated, we manually call ValidateElement at level 3. - Element VV1 = params.DecodeElement(staticOtherPublicKey, false); - if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL)) - return false; - - // DecodeElement calls ValidateElement at level 1. Level 1 only calls - // VerifyPoint to ensure the element is in G*. Crank it up. - Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false); - if(!params.ValidateElement(3, VV2, NULL)) - return false; - -// const Integer& p = params.GetGroupOrder(); // not used, remove later - const Integer& q = params.GetSubgroupOrder(); - const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); - - Integer d, e; - SecByteBlock dd(len), ee(len); - - // Compute $d = \hat{H}(X, \hat{B})$ - Hash(NULL, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); - d.Decode(dd.BytePtr(), dd.SizeInBytes()); - - // Compute $e = \hat{H}(Y, \hat{A})$ - Hash(NULL, YY, yys, AA, aas, ee.BytePtr(), ee.SizeInBytes()); - e.Decode(ee.BytePtr(), ee.SizeInBytes()); - - Element sigma; - if(m_role == RoleServer) - { - Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); - Integer b(staticPrivateKey, StaticPrivateKeyLength()); - Integer s_B = (y + e * b) % q; - - Element A = params.DecodeElement(AA, false); - Element X = params.DecodeElement(XX, false); - - Element t1 = params.ExponentiateElement(A, d); - Element t2 = m_groupParameters.MultiplyElements(X, t1); - - // $\sigma_B}=(X \cdot A^{d})^{s_B} - sigma = params.ExponentiateElement(t2, s_B); - } - else - { - Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); - Integer a(staticPrivateKey, StaticPrivateKeyLength()); - Integer s_A = (x + d * a) % q; - - Element B = params.DecodeElement(BB, false); - Element Y = params.DecodeElement(YY, false); - - Element t1 = params.ExponentiateElement(B, e); - Element t2 = m_groupParameters.MultiplyElements(Y, t1); - - // $\sigma_A}=(Y \cdot B^{e})^{s_A} - sigma = params.ExponentiateElement(t2, s_A); - } - Hash(&sigma, NULL, 0, NULL, 0, agreedValue, AgreedValueLength()); - } - catch (DL_BadElement &) - { - return false; - } - return true; - } - -private: - - // The paper uses Initiator and Recipient - make it classical. - enum KeyAgreementRole{ RoleServer = 1, RoleClient }; - - DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} - const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} - - KeyAgreementRole m_role; - GroupParameters m_groupParameters; -}; - -//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, -/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol - Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. -*/ -typedef HMQV_Domain HashedMQV; - -NAMESPACE_END - -#endif +// hmqv.h - written and placed in the public domain by Uri Blumenthal +// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files + +#ifndef CRYPTOPP_HMQV_H +#define CRYPTOPP_HMQV_H + +/** \file +*/ + +#include "gfpcrypt.h" +#include "algebra.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol + Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. +*/ +template +class HMQV_Domain: public AuthenticatedKeyAgreementDomain +{ +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef HMQV_Domain Domain; + + HMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} + + HMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} + + HMQV_Domain(BufferedTransformation &bt, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.BERDecode(bt);} + + template + HMQV_Domain(T1 v1, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1);} + + template + HMQV_Domain(T1 v1, T2 v2, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2);} + + template + HMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3);} + + template + HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + +protected: + // Hash invocation by client and server differ only in what keys + // each provides. + + inline void Hash(const Element* sigma, + const byte* e1, size_t e1len, // Ephemeral key and key length + const byte* s1, size_t s1len, // Static key and key length + byte* digest, size_t dlen) const + { + HASH hash; + size_t idx = 0, req = dlen; + size_t blk = std::min(dlen, (size_t)HASH::DIGESTSIZE); + + if(sigma) + { + if (e1len != 0 || s1len != 0) { + assert(0); + } + Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); + SecByteBlock sbb(x.MinEncodedSize()); + x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); + hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); + } else { + if (e1len == 0 || s1len == 0) { + assert(0); + } + hash.Update(e1, e1len); + hash.Update(s1, s1len); + } + + hash.TruncatedFinal(digest, blk); + req -= blk; + + // All this to catch tail bytes for large curves and small hashes + while(req != 0) + { + hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE); + + idx += (size_t)HASH::DIGESTSIZE; + blk = std::min(req, (size_t)HASH::DIGESTSIZE); + hash.TruncatedFinal(&digest[idx], blk); + + req -= blk; + } + } + +public: + + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + GroupParameters & AccessGroupParameters(){return m_groupParameters;} + + CryptoParameters & AccessCryptoParameters(){return AccessAbstractGroupParameters();} + + //! return length of agreed value produced + unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + //! return length of static private keys in this domain + unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + //! return length of static public keys in this domain + unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + //! generate static private key + /*! \pre size of privateKey == PrivateStaticKeyLength() */ + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + } + + //! generate static public key + /*! \pre size of publicKey == PublicStaticKeyLength() */ + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} + unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} + + //! return length of ephemeral private keys in this domain + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(rng, Integer::One(), params.GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); + } + + //! return length of ephemeral public keys in this domain + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); + } + + //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure + /*! \note The ephemeral public key will always be validated. + If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. + \pre size of agreedValue == AgreedValueLength() + \pre length of staticPrivateKey == StaticPrivateKeyLength() + \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() + \pre length of staticOtherPublicKey == StaticPublicKeyLength() + \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() + */ + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const + { + byte *XX = NULL, *YY = NULL, *AA = NULL, *BB = NULL; + size_t xxs = 0, yys = 0, aas = 0, bbs = 0; + + // Depending on the role, this will hold either A's or B's static + // (long term) public key. AA or BB will then point into tt. + SecByteBlock tt(StaticPublicKeyLength()); + + try + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + + if(m_role == RoleServer) + { + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Element B = params.ExponentiateBase(b); + params.EncodeElement(true, B, tt); + + XX = const_cast(ephemeralOtherPublicKey); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + yys = EphemeralPublicKeyLength(); + AA = const_cast(staticOtherPublicKey); + aas = StaticPublicKeyLength(); + BB = tt.BytePtr(); + bbs = tt.SizeInBytes(); + } + else if(m_role == RoleClient) + { + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Element A = params.ExponentiateBase(a); + params.EncodeElement(true, A, tt); + + XX = const_cast(ephemeralPrivateKey) + StaticPrivateKeyLength(); + xxs = EphemeralPublicKeyLength(); + YY = const_cast(ephemeralOtherPublicKey); + yys = EphemeralPublicKeyLength(); + AA = tt.BytePtr(); + aas = tt.SizeInBytes(); + BB = const_cast(staticOtherPublicKey); + bbs = StaticPublicKeyLength(); + } + else + { + assert(0); + return false; + } + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. If the other's PublicKey is + // requested to be validated, we manually call ValidateElement at level 3. + Element VV1 = params.DecodeElement(staticOtherPublicKey, false); + if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULL)) + return false; + + // DecodeElement calls ValidateElement at level 1. Level 1 only calls + // VerifyPoint to ensure the element is in G*. Crank it up. + Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false); + if(!params.ValidateElement(3, VV2, NULL)) + return false; + +// const Integer& p = params.GetGroupOrder(); // not used, remove later + const Integer& q = params.GetSubgroupOrder(); + const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); + + Integer d, e; + SecByteBlock dd(len), ee(len); + + // Compute $d = \hat{H}(X, \hat{B})$ + Hash(NULL, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); + d.Decode(dd.BytePtr(), dd.SizeInBytes()); + + // Compute $e = \hat{H}(Y, \hat{A})$ + Hash(NULL, YY, yys, AA, aas, ee.BytePtr(), ee.SizeInBytes()); + e.Decode(ee.BytePtr(), ee.SizeInBytes()); + + Element sigma; + if(m_role == RoleServer) + { + Integer y(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer b(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_B = (y + e * b) % q; + + Element A = params.DecodeElement(AA, false); + Element X = params.DecodeElement(XX, false); + + Element t1 = params.ExponentiateElement(A, d); + Element t2 = m_groupParameters.MultiplyElements(X, t1); + + // $\sigma_B}=(X \cdot A^{d})^{s_B} + sigma = params.ExponentiateElement(t2, s_B); + } + else + { + Integer x(ephemeralPrivateKey, StaticPrivateKeyLength()); + Integer a(staticPrivateKey, StaticPrivateKeyLength()); + Integer s_A = (x + d * a) % q; + + Element B = params.DecodeElement(BB, false); + Element Y = params.DecodeElement(YY, false); + + Element t1 = params.ExponentiateElement(B, e); + Element t2 = m_groupParameters.MultiplyElements(Y, t1); + + // $\sigma_A}=(Y \cdot B^{e})^{s_A} + sigma = params.ExponentiateElement(t2, s_A); + } + Hash(&sigma, NULL, 0, NULL, 0, agreedValue, AgreedValueLength()); + } + catch (DL_BadElement &) + { + return false; + } + return true; + } + +private: + + // The paper uses Initiator and Recipient - make it classical. + enum KeyAgreementRole{ RoleServer = 1, RoleClient }; + + DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} + const DL_GroupParameters & GetAbstractGroupParameters() const{return m_groupParameters;} + + KeyAgreementRole m_role; + GroupParameters m_groupParameters; +}; + +//! Hashed Menezes-Qu-Vanstone in GF(p) with key validation, +/*! HMQV: A High-Performance Secure Diffie-Hellman Protocol + Note: this implements HMQV only. HMQV-C (with Key Confirmation) will be provided separately. +*/ +typedef HMQV_Domain HashedMQV; + +NAMESPACE_END + +#endif diff --git a/mqv.h b/mqv.h index 077bb0d0..673b1e68 100644 --- a/mqv.h +++ b/mqv.h @@ -46,7 +46,7 @@ public: //! \brief Construct a MQV domain //! \tparam T1 template parameter used as a constructor parameter //! \tparam T2 template parameter used as a constructor parameter - //! \param v1 first parameter + //! \param v1 first parameter //! \param v2 second parameter //! \details v1 and v2 are passed directly to the GROUP_PARAMETERS object. template @@ -57,7 +57,7 @@ public: //! \tparam T1 template parameter used as a constructor parameter //! \tparam T2 template parameter used as a constructor parameter //! \tparam T3 template parameter used as a constructor parameter - //! \param v1 first parameter + //! \param v1 first parameter //! \param v2 second parameter //! \param v3 third parameter //! \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object. @@ -70,7 +70,7 @@ public: //! \tparam T2 template parameter used as a constructor parameter //! \tparam T3 template parameter used as a constructor parameter //! \tparam T4 template parameter used as a constructor parameter - //! \param v1 first parameter + //! \param v1 first parameter //! \param v2 second parameter //! \param v3 third parameter //! \param v4 third parameter @@ -156,7 +156,7 @@ public: } bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, bool validateStaticOtherPublicKey=true) const {