|
||||
File indexing completed on 2025-01-18 09:54:56
0001 // dh.h - originally written and placed in the public domain by Wei Dai 0002 0003 /// \file dh.h 0004 /// \brief Classes for Diffie-Hellman key exchange 0005 0006 #ifndef CRYPTOPP_DH_H 0007 #define CRYPTOPP_DH_H 0008 0009 #include "cryptlib.h" 0010 #include "gfpcrypt.h" 0011 #include "algebra.h" 0012 0013 NAMESPACE_BEGIN(CryptoPP) 0014 0015 /// \brief Diffie-Hellman domain 0016 /// \tparam GROUP_PARAMETERS group parameters 0017 /// \tparam COFACTOR_OPTION cofactor multiplication option 0018 /// \details A Diffie-Hellman domain is a set of parameters that must be shared 0019 /// by two parties in a key agreement protocol, along with the algorithms 0020 /// for generating key pairs and deriving agreed values. 0021 /// \details For COFACTOR_OPTION, see CofactorMultiplicationOption. 0022 /// \sa DL_SimpleKeyAgreementDomainBase 0023 /// \since Crypto++ 1.0 0024 template <class GROUP_PARAMETERS, class COFACTOR_OPTION = typename GROUP_PARAMETERS::DefaultCofactorOption> 0025 class DH_Domain : public DL_SimpleKeyAgreementDomainBase<typename GROUP_PARAMETERS::Element> 0026 { 0027 typedef DL_SimpleKeyAgreementDomainBase<typename GROUP_PARAMETERS::Element> Base; 0028 0029 public: 0030 typedef GROUP_PARAMETERS GroupParameters; 0031 typedef typename GroupParameters::Element Element; 0032 typedef DL_KeyAgreementAlgorithm_DH<Element, COFACTOR_OPTION> DH_Algorithm; 0033 typedef DH_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain; 0034 0035 virtual ~DH_Domain() {} 0036 0037 /// \brief Construct a Diffie-Hellman domain 0038 DH_Domain() {} 0039 0040 /// \brief Construct a Diffie-Hellman domain 0041 /// \param params group parameters and options 0042 DH_Domain(const GroupParameters ¶ms) 0043 : m_groupParameters(params) {} 0044 0045 /// \brief Construct a Diffie-Hellman domain 0046 /// \param bt BufferedTransformation with group parameters and options 0047 DH_Domain(BufferedTransformation &bt) 0048 {m_groupParameters.BERDecode(bt);} 0049 0050 /// \brief Create a Diffie-Hellman domain 0051 /// \tparam T2 template parameter used as a constructor parameter 0052 /// \param v1 RandomNumberGenerator derived class 0053 /// \param v2 second parameter 0054 /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object. 0055 template <class T2> 0056 DH_Domain(RandomNumberGenerator &v1, const T2 &v2) 0057 {m_groupParameters.Initialize(v1, v2);} 0058 0059 /// \brief Create a Diffie-Hellman domain 0060 /// \tparam T2 template parameter used as a constructor parameter 0061 /// \tparam T3 template parameter used as a constructor parameter 0062 /// \param v1 RandomNumberGenerator derived class 0063 /// \param v2 second parameter 0064 /// \param v3 third parameter 0065 /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object. 0066 template <class T2, class T3> 0067 DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3) 0068 {m_groupParameters.Initialize(v1, v2, v3);} 0069 0070 /// \brief Create a Diffie-Hellman domain 0071 /// \tparam T2 template parameter used as a constructor parameter 0072 /// \tparam T3 template parameter used as a constructor parameter 0073 /// \tparam T4 template parameter used as a constructor parameter 0074 /// \param v1 RandomNumberGenerator derived class 0075 /// \param v2 second parameter 0076 /// \param v3 third parameter 0077 /// \param v4 fourth parameter 0078 /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object. 0079 template <class T2, class T3, class T4> 0080 DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3, const T4 &v4) 0081 {m_groupParameters.Initialize(v1, v2, v3, v4);} 0082 0083 /// \brief Construct a Diffie-Hellman domain 0084 /// \tparam T1 template parameter used as a constructor parameter 0085 /// \tparam T2 template parameter used as a constructor parameter 0086 /// \param v1 first parameter 0087 /// \param v2 second parameter 0088 /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object. 0089 template <class T1, class T2> 0090 DH_Domain(const T1 &v1, const T2 &v2) 0091 {m_groupParameters.Initialize(v1, v2);} 0092 0093 /// \brief Construct a Diffie-Hellman domain 0094 /// \tparam T1 template parameter used as a constructor parameter 0095 /// \tparam T2 template parameter used as a constructor parameter 0096 /// \tparam T3 template parameter used as a constructor parameter 0097 /// \param v1 first parameter 0098 /// \param v2 second parameter 0099 /// \param v3 third parameter 0100 /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object. 0101 template <class T1, class T2, class T3> 0102 DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3) 0103 {m_groupParameters.Initialize(v1, v2, v3);} 0104 0105 /// \brief Construct a Diffie-Hellman domain 0106 /// \tparam T1 template parameter used as a constructor parameter 0107 /// \tparam T2 template parameter used as a constructor parameter 0108 /// \tparam T3 template parameter used as a constructor parameter 0109 /// \tparam T4 template parameter used as a constructor parameter 0110 /// \param v1 first parameter 0111 /// \param v2 second parameter 0112 /// \param v3 third parameter 0113 /// \param v4 fourth parameter 0114 /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object. 0115 template <class T1, class T2, class T3, class T4> 0116 DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) 0117 {m_groupParameters.Initialize(v1, v2, v3, v4);} 0118 0119 /// \brief Retrieves the group parameters for this domain 0120 /// \return the group parameters for this domain as a const reference 0121 const GroupParameters & GetGroupParameters() const {return m_groupParameters;} 0122 /// \brief Retrieves the group parameters for this domain 0123 /// \return the group parameters for this domain as a non-const reference 0124 GroupParameters & AccessGroupParameters() {return m_groupParameters;} 0125 0126 /// \brief Generate a public key from a private key in this domain 0127 /// \param rng RandomNumberGenerator derived class 0128 /// \param privateKey byte buffer with the previously generated private key 0129 /// \param publicKey byte buffer for the generated public key in this domain 0130 /// \details If using a FIPS 140-2 validated library on Windows, then this class will perform 0131 /// a self test to ensure the key pair is pairwise consistent. Non-FIPS and non-Windows 0132 /// builds of the library do not provide FIPS validated cryptography, so the code should be 0133 /// removed by the optimizer. 0134 /// \pre <tt>COUNTOF(publicKey) == PublicKeyLength()</tt> 0135 void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const 0136 { 0137 Base::GeneratePublicKey(rng, privateKey, publicKey); 0138 0139 if (FIPS_140_2_ComplianceEnabled()) 0140 { 0141 SecByteBlock privateKey2(this->PrivateKeyLength()); 0142 this->GeneratePrivateKey(rng, privateKey2); 0143 0144 SecByteBlock publicKey2(this->PublicKeyLength()); 0145 Base::GeneratePublicKey(rng, privateKey2, publicKey2); 0146 0147 SecByteBlock agreedValue(this->AgreedValueLength()), agreedValue2(this->AgreedValueLength()); 0148 bool agreed1 = this->Agree(agreedValue, privateKey, publicKey2); 0149 bool agreed2 = this->Agree(agreedValue2, privateKey2, publicKey); 0150 0151 if (!agreed1 || !agreed2 || agreedValue != agreedValue2) 0152 throw SelfTestFailure(this->AlgorithmName() + ": pairwise consistency test failed"); 0153 } 0154 } 0155 0156 static std::string CRYPTOPP_API StaticAlgorithmName() 0157 {return GroupParameters::StaticAlgorithmNamePrefix() + DH_Algorithm::StaticAlgorithmName();} 0158 std::string AlgorithmName() const {return StaticAlgorithmName();} 0159 0160 private: 0161 const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const 0162 {return Singleton<DH_Algorithm>().Ref();} 0163 DL_GroupParameters<Element> & AccessAbstractGroupParameters() 0164 {return m_groupParameters;} 0165 0166 GroupParameters m_groupParameters; 0167 }; 0168 0169 CRYPTOPP_DLL_TEMPLATE_CLASS DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime>; 0170 0171 /// \brief Diffie-Hellman in GF(p) 0172 /// \details DH() class is a typedef of DH_Domain(). The documentation that follows 0173 /// does not exist. Rather the documentation was created in response to <a href="https://github.com/weidai11/cryptopp/issues/328">Issue 0174 /// 328, Diffie-Hellman example code not compiling</a>. 0175 /// \details Generally speaking, a DH() object is ephemeral and is intended to execute one instance of the Diffie-Hellman protocol. The 0176 /// private and public key parts are not intended to be set or persisted. Rather, a new set of domain parameters are generated each 0177 /// time an object is created. 0178 /// \details Once a DH() object is created, once can retrieve the ephemeral public key for the other party with code similar to the 0179 /// following. 0180 /// <pre> AutoSeededRandomPool prng; 0181 /// Integer p, q, g; 0182 /// PrimeAndGenerator pg; 0183 /// 0184 /// pg.Generate(1, prng, 512, 511); 0185 /// p = pg.Prime(); 0186 /// q = pg.SubPrime(); 0187 /// g = pg.Generator(); 0188 /// 0189 /// DH dh(p, q, g); 0190 /// SecByteBlock t1(dh.PrivateKeyLength()), t2(dh.PublicKeyLength()); 0191 /// dh.GenerateKeyPair(prng, t1, t2); 0192 /// Integer k1(t1, t1.size()), k2(t2, t2.size()); 0193 /// 0194 /// cout << "Private key:\n"; 0195 /// cout << hex << k1 << endl; 0196 /// 0197 /// cout << "Public key:\n"; 0198 /// cout << hex << k2 << endl;</pre> 0199 /// 0200 /// \details Output of the program above will be similar to the following. 0201 /// <pre> $ ./cryptest.exe 0202 /// Private key: 0203 /// 72b45a42371545e9d4880f48589aefh 0204 /// Public key: 0205 /// 45fdb13f97b1840626f0250cec1dba4a23b894100b51fb5d2dd13693d789948f8bfc88f9200014b2 0206 /// ba8dd8a6debc471c69ef1e2326c61184a2eca88ec866346bh</pre> 0207 /// \sa <a href="http://www.cryptopp.com/wiki/Diffie-Hellman">Diffie-Hellman on the Crypto++ wiki</a> and 0208 /// <a href="http://www.weidai.com/scan-mirror/ka.html#DH">Diffie-Hellman</a> in GF(p) with key validation 0209 /// \since Crypto++ 1.0 0210 #if defined(CRYPTOPP_DOXYGEN_PROCESSING) 0211 struct DH : public DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime> 0212 { 0213 typedef DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime> GroupParameters; 0214 typedef GroupParameters::Element Element; 0215 0216 virtual ~DH() {} 0217 0218 /// \brief Create an uninitialized Diffie-Hellman object 0219 DH() : DH_Domain() {} 0220 0221 /// \brief Initialize a Diffie-Hellman object 0222 /// \param bt BufferedTransformation with group parameters and options 0223 DH(BufferedTransformation &bt) : DH_Domain(bt) {} 0224 0225 /// \brief Initialize a Diffie-Hellman object 0226 /// \param params group parameters and options 0227 DH(const GroupParameters ¶ms) : DH_Domain(params) {} 0228 0229 /// \brief Create a Diffie-Hellman object 0230 /// \param rng a RandomNumberGenerator derived class 0231 /// \param modulusBits the size of the modulus, in bits 0232 /// \details This function overload of Initialize() creates a new Diffie-Hellman object because it 0233 /// takes a RandomNumberGenerator() as a parameter. 0234 DH(RandomNumberGenerator &rng, unsigned int modulusBits) : DH_Domain(rng, modulusBits) {} 0235 0236 /// \brief Initialize a Diffie-Hellman object 0237 /// \param p the modulus 0238 /// \param g the generator 0239 DH(const Integer &p, const Integer &g) : DH_Domain(p, g) {} 0240 0241 /// \brief Initialize a Diffie-Hellman object 0242 /// \param p the modulus 0243 /// \param q the subgroup order 0244 /// \param g the generator 0245 DH(const Integer &p, const Integer &q, const Integer &g) : DH_Domain(p, q, g) {} 0246 0247 /// \brief Creates a Diffie-Hellman object 0248 /// \param rng a RandomNumberGenerator derived class 0249 /// \param modulusBits the size of the modulus, in bits 0250 /// \details This function overload of Initialize() creates a new Diffie-Hellman object because it 0251 /// takes a RandomNumberGenerator() as a parameter. 0252 void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) 0253 {AccessGroupParameters().Initialize(rng, modulusBits);} 0254 0255 /// \brief Initialize a Diffie-Hellman object 0256 /// \param p the modulus 0257 /// \param g the generator 0258 void Initialize(const Integer &p, const Integer &g) 0259 {AccessGroupParameters().Initialize(p, g);} 0260 0261 /// \brief Initialize a Diffie-Hellman object 0262 /// \param p the modulus 0263 /// \param q the subgroup order 0264 /// \param g the generator 0265 void Initialize(const Integer &p, const Integer &q, const Integer &g) 0266 {AccessGroupParameters().Initialize(p, q, g);} 0267 }; 0268 #else 0269 // The real DH class is a typedef. 0270 typedef DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime> DH; 0271 #endif 0272 0273 NAMESPACE_END 0274 0275 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |