From 47a58050c62b3f9af7eb4df224b0390d77112263 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sat, 3 Aug 2019 19:22:17 -0400 Subject: Update documentation --- fhmqv.h | 182 +++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 141 insertions(+), 41 deletions(-) (limited to 'fhmqv.h') diff --git a/fhmqv.h b/fhmqv.h index eaf6193b..7d2fc1ca 100644 --- a/fhmqv.h +++ b/fhmqv.h @@ -30,59 +30,144 @@ public: virtual ~FHMQV_Domain() {} - FHMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} - + /// \brief Construct a FHMQV domain + /// \params clientRole flag indicating initiator or recipient + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. + FHMQV_Domain(bool clientRole = true) + : m_role(clientRole ? RoleClient : RoleServer) {} + + /// \brief Construct a FHMQV domain + /// \param params group parameters and options + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. FHMQV_Domain(const GroupParameters ¶ms, bool clientRole = true) : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} + /// \brief Construct a FHMQV domain + /// \param bt BufferedTransformation with group parameters and options + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true) : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.BERDecode(bt);} - + {m_groupParameters.BERDecode(bt);} + + /// \brief Construct a FHMQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. template FHMQV_Domain(T1 v1, bool clientRole = true) : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1);} - + {m_groupParameters.Initialize(v1);} + + /// \brief Construct a FHMQV domain + /// \tparam T1 template parameter used as a constructor parameter + /// \tparam T2 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. template FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true) : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2);} - + {m_groupParameters.Initialize(v1, v2);} + + /// \brief Construct a FHMQV domain + /// \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 v2 second parameter + /// \param v3 third parameter + /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. template FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) : m_role(clientRole ? RoleClient : RoleServer) - {m_groupParameters.Initialize(v1, v2, v3);} - + {m_groupParameters.Initialize(v1, v2, v3);} + + /// \brief Construct a FHMQV domain + /// \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 + /// \tparam T4 template parameter used as a constructor parameter + /// \param v1 first parameter + /// \param v2 second parameter + /// \param v3 third parameter + /// \param v4 third parameter + /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object. + /// \details clientRole = true indicates initiator, and + /// clientRole = false indicates recipient or server. 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);} + {m_groupParameters.Initialize(v1, v2, v3, v4);} public: + /// \brief Retrieves the group parameters for this domain + /// \return the group parameters for this domain as a const reference 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() */ + /// \brief Retrieves the group parameters for this domain + /// \return the group parameters for this domain as a non-const reference + GroupParameters & AccessGroupParameters() {return m_groupParameters;} + + /// \brief Retrieves the crypto parameters for this domain + /// \return the crypto parameters for this domain as a non-const reference + CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} + + /// \brief Provides the size of the agreed value + /// \return size of agreed value produced in this domain + /// \details The length is calculated using GetEncodedElementSize(false), + /// which means the element is encoded in a non-reversible format. A + /// non-reversible format means its a raw byte array, and it lacks presentation + /// format like an ASN.1 BIT_STRING or OCTET_STRING. + unsigned int AgreedValueLength() const + {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + + /// \brief Provides the size of the static private key + /// \return size of static private keys in this domain + /// \details The length is calculated using the byte count of the subgroup order. + unsigned int StaticPrivateKeyLength() const + {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + + /// \brief Provides the size of the static public key + /// \return size of static public keys in this domain + /// \details The length is calculated using GetEncodedElementSize(true), + /// which means the element is encoded in a reversible format. A reversible + /// format means it has a presentation format, and its an ANS.1 encoded element + /// or point. + unsigned int StaticPublicKeyLength() const + {return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + /// \brief Generate static private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer for the generated private key in this domain + /// \details The private key is a random scalar used as an exponent in the range + /// [1,MaxExponent()]. + /// \pre COUNTOF(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() */ + /// \brief Generate a static public key from a private key in this domain + /// \param rng a RandomNumberGenerator derived class + /// \param privateKey a byte buffer with the previously generated private key + /// \param publicKey a byte buffer for the generated public key in this domain + /// \details The public key is an element or point on the curve, and its stored + /// in a revrsible format. A reversible format means it has a presentation + /// format, and its an ANS.1 encoded element or point. + /// \pre COUNTOF(publicKey) == PublicStaticKeyLength() void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const { CRYPTOPP_UNUSED(rng); @@ -112,15 +197,26 @@ public: 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() - */ + /// \brief Derive shared secre from your private keys and couterparty's public keys + /// \param agreedValue the shared secret + /// \param staticPrivateKey your long term private key + /// \param ephemeralPrivateKey your ephemeral private key + /// \param staticOtherPublicKey couterparty's long term public key + /// \param ephemeralOtherPublicKey your ephemeral public key + /// \param validateStaticOtherPublicKey flag indicating validation + /// \details Agree() performs the authenticated key agreement. Each instance + /// or run of the protocol should use a new ephemeral key pair. + /// \details The other's ephemeral public key will always be validated at + /// Level 1 to ensure it is a point on the curve. + /// validateStaticOtherPublicKey determines how thoroughly other's + /// static public key is validated. If you have previously validated the + /// couterparty's static public key, then 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, @@ -153,7 +249,7 @@ public: BB = tt.BytePtr(); bbs = tt.SizeInBytes(); } - else if(m_role == RoleClient) + else { Integer a(staticPrivateKey, StaticPrivateKeyLength()); Element A = params.ExponentiateBase(a); @@ -168,24 +264,25 @@ public: BB = staticOtherPublicKey; bbs = StaticPublicKeyLength(); } - else - { - CRYPTOPP_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, NULLPTR)) + { + CRYPTOPP_ASSERT(0); 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, NULLPTR)) + { + CRYPTOPP_ASSERT(0); return false; + } const Integer& q = params.GetSubgroupOrder(); const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); @@ -233,6 +330,7 @@ public: } catch (DL_BadElement &) { + CRYPTOPP_ASSERT(0); return false; } return true; @@ -251,6 +349,8 @@ protected: if(sigma) { + //SecByteBlock sbb(GetAbstractGroupParameters().GetEncodedElementSize(false)); + //GetAbstractGroupParameters().EncodeElement(false, *sigma, sbb); Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); SecByteBlock sbb(x.MinEncodedSize()); x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); @@ -294,7 +394,7 @@ private: /// \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. -/// \sa FHMQV, MQV_Domain, HMQV_Domain, AuthenticatedKeyAgreementDomain +/// \sa FHMQV, MQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain /// \since Crypto++ 5.6.4 typedef FHMQV_Domain FHMQV; -- cgit v1.2.1