Crypto++ 8.7
Free C++ class library of cryptographic schemes
dh.h
Go to the documentation of this file.
1// dh.h - originally written and placed in the public domain by Wei Dai
2
3/// \file dh.h
4/// \brief Classes for Diffie-Hellman key exchange
5
6#ifndef CRYPTOPP_DH_H
7#define CRYPTOPP_DH_H
8
9#include "cryptlib.h"
10#include "gfpcrypt.h"
11#include "algebra.h"
12
13NAMESPACE_BEGIN(CryptoPP)
14
15/// \brief Diffie-Hellman domain
16/// \tparam GROUP_PARAMETERS group parameters
17/// \tparam COFACTOR_OPTION cofactor multiplication option
18/// \details A Diffie-Hellman domain is a set of parameters that must be shared
19/// by two parties in a key agreement protocol, along with the algorithms
20/// for generating key pairs and deriving agreed values.
21/// \details For COFACTOR_OPTION, see CofactorMultiplicationOption.
22/// \sa DL_SimpleKeyAgreementDomainBase
23/// \since Crypto++ 1.0
24template <class GROUP_PARAMETERS, class COFACTOR_OPTION = typename GROUP_PARAMETERS::DefaultCofactorOption>
25class DH_Domain : public DL_SimpleKeyAgreementDomainBase<typename GROUP_PARAMETERS::Element>
26{
28
29public:
30 typedef GROUP_PARAMETERS GroupParameters;
31 typedef typename GroupParameters::Element Element;
34
35 virtual ~DH_Domain() {}
36
37 /// \brief Construct a Diffie-Hellman domain
39
40 /// \brief Construct a Diffie-Hellman domain
41 /// \param params group parameters and options
42 DH_Domain(const GroupParameters &params)
43 : m_groupParameters(params) {}
44
45 /// \brief Construct a Diffie-Hellman domain
46 /// \param bt BufferedTransformation with group parameters and options
48 {m_groupParameters.BERDecode(bt);}
49
50 /// \brief Create a Diffie-Hellman domain
51 /// \tparam T2 template parameter used as a constructor parameter
52 /// \param v1 RandomNumberGenerator derived class
53 /// \param v2 second parameter
54 /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
55 template <class T2>
57 {m_groupParameters.Initialize(v1, v2);}
58
59 /// \brief Create a Diffie-Hellman domain
60 /// \tparam T2 template parameter used as a constructor parameter
61 /// \tparam T3 template parameter used as a constructor parameter
62 /// \param v1 RandomNumberGenerator derived class
63 /// \param v2 second parameter
64 /// \param v3 third parameter
65 /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
66 template <class T2, class T3>
67 DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3)
68 {m_groupParameters.Initialize(v1, v2, v3);}
69
70 /// \brief Create a Diffie-Hellman domain
71 /// \tparam T2 template parameter used as a constructor parameter
72 /// \tparam T3 template parameter used as a constructor parameter
73 /// \tparam T4 template parameter used as a constructor parameter
74 /// \param v1 RandomNumberGenerator derived class
75 /// \param v2 second parameter
76 /// \param v3 third parameter
77 /// \param v4 fourth parameter
78 /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
79 template <class T2, class T3, class T4>
80 DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3, const T4 &v4)
81 {m_groupParameters.Initialize(v1, v2, v3, v4);}
82
83 /// \brief Construct a Diffie-Hellman domain
84 /// \tparam T1 template parameter used as a constructor parameter
85 /// \tparam T2 template parameter used as a constructor parameter
86 /// \param v1 first parameter
87 /// \param v2 second parameter
88 /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
89 template <class T1, class T2>
90 DH_Domain(const T1 &v1, const T2 &v2)
91 {m_groupParameters.Initialize(v1, v2);}
92
93 /// \brief Construct a Diffie-Hellman domain
94 /// \tparam T1 template parameter used as a constructor parameter
95 /// \tparam T2 template parameter used as a constructor parameter
96 /// \tparam T3 template parameter used as a constructor parameter
97 /// \param v1 first parameter
98 /// \param v2 second parameter
99 /// \param v3 third parameter
100 /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
101 template <class T1, class T2, class T3>
102 DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3)
103 {m_groupParameters.Initialize(v1, v2, v3);}
104
105 /// \brief Construct a Diffie-Hellman domain
106 /// \tparam T1 template parameter used as a constructor parameter
107 /// \tparam T2 template parameter used as a constructor parameter
108 /// \tparam T3 template parameter used as a constructor parameter
109 /// \tparam T4 template parameter used as a constructor parameter
110 /// \param v1 first parameter
111 /// \param v2 second parameter
112 /// \param v3 third parameter
113 /// \param v4 fourth parameter
114 /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
115 template <class T1, class T2, class T3, class T4>
116 DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
117 {m_groupParameters.Initialize(v1, v2, v3, v4);}
118
119 /// \brief Retrieves the group parameters for this domain
120 /// \return the group parameters for this domain as a const reference
121 const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
122 /// \brief Retrieves the group parameters for this domain
123 /// \return the group parameters for this domain as a non-const reference
124 GroupParameters & AccessGroupParameters() {return m_groupParameters;}
125
126 /// \brief Generate a public key from a private key in this domain
127 /// \param rng RandomNumberGenerator derived class
128 /// \param privateKey byte buffer with the previously generated private key
129 /// \param publicKey byte buffer for the generated public key in this domain
130 /// \details If using a FIPS 140-2 validated library on Windows, then this class will perform
131 /// a self test to ensure the key pair is pairwise consistent. Non-FIPS and non-Windows
132 /// builds of the library do not provide FIPS validated cryptography, so the code should be
133 /// removed by the optimizer.
134 /// \pre <tt>COUNTOF(publicKey) == PublicKeyLength()</tt>
135 void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
136 {
137 Base::GeneratePublicKey(rng, privateKey, publicKey);
138
140 {
141 SecByteBlock privateKey2(this->PrivateKeyLength());
142 this->GeneratePrivateKey(rng, privateKey2);
143
144 SecByteBlock publicKey2(this->PublicKeyLength());
145 Base::GeneratePublicKey(rng, privateKey2, publicKey2);
146
147 SecByteBlock agreedValue(this->AgreedValueLength()), agreedValue2(this->AgreedValueLength());
148 bool agreed1 = this->Agree(agreedValue, privateKey, publicKey2);
149 bool agreed2 = this->Agree(agreedValue2, privateKey2, publicKey);
150
151 if (!agreed1 || !agreed2 || agreedValue != agreedValue2)
152 throw SelfTestFailure(this->AlgorithmName() + ": pairwise consistency test failed");
153 }
154 }
155
156 static std::string CRYPTOPP_API StaticAlgorithmName()
157 {return GroupParameters::StaticAlgorithmNamePrefix() + DH_Algorithm::StaticAlgorithmName();}
158 std::string AlgorithmName() const {return StaticAlgorithmName();}
159
160private:
161 const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
162 {return Singleton<DH_Algorithm>().Ref();}
163 DL_GroupParameters<Element> & AccessAbstractGroupParameters()
164 {return m_groupParameters;}
165
166 GroupParameters m_groupParameters;
167};
168
170
171/// \brief Diffie-Hellman in GF(p)
172/// \details DH() class is a typedef of DH_Domain(). The documentation that follows
173/// does not exist. Rather the documentation was created in response to <a href="https://github.com/weidai11/cryptopp/issues/328">Issue
174/// 328, Diffie-Hellman example code not compiling</a>.
175/// \details Generally speaking, a DH() object is ephemeral and is intended to execute one instance of the Diffie-Hellman protocol. The
176/// private and public key parts are not intended to be set or persisted. Rather, a new set of domain parameters are generated each
177/// time an object is created.
178/// \details Once a DH() object is created, once can retrieve the ephemeral public key for the other party with code similar to the
179/// following.
180/// <pre> AutoSeededRandomPool prng;
181/// Integer p, q, g;
182/// PrimeAndGenerator pg;
183///
184/// pg.Generate(1, prng, 512, 511);
185/// p = pg.Prime();
186/// q = pg.SubPrime();
187/// g = pg.Generator();
188///
189/// DH dh(p, q, g);
190/// SecByteBlock t1(dh.PrivateKeyLength()), t2(dh.PublicKeyLength());
191/// dh.GenerateKeyPair(prng, t1, t2);
192/// Integer k1(t1, t1.size()), k2(t2, t2.size());
193///
194/// cout << "Private key:\n";
195/// cout << hex << k1 << endl;
196///
197/// cout << "Public key:\n";
198/// cout << hex << k2 << endl;</pre>
199///
200/// \details Output of the program above will be similar to the following.
201/// <pre> $ ./cryptest.exe
202/// Private key:
203/// 72b45a42371545e9d4880f48589aefh
204/// Public key:
205/// 45fdb13f97b1840626f0250cec1dba4a23b894100b51fb5d2dd13693d789948f8bfc88f9200014b2
206/// ba8dd8a6debc471c69ef1e2326c61184a2eca88ec866346bh</pre>
207/// \sa <a href="http://www.cryptopp.com/wiki/Diffie-Hellman">Diffie-Hellman on the Crypto++ wiki</a> and
208/// <a href="http://www.weidai.com/scan-mirror/ka.html#DH">Diffie-Hellman</a> in GF(p) with key validation
209/// \since Crypto++ 1.0
210#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
211struct DH : public DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime>
212{
214 typedef GroupParameters::Element Element;
215
216 virtual ~DH() {}
217
218 /// \brief Create an uninitialized Diffie-Hellman object
219 DH() : DH_Domain() {}
220
221 /// \brief Initialize a Diffie-Hellman object
222 /// \param bt BufferedTransformation with group parameters and options
224
225 /// \brief Initialize a Diffie-Hellman object
226 /// \param params group parameters and options
227 DH(const GroupParameters &params) : DH_Domain(params) {}
228
229 /// \brief Create a Diffie-Hellman object
230 /// \param rng a RandomNumberGenerator derived class
231 /// \param modulusBits the size of the modulus, in bits
232 /// \details This function overload of Initialize() creates a new Diffie-Hellman object because it
233 /// takes a RandomNumberGenerator() as a parameter.
234 DH(RandomNumberGenerator &rng, unsigned int modulusBits) : DH_Domain(rng, modulusBits) {}
235
236 /// \brief Initialize a Diffie-Hellman object
237 /// \param p the modulus
238 /// \param g the generator
239 DH(const Integer &p, const Integer &g) : DH_Domain(p, g) {}
240
241 /// \brief Initialize a Diffie-Hellman object
242 /// \param p the modulus
243 /// \param q the subgroup order
244 /// \param g the generator
245 DH(const Integer &p, const Integer &q, const Integer &g) : DH_Domain(p, q, g) {}
246
247 /// \brief Creates a Diffie-Hellman object
248 /// \param rng a RandomNumberGenerator derived class
249 /// \param modulusBits the size of the modulus, in bits
250 /// \details This function overload of Initialize() creates a new Diffie-Hellman object because it
251 /// takes a RandomNumberGenerator() as a parameter.
252 void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
253 {AccessGroupParameters().Initialize(rng, modulusBits);}
254
255 /// \brief Initialize a Diffie-Hellman object
256 /// \param p the modulus
257 /// \param g the generator
258 void Initialize(const Integer &p, const Integer &g)
259 {AccessGroupParameters().Initialize(p, g);}
260
261 /// \brief Initialize a Diffie-Hellman object
262 /// \param p the modulus
263 /// \param q the subgroup order
264 /// \param g the generator
265 void Initialize(const Integer &p, const Integer &q, const Integer &g)
266 {AccessGroupParameters().Initialize(p, q, g);}
267};
268#else
269// The real DH class is a typedef.
271#endif
272
273NAMESPACE_END
274
275#endif
Classes for performing mathematics over different fields.
Interface for buffered transformations.
Definition: cryptlib.h:1652
Diffie-Hellman domain.
Definition: dh.h:26
const GroupParameters & GetGroupParameters() const
Retrieves the group parameters for this domain.
Definition: dh.h:121
DH_Domain(BufferedTransformation &bt)
Construct a Diffie-Hellman domain.
Definition: dh.h:47
DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3)
Create a Diffie-Hellman domain.
Definition: dh.h:67
std::string AlgorithmName() const
Provides the name of this algorithm.
Definition: dh.h:158
DH_Domain(const GroupParameters &params)
Construct a Diffie-Hellman domain.
Definition: dh.h:42
DH_Domain(RandomNumberGenerator &v1, const T2 &v2)
Create a Diffie-Hellman domain.
Definition: dh.h:56
DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3, const T4 &v4)
Create a Diffie-Hellman domain.
Definition: dh.h:80
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
Definition: dh.h:135
DH_Domain()
Construct a Diffie-Hellman domain.
Definition: dh.h:38
DH_Domain(const T1 &v1, const T2 &v2)
Construct a Diffie-Hellman domain.
Definition: dh.h:90
GroupParameters & AccessGroupParameters()
Retrieves the group parameters for this domain.
Definition: dh.h:124
DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
Construct a Diffie-Hellman domain.
Definition: dh.h:116
DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3)
Construct a Diffie-Hellman domain.
Definition: dh.h:102
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:782
Diffie-Hellman key agreement algorithm.
Definition: pubkey.h:2142
Interface for DL key agreement algorithms.
Definition: pubkey.h:1477
Discrete Log (DL) simple key agreement base implementation.
Definition: pubkey.h:2064
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Definition: pubkey.h:2090
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Definition: pubkey.h:2075
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
Definition: pubkey.h:2081
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
Interface for random number generators.
Definition: cryptlib.h:1435
SecBlock<byte> typedef.
Definition: secblock.h:1226
Exception thrown when a crypto algorithm is used after a self test fails.
Definition: fips140.h:23
Restricts the instantiation of a class to one static object without locks.
Definition: misc.h:307
const T & Ref(...) const
Return a reference to the inner Singleton object.
Definition: misc.h:327
#define CRYPTOPP_API
Win32 calling convention.
Definition: config_dll.h:119
#define CRYPTOPP_DLL_TEMPLATE_CLASS
Instantiate templates in a dynamic library.
Definition: config_dll.h:72
Abstract base classes that provide a uniform interface to this library.
CRYPTOPP_DLL bool FIPS_140_2_ComplianceEnabled()
Determines whether the library provides FIPS validated cryptography.
Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
Crypto++ library namespace.
Diffie-Hellman in GF(p)
Definition: dh.h:212
DH(BufferedTransformation &bt)
Initialize a Diffie-Hellman object.
Definition: dh.h:223
DH(const Integer &p, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:239
DH()
Create an uninitialized Diffie-Hellman object.
Definition: dh.h:219
DH(RandomNumberGenerator &rng, unsigned int modulusBits)
Create a Diffie-Hellman object.
Definition: dh.h:234
DH(const GroupParameters &params)
Initialize a Diffie-Hellman object.
Definition: dh.h:227
void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
Creates a Diffie-Hellman object.
Definition: dh.h:252
void Initialize(const Integer &p, const Integer &q, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:265
void Initialize(const Integer &p, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:258
DH(const Integer &p, const Integer &q, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:245