Crypto++  5.6.5
Free C++ class library of cryptographic schemes
dh.h
Go to the documentation of this file.
1 // dh.h - 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 //! \class DH_Domain
16 //! \brief Diffie-Hellman domain
17 //! \tparam GROUP_PARAMETERS group parameters
18 //! \tparam COFACTOR_OPTION \ref CofactorMultiplicationOption "cofactor multiplication option"
19 //! \details A Diffie-Hellman domain is a set of parameters that must be shared
20 //! by two parties in a key agreement protocol, along with the algorithms
21 //! for generating key pairs and deriving agreed values.
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 {
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
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(const Integer &p, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:239
Diffie-Hellman key agreement algorithm.
Definition: pubkey.h:1898
Restricts the instantiation of a class to one static object without locks.
Definition: misc.h:274
std::string AlgorithmName() const
Provides the name of this algorithm.
Definition: dh.h:158
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:730
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:1188
DH(BufferedTransformation &bt)
Initialize a Diffie-Hellman object.
Definition: dh.h:223
SecBlock typedef.
Definition: secblock.h:731
Classes for performing mathematics over different fields.
Interface for buffered transformations.
Definition: cryptlib.h:1352
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
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:23
DH()
Create an uninitialized Diffie-Hellman object.
Definition: dh.h:219
Multiple precision integer with arithmetic operations.
Definition: integer.h:43
void Initialize(const Integer &p, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:258
void Initialize(const Integer &p, const Integer &q, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:265
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
const GroupParameters & GetGroupParameters() const
Retrieves the group parameters for this domain.
Definition: dh.h:121
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:1272
Discrete Log (DL) simple key agreement base implementation.
Definition: pubkey.h:1820
DH_Domain(const T1 &v1, const T2 &v2)
Construct a Diffie-Hellman domain.
Definition: dh.h:90