Crypto++  6.0
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 
13 NAMESPACE_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
24 template <class GROUP_PARAMETERS, class COFACTOR_OPTION = typename GROUP_PARAMETERS::DefaultCofactorOption>
25 class DH_Domain : public DL_SimpleKeyAgreementDomainBase<typename GROUP_PARAMETERS::Element>
26 {
28 
29 public:
30  typedef GROUP_PARAMETERS GroupParameters;
31  typedef typename GroupParameters::Element Element;
34 
35  virtual ~DH_Domain() {}
36 
37  /// \brief Construct a Diffie-Hellman domain
38  DH_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>
56  DH_Domain(RandomNumberGenerator &v1, const T2 &v2)
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 
160 private:
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 
169 CRYPTOPP_DLL_TEMPLATE_CLASS DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime>;
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)
211 struct 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 
273 NAMESPACE_END
274 
275 #endif
const GroupParameters & GetGroupParameters() const
Retrieves the group parameters for this domain.
Definition: dh.h:121
DH(const Integer &p, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:239
Diffie-Hellman key agreement algorithm.
Definition: pubkey.h:2059
Restricts the instantiation of a class to one static object without locks.
Definition: misc.h:291
DH(const Integer &p, const Integer &q, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:245
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:753
DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3, const T4 &v4)
Create a Diffie-Hellman domain.
Definition: dh.h:80
DH_Domain(BufferedTransformation &bt)
Construct a Diffie-Hellman domain.
Definition: dh.h:47
Abstract base classes that provide a uniform interface to this library.
Interface for random number generators.
Definition: cryptlib.h:1327
DH(BufferedTransformation &bt)
Initialize a Diffie-Hellman object.
Definition: dh.h:223
std::string AlgorithmName() const
Provides the name of this algorithm.
Definition: dh.h:158
SecBlock<byte> typedef.
Definition: secblock.h:822
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Definition: pubkey.h:1993
Classes for performing mathematics over different fields.
Interface for buffered transformations.
Definition: cryptlib.h:1472
DH(const GroupParameters &params)
Initialize a Diffie-Hellman object.
Definition: dh.h:227
DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
Construct a Diffie-Hellman domain.
Definition: dh.h:116
bool FIPS_140_2_ComplianceEnabled()
Determines whether the library provides FIPS validated cryptography.
Definition: fips140.cpp:29
DH_Domain(RandomNumberGenerator &v1, const T2 &v2)
Create a Diffie-Hellman domain.
Definition: dh.h:56
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
Definition: pubkey.h:1999
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
Diffie-Hellman in GF(p)
Definition: dh.h:211
Exception thrown when a crypto algorithm is used after a self test fails.
Definition: fips140.h:22
DH()
Create an uninitialized Diffie-Hellman object.
Definition: dh.h:219
Multiple precision integer with arithmetic operations.
Definition: integer.h:49
void Initialize(const Integer &p, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:258
Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
void Initialize(const Integer &p, const Integer &q, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:265
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Definition: pubkey.h:2008
DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3)
Construct a Diffie-Hellman domain.
Definition: dh.h:102
Diffie-Hellman domain.
Definition: dh.h:25
DH_Domain(const GroupParameters &params)
Construct a Diffie-Hellman domain.
Definition: dh.h:42
DH_Domain()
Construct a Diffie-Hellman domain.
Definition: dh.h:38
DH(RandomNumberGenerator &rng, unsigned int modulusBits)
Create a Diffie-Hellman object.
Definition: dh.h:234
DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3)
Create a Diffie-Hellman domain.
Definition: dh.h:67
void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
Creates a Diffie-Hellman object.
Definition: dh.h:252
Crypto++ library namespace.
GroupParameters & AccessGroupParameters()
Retrieves the group parameters for this domain.
Definition: dh.h:124
Interface for DL key agreement algorithms.
Definition: pubkey.h:1415
Discrete Log (DL) simple key agreement base implementation.
Definition: pubkey.h:1981
DH_Domain(const T1 &v1, const T2 &v2)
Construct a Diffie-Hellman domain.
Definition: dh.h:90