| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- // dh.h - originally written and placed in the public domain by Wei Dai
- /// \file dh.h
- /// \brief Classes for Diffie-Hellman key exchange
- #ifndef CRYPTOPP_DH_H
- #define CRYPTOPP_DH_H
- #include "cryptlib.h"
- #include "gfpcrypt.h"
- #include "algebra.h"
- NAMESPACE_BEGIN(CryptoPP)
- /// \brief Diffie-Hellman domain
- /// \tparam GROUP_PARAMETERS group parameters
- /// \tparam COFACTOR_OPTION cofactor multiplication option
- /// \details A Diffie-Hellman domain is a set of parameters that must be shared
- /// by two parties in a key agreement protocol, along with the algorithms
- /// for generating key pairs and deriving agreed values.
- /// \details For COFACTOR_OPTION, see CofactorMultiplicationOption.
- /// \sa DL_SimpleKeyAgreementDomainBase
- /// \since Crypto++ 1.0
- template <class GROUP_PARAMETERS, class COFACTOR_OPTION = typename GROUP_PARAMETERS::DefaultCofactorOption>
- class DH_Domain : public DL_SimpleKeyAgreementDomainBase<typename GROUP_PARAMETERS::Element>
- {
- typedef DL_SimpleKeyAgreementDomainBase<typename GROUP_PARAMETERS::Element> Base;
- public:
- typedef GROUP_PARAMETERS GroupParameters;
- typedef typename GroupParameters::Element Element;
- typedef DL_KeyAgreementAlgorithm_DH<Element, COFACTOR_OPTION> DH_Algorithm;
- typedef DH_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain;
- virtual ~DH_Domain() {}
- /// \brief Construct a Diffie-Hellman domain
- DH_Domain() {}
- /// \brief Construct a Diffie-Hellman domain
- /// \param params group parameters and options
- DH_Domain(const GroupParameters ¶ms)
- : m_groupParameters(params) {}
- /// \brief Construct a Diffie-Hellman domain
- /// \param bt BufferedTransformation with group parameters and options
- DH_Domain(BufferedTransformation &bt)
- {m_groupParameters.BERDecode(bt);}
- /// \brief Create a Diffie-Hellman domain
- /// \tparam T2 template parameter used as a constructor parameter
- /// \param v1 RandomNumberGenerator derived class
- /// \param v2 second parameter
- /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
- template <class T2>
- DH_Domain(RandomNumberGenerator &v1, const T2 &v2)
- {m_groupParameters.Initialize(v1, v2);}
- /// \brief Create a Diffie-Hellman domain
- /// \tparam T2 template parameter used as a constructor parameter
- /// \tparam T3 template parameter used as a constructor parameter
- /// \param v1 RandomNumberGenerator derived class
- /// \param v2 second parameter
- /// \param v3 third parameter
- /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
- template <class T2, class T3>
- DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3)
- {m_groupParameters.Initialize(v1, v2, v3);}
- /// \brief Create a Diffie-Hellman domain
- /// \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 RandomNumberGenerator derived class
- /// \param v2 second parameter
- /// \param v3 third parameter
- /// \param v4 fourth parameter
- /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
- template <class T2, class T3, class T4>
- DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3, const T4 &v4)
- {m_groupParameters.Initialize(v1, v2, v3, v4);}
- /// \brief Construct a Diffie-Hellman 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.
- template <class T1, class T2>
- DH_Domain(const T1 &v1, const T2 &v2)
- {m_groupParameters.Initialize(v1, v2);}
- /// \brief Construct a Diffie-Hellman 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.
- template <class T1, class T2, class T3>
- DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3)
- {m_groupParameters.Initialize(v1, v2, v3);}
- /// \brief Construct a Diffie-Hellman 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 fourth parameter
- /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
- template <class T1, class T2, class T3, class T4>
- DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
- {m_groupParameters.Initialize(v1, v2, v3, v4);}
- /// \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;}
- /// \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 Generate a public key from a private key in this domain
- /// \param rng RandomNumberGenerator derived class
- /// \param privateKey byte buffer with the previously generated private key
- /// \param publicKey byte buffer for the generated public key in this domain
- /// \details If using a FIPS 140-2 validated library on Windows, then this class will perform
- /// a self test to ensure the key pair is pairwise consistent. Non-FIPS and non-Windows
- /// builds of the library do not provide FIPS validated cryptography, so the code should be
- /// removed by the optimizer.
- /// \pre <tt>COUNTOF(publicKey) == PublicKeyLength()</tt>
- void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
- {
- Base::GeneratePublicKey(rng, privateKey, publicKey);
- if (FIPS_140_2_ComplianceEnabled())
- {
- SecByteBlock privateKey2(this->PrivateKeyLength());
- this->GeneratePrivateKey(rng, privateKey2);
- SecByteBlock publicKey2(this->PublicKeyLength());
- Base::GeneratePublicKey(rng, privateKey2, publicKey2);
- SecByteBlock agreedValue(this->AgreedValueLength()), agreedValue2(this->AgreedValueLength());
- bool agreed1 = this->Agree(agreedValue, privateKey, publicKey2);
- bool agreed2 = this->Agree(agreedValue2, privateKey2, publicKey);
- if (!agreed1 || !agreed2 || agreedValue != agreedValue2)
- throw SelfTestFailure(this->AlgorithmName() + ": pairwise consistency test failed");
- }
- }
- static std::string CRYPTOPP_API StaticAlgorithmName()
- {return GroupParameters::StaticAlgorithmNamePrefix() + DH_Algorithm::StaticAlgorithmName();}
- std::string AlgorithmName() const {return StaticAlgorithmName();}
- private:
- const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
- {return Singleton<DH_Algorithm>().Ref();}
- DL_GroupParameters<Element> & AccessAbstractGroupParameters()
- {return m_groupParameters;}
- GroupParameters m_groupParameters;
- };
- CRYPTOPP_DLL_TEMPLATE_CLASS DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime>;
- /// \brief Diffie-Hellman in GF(p)
- /// \details DH() class is a typedef of DH_Domain(). The documentation that follows
- /// does not exist. Rather the documentation was created in response to <a href="https://github.com/weidai11/cryptopp/issues/328">Issue
- /// 328, Diffie-Hellman example code not compiling</a>.
- /// \details Generally speaking, a DH() object is ephemeral and is intended to execute one instance of the Diffie-Hellman protocol. The
- /// private and public key parts are not intended to be set or persisted. Rather, a new set of domain parameters are generated each
- /// time an object is created.
- /// \details Once a DH() object is created, once can retrieve the ephemeral public key for the other party with code similar to the
- /// following.
- /// <pre> AutoSeededRandomPool prng;
- /// Integer p, q, g;
- /// PrimeAndGenerator pg;
- ///
- /// pg.Generate(1, prng, 512, 511);
- /// p = pg.Prime();
- /// q = pg.SubPrime();
- /// g = pg.Generator();
- ///
- /// DH dh(p, q, g);
- /// SecByteBlock t1(dh.PrivateKeyLength()), t2(dh.PublicKeyLength());
- /// dh.GenerateKeyPair(prng, t1, t2);
- /// Integer k1(t1, t1.size()), k2(t2, t2.size());
- ///
- /// cout << "Private key:\n";
- /// cout << hex << k1 << endl;
- ///
- /// cout << "Public key:\n";
- /// cout << hex << k2 << endl;</pre>
- ///
- /// \details Output of the program above will be similar to the following.
- /// <pre> $ ./cryptest.exe
- /// Private key:
- /// 72b45a42371545e9d4880f48589aefh
- /// Public key:
- /// 45fdb13f97b1840626f0250cec1dba4a23b894100b51fb5d2dd13693d789948f8bfc88f9200014b2
- /// ba8dd8a6debc471c69ef1e2326c61184a2eca88ec866346bh</pre>
- /// \sa <a href="http://www.cryptopp.com/wiki/Diffie-Hellman">Diffie-Hellman on the Crypto++ wiki</a> and
- /// <a href="http://www.weidai.com/scan-mirror/ka.html#DH">Diffie-Hellman</a> in GF(p) with key validation
- /// \since Crypto++ 1.0
- #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
- struct DH : public DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime>
- {
- typedef DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime> GroupParameters;
- typedef GroupParameters::Element Element;
- virtual ~DH() {}
- /// \brief Create an uninitialized Diffie-Hellman object
- DH() : DH_Domain() {}
- /// \brief Initialize a Diffie-Hellman object
- /// \param bt BufferedTransformation with group parameters and options
- DH(BufferedTransformation &bt) : DH_Domain(bt) {}
- /// \brief Initialize a Diffie-Hellman object
- /// \param params group parameters and options
- DH(const GroupParameters ¶ms) : DH_Domain(params) {}
- /// \brief Create a Diffie-Hellman object
- /// \param rng a RandomNumberGenerator derived class
- /// \param modulusBits the size of the modulus, in bits
- /// \details This function overload of Initialize() creates a new Diffie-Hellman object because it
- /// takes a RandomNumberGenerator() as a parameter.
- DH(RandomNumberGenerator &rng, unsigned int modulusBits) : DH_Domain(rng, modulusBits) {}
- /// \brief Initialize a Diffie-Hellman object
- /// \param p the modulus
- /// \param g the generator
- DH(const Integer &p, const Integer &g) : DH_Domain(p, g) {}
- /// \brief Initialize a Diffie-Hellman object
- /// \param p the modulus
- /// \param q the subgroup order
- /// \param g the generator
- DH(const Integer &p, const Integer &q, const Integer &g) : DH_Domain(p, q, g) {}
- /// \brief Creates a Diffie-Hellman object
- /// \param rng a RandomNumberGenerator derived class
- /// \param modulusBits the size of the modulus, in bits
- /// \details This function overload of Initialize() creates a new Diffie-Hellman object because it
- /// takes a RandomNumberGenerator() as a parameter.
- void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
- {AccessGroupParameters().Initialize(rng, modulusBits);}
- /// \brief Initialize a Diffie-Hellman object
- /// \param p the modulus
- /// \param g the generator
- void Initialize(const Integer &p, const Integer &g)
- {AccessGroupParameters().Initialize(p, g);}
- /// \brief Initialize a Diffie-Hellman object
- /// \param p the modulus
- /// \param q the subgroup order
- /// \param g the generator
- void Initialize(const Integer &p, const Integer &q, const Integer &g)
- {AccessGroupParameters().Initialize(p, q, g);}
- };
- #else
- // The real DH class is a typedef.
- typedef DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime> DH;
- #endif
- NAMESPACE_END
- #endif
|