Crypto++ 8.4 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 {
27 typedef DL_SimpleKeyAgreementDomainBase<typename GROUP_PARAMETERS::Element> Base;
28
29 public:
30 typedef GROUP_PARAMETERS GroupParameters;
31 typedef typename GroupParameters::Element Element;
32 typedef DL_KeyAgreementAlgorithm_DH<Element, COFACTOR_OPTION> DH_Algorithm;
33 typedef DH_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain;
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
47 DH_Domain(BufferedTransformation &bt)
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
139 if (FIPS_140_2_ComplianceEnabled())
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 {
213 typedef DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime> GroupParameters;
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
223 DH(BufferedTransformation &bt) : DH_Domain(bt) {}
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.
270 typedef DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime> DH;
271 #endif
272
273 NAMESPACE_END
274
275 #endif
DH_Domain::DH_Domain
DH_Domain()
Construct a Diffie-Hellman domain.
Definition: dh.h:38
Singleton::Ref
const T & Ref(...) const
Return a reference to the inner Singleton object.
Definition: misc.h:325
DL_SimpleKeyAgreementDomainBase< GROUP_PARAMETERS::Element >::PublicKeyLength
unsigned int PublicKeyLength() const
Definition: pubkey.h:2063
DH::DH
DH(const Integer &p, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:239
DL_SimpleKeyAgreementDomainBase< GROUP_PARAMETERS::Element >::Agree
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Definition: pubkey.h:2080
DH_Domain::GetGroupParameters
const GroupParameters & GetGroupParameters() const
Retrieves the group parameters for this domain.
Definition: dh.h:121
DH_Domain::AlgorithmName
std::string AlgorithmName() const
Provides the name of this algorithm.
Definition: dh.h:158
BufferedTransformation
Interface for buffered transformations.
Definition: cryptlib.h:1634
DH::DH
DH(const Integer &p, const Integer &q, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:245
SecByteBlock
SecBlock<byte> typedef.
Definition: secblock.h:1115
DL_KeyAgreementAlgorithm
Interface for DL key agreement algorithms.
Definition: pubkey.h:1473
DL_SimpleKeyAgreementDomainBase::GeneratePublicKey
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
Definition: pubkey.h:2071
gfpcrypt.h
Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
DH::DH
DH(const GroupParameters &params)
Initialize a Diffie-Hellman object.
Definition: dh.h:227
Singleton
Restricts the instantiation of a class to one static object without locks.
Definition: misc.h:304
DL_SimpleKeyAgreementDomainBase< GROUP_PARAMETERS::Element >::AgreedValueLength
unsigned int AgreedValueLength() const
Definition: pubkey.h:2061
DH::DH
DH(BufferedTransformation &bt)
Initialize a Diffie-Hellman object.
Definition: dh.h:223
DH_Domain::DH_Domain
DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3)
Construct a Diffie-Hellman domain.
Definition: dh.h:102
RandomNumberGenerator
Interface for random number generators.
Definition: cryptlib.h:1417
DH_Domain::AccessGroupParameters
GroupParameters & AccessGroupParameters()
Retrieves the group parameters for this domain.
Definition: dh.h:124
DH::DH
DH()
Create an uninitialized Diffie-Hellman object.
Definition: dh.h:219
DH_Domain::DH_Domain
DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3)
Create a Diffie-Hellman domain.
Definition: dh.h:67
DH_Domain::DH_Domain
DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3, const T4 &v4)
Create a Diffie-Hellman domain.
Definition: dh.h:80
DH
Diffie-Hellman in GF(p)
Definition: dh.h:211
DH_Domain::DH_Domain
DH_Domain(BufferedTransformation &bt)
Construct a Diffie-Hellman domain.
Definition: dh.h:47
DH::Initialize
void Initialize(const Integer &p, const Integer &q, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:265
DL_SimpleKeyAgreementDomainBase< GROUP_PARAMETERS::Element >::GeneratePrivateKey
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Definition: pubkey.h:2065
DH_Domain::GeneratePublicKey
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
DL_SimpleKeyAgreementDomainBase< GROUP_PARAMETERS::Element >::PrivateKeyLength
unsigned int PrivateKeyLength() const
Definition: pubkey.h:2062
DH::Initialize
void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
Creates a Diffie-Hellman object.
Definition: dh.h:252
DH_Domain::DH_Domain
DH_Domain(const T1 &v1, const T2 &v2)
Construct a Diffie-Hellman domain.
Definition: dh.h:90
DH_Domain::DH_Domain
DH_Domain(RandomNumberGenerator &v1, const T2 &v2)
Create a Diffie-Hellman domain.
Definition: dh.h:56
DH::Initialize
void Initialize(const Integer &p, const Integer &g)
Initialize a Diffie-Hellman object.
Definition: dh.h:258
DL_KeyAgreementAlgorithm_DH
Diffie-Hellman key agreement algorithm.
Definition: pubkey.h:2131
FIPS_140_2_ComplianceEnabled
CRYPTOPP_DLL bool FIPS_140_2_ComplianceEnabled()
Determines whether the library provides FIPS validated cryptography.
DH_Domain::DH_Domain
DH_Domain(const GroupParameters &params)
Construct a Diffie-Hellman domain.
Definition: dh.h:42
algebra.h
Classes for performing mathematics over different fields.
CryptoPP
Crypto++ library namespace.
CRYPTOPP_API
#define CRYPTOPP_API
Win32 calling convention.
Definition: config_dll.h:119
CRYPTOPP_DLL_TEMPLATE_CLASS
#define CRYPTOPP_DLL_TEMPLATE_CLASS
Instantiate templates in a dynamic library.
Definition: config_dll.h:72
DL_GroupParameters
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:781
DH::DH
DH(RandomNumberGenerator &rng, unsigned int modulusBits)
Create a Diffie-Hellman object.
Definition: dh.h:234
DH_Domain::DH_Domain
DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
Construct a Diffie-Hellman domain.
Definition: dh.h:116
DL_GroupParameters_GFP_DefaultSafePrime
GF(p) group parameters that default to safe primes.
Definition: gfpcrypt.h:274
DL_SimpleKeyAgreementDomainBase
Discrete Log (DL) simple key agreement base implementation.
Definition: pubkey.h:2053
cryptlib.h
Abstract base classes that provide a uniform interface to this library.
DH_Domain
Diffie-Hellman domain.
Definition: dh.h:25
SelfTestFailure
Exception thrown when a crypto algorithm is used after a self test fails.
Definition: fips140.h:22
Integer
Multiple precision integer with arithmetic operations.
Definition: integer.h:49