Crypto++ 8.7
Free C++ class library of cryptographic schemes
fhmqv.h
Go to the documentation of this file.
1// fhmqv.h - written and placed in the public domain by Jeffrey Walton, Ray Clayton and Uri Blumenthal
2// Shamelessly based upon Wei Dai's MQV source files
3
4#ifndef CRYPTOPP_FHMQV_H
5#define CRYPTOPP_FHMQV_H
6
7/// \file fhmqv.h
8/// \brief Classes for Fully Hashed Menezes-Qu-Vanstone key agreement in GF(p)
9/// \since Crypto++ 5.6.4
10
11#include "gfpcrypt.h"
12#include "algebra.h"
13#include "sha.h"
14
15NAMESPACE_BEGIN(CryptoPP)
16
17/// \brief Fully Hashed Menezes-Qu-Vanstone in GF(p)
18/// \details This implementation follows Augustin P. Sarr and Philippe Elbaz–Vincent, and Jean–Claude Bajard's
19/// <a href="http://eprint.iacr.org/2009/408">A Secure and Efficient Authenticated Diffie-Hellman Protocol</a>.
20/// Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C.
21/// \sa MQV, HMQV, FHMQV, and AuthenticatedKeyAgreementDomain
22/// \since Crypto++ 5.6.4
23template <class GROUP_PARAMETERS, class COFACTOR_OPTION = typename GROUP_PARAMETERS::DefaultCofactorOption, class HASH = SHA512>
25{
26public:
27 typedef GROUP_PARAMETERS GroupParameters;
28 typedef typename GroupParameters::Element Element;
30
31 virtual ~FHMQV_Domain() {}
32
33 /// \brief Construct a FHMQV domain
34 /// \param clientRole flag indicating initiator or recipient
35 /// \details <tt>clientRole = true</tt> indicates initiator, and
36 /// <tt>clientRole = false</tt> indicates recipient or server.
37 FHMQV_Domain(bool clientRole = true)
38 : m_role(clientRole ? RoleClient : RoleServer) {}
39
40 /// \brief Construct a FHMQV domain
41 /// \param params group parameters and options
42 /// \param clientRole flag indicating initiator or recipient
43 /// \details <tt>clientRole = true</tt> indicates initiator, and
44 /// <tt>clientRole = false</tt> indicates recipient or server.
45 FHMQV_Domain(const GroupParameters &params, bool clientRole = true)
46 : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {}
47
48 /// \brief Construct a FHMQV domain
49 /// \param bt BufferedTransformation with group parameters and options
50 /// \param clientRole flag indicating initiator or recipient
51 /// \details <tt>clientRole = true</tt> indicates initiator, and
52 /// <tt>clientRole = false</tt> indicates recipient or server.
53 FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true)
54 : m_role(clientRole ? RoleClient : RoleServer)
55 {m_groupParameters.BERDecode(bt);}
56
57 /// \brief Construct a FHMQV domain
58 /// \tparam T1 template parameter used as a constructor parameter
59 /// \param v1 first parameter
60 /// \param clientRole flag indicating initiator or recipient
61 /// \details v1 is passed directly to the GROUP_PARAMETERS object.
62 /// \details <tt>clientRole = true</tt> indicates initiator, and
63 /// <tt>clientRole = false</tt> indicates recipient or server.
64 template <class T1>
65 FHMQV_Domain(T1 v1, bool clientRole = true)
66 : m_role(clientRole ? RoleClient : RoleServer)
67 {m_groupParameters.Initialize(v1);}
68
69 /// \brief Construct a FHMQV domain
70 /// \tparam T1 template parameter used as a constructor parameter
71 /// \tparam T2 template parameter used as a constructor parameter
72 /// \param v1 first parameter
73 /// \param v2 second parameter
74 /// \param clientRole flag indicating initiator or recipient
75 /// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
76 /// \details <tt>clientRole = true</tt> indicates initiator, and
77 /// <tt>clientRole = false</tt> indicates recipient or server.
78 template <class T1, class T2>
79 FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true)
80 : m_role(clientRole ? RoleClient : RoleServer)
81 {m_groupParameters.Initialize(v1, v2);}
82
83 /// \brief Construct a FHMQV domain
84 /// \tparam T1 template parameter used as a constructor parameter
85 /// \tparam T2 template parameter used as a constructor parameter
86 /// \tparam T3 template parameter used as a constructor parameter
87 /// \param v1 first parameter
88 /// \param v2 second parameter
89 /// \param v3 third parameter
90 /// \param clientRole flag indicating initiator or recipient
91 /// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
92 /// \details <tt>clientRole = true</tt> indicates initiator, and
93 /// <tt>clientRole = false</tt> indicates recipient or server.
94 template <class T1, class T2, class T3>
95 FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true)
96 : m_role(clientRole ? RoleClient : RoleServer)
97 {m_groupParameters.Initialize(v1, v2, v3);}
98
99 /// \brief Construct a FHMQV domain
100 /// \tparam T1 template parameter used as a constructor parameter
101 /// \tparam T2 template parameter used as a constructor parameter
102 /// \tparam T3 template parameter used as a constructor parameter
103 /// \tparam T4 template parameter used as a constructor parameter
104 /// \param v1 first parameter
105 /// \param v2 second parameter
106 /// \param v3 third parameter
107 /// \param v4 third parameter
108 /// \param clientRole flag indicating initiator or recipient
109 /// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
110 /// \details <tt>clientRole = true</tt> indicates initiator, and
111 /// <tt>clientRole = false</tt> indicates recipient or server.
112 template <class T1, class T2, class T3, class T4>
113 FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true)
114 : m_role(clientRole ? RoleClient : RoleServer)
115 {m_groupParameters.Initialize(v1, v2, v3, v4);}
116
117public:
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
123 /// \brief Retrieves the group parameters for this domain
124 /// \return the group parameters for this domain as a non-const reference
125 GroupParameters & AccessGroupParameters() {return m_groupParameters;}
126
127 /// \brief Retrieves the crypto parameters for this domain
128 /// \return the crypto parameters for this domain as a non-const reference
129 CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
130
131 /// \brief Provides the size of the agreed value
132 /// \return size of agreed value produced in this domain
133 /// \details The length is calculated using <tt>GetEncodedElementSize(false)</tt>,
134 /// which means the element is encoded in a non-reversible format. A
135 /// non-reversible format means its a raw byte array, and it lacks presentation
136 /// format like an ASN.1 BIT_STRING or OCTET_STRING.
137 unsigned int AgreedValueLength() const
138 {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
139
140 /// \brief Provides the size of the static private key
141 /// \return size of static private keys in this domain
142 /// \details The length is calculated using the byte count of the subgroup order.
143 unsigned int StaticPrivateKeyLength() const
144 {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
145
146 /// \brief Provides the size of the static public key
147 /// \return size of static public keys in this domain
148 /// \details The length is calculated using <tt>GetEncodedElementSize(true)</tt>,
149 /// which means the element is encoded in a reversible format. A reversible
150 /// format means it has a presentation format, and its an ANS.1 encoded element
151 /// or point.
152 unsigned int StaticPublicKeyLength() const
153 {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
154
155 /// \brief Generate static private key in this domain
156 /// \param rng a RandomNumberGenerator derived class
157 /// \param privateKey a byte buffer for the generated private key in this domain
158 /// \details The private key is a random scalar used as an exponent in the range
159 /// <tt>[1,MaxExponent()]</tt>.
160 /// \pre <tt>COUNTOF(privateKey) == PrivateStaticKeyLength()</tt>
161 void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
162 {
163 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
164 x.Encode(privateKey, StaticPrivateKeyLength());
165 }
166
167 /// \brief Generate a static public key from a private key in this domain
168 /// \param rng a RandomNumberGenerator derived class
169 /// \param privateKey a byte buffer with the previously generated private key
170 /// \param publicKey a byte buffer for the generated public key in this domain
171 /// \details The public key is an element or point on the curve, and its stored
172 /// in a revrsible format. A reversible format means it has a presentation
173 /// format, and its an ANS.1 encoded element or point.
174 /// \pre <tt>COUNTOF(publicKey) == PublicStaticKeyLength()</tt>
175 void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
176 {
177 CRYPTOPP_UNUSED(rng);
178 const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
179 Integer x(privateKey, StaticPrivateKeyLength());
180 Element y = params.ExponentiateBase(x);
181 params.EncodeElement(true, y, publicKey);
182 }
183
184 /// \brief Provides the size of the ephemeral private key
185 /// \return size of ephemeral private keys in this domain
186 /// \details An ephemeral private key is a private key and public key.
187 /// The serialized size is different than a static private key.
189
190 /// \brief Provides the size of the ephemeral public key
191 /// \return size of ephemeral public keys in this domain
192 /// \details An ephemeral public key is a public key.
193 /// The serialized size is the same as a static public key.
194 unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();}
195
196 /// \brief Generate ephemeral private key in this domain
197 /// \param rng a RandomNumberGenerator derived class
198 /// \param privateKey a byte buffer for the generated private key in this domain
199 /// \pre <tt>COUNTOF(privateKey) == EphemeralPrivateKeyLength()</tt>
200 void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
201 {
202 const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
203 Integer x(rng, Integer::One(), params.GetMaxExponent());
204 x.Encode(privateKey, StaticPrivateKeyLength());
205 Element y = params.ExponentiateBase(x);
206 params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
207 }
208
209 /// \brief Generate ephemeral public key from a private key in this domain
210 /// \param rng a RandomNumberGenerator derived class
211 /// \param privateKey a byte buffer with the previously generated private key
212 /// \param publicKey a byte buffer for the generated public key in this domain
213 /// \pre <tt>COUNTOF(publicKey) == EphemeralPublicKeyLength()</tt>
214 void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
215 {
216 CRYPTOPP_UNUSED(rng);
217 memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
218 }
219
220 /// \brief Derive agreed value or shared secret
221 /// \param agreedValue the shared secret
222 /// \param staticPrivateKey your long term private key
223 /// \param ephemeralPrivateKey your ephemeral private key
224 /// \param staticOtherPublicKey couterparty's long term public key
225 /// \param ephemeralOtherPublicKey couterparty's ephemeral public key
226 /// \param validateStaticOtherPublicKey flag indicating validation
227 /// \return true upon success, false in case of failure
228 /// \details Agree() performs the authenticated key agreement. Agree()
229 /// derives a shared secret from your private keys and couterparty's
230 /// public keys. Each instance or run of the protocol should use a new
231 /// ephemeral key pair.
232 /// \details The other's ephemeral public key will always be validated at
233 /// Level 1 to ensure it is a point on the curve.
234 /// <tt>validateStaticOtherPublicKey</tt> determines how thoroughly other's
235 /// static public key is validated. If you have previously validated the
236 /// couterparty's static public key, then use
237 /// <tt>validateStaticOtherPublicKey=false</tt> to save time.
238 /// \pre <tt>COUNTOF(agreedValue) == AgreedValueLength()</tt>
239 /// \pre <tt>COUNTOF(staticPrivateKey) == StaticPrivateKeyLength()</tt>
240 /// \pre <tt>COUNTOF(ephemeralPrivateKey) == EphemeralPrivateKeyLength()</tt>
241 /// \pre <tt>COUNTOF(staticOtherPublicKey) == StaticPublicKeyLength()</tt>
242 /// \pre <tt>COUNTOF(ephemeralOtherPublicKey) == EphemeralPublicKeyLength()</tt>
243 bool Agree(byte *agreedValue,
244 const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
245 const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
246 bool validateStaticOtherPublicKey=true) const
247 {
248 const byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR;
249 size_t xxs = 0, yys = 0, aas = 0, bbs = 0;
250
251 // Depending on the role, this will hold either A's or B's static
252 // (long term) public key. AA or BB will then point into tt.
254
255 try
256 {
258 const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
259
260 if(m_role == RoleServer)
261 {
262 Integer b(staticPrivateKey, StaticPrivateKeyLength());
263 Element B = params.ExponentiateBase(b);
264 params.EncodeElement(true, B, tt);
265
266 XX = ephemeralOtherPublicKey;
268 YY = ephemeralPrivateKey + StaticPrivateKeyLength();
270 AA = staticOtherPublicKey;
271 aas = StaticPublicKeyLength();
272 BB = tt.BytePtr();
273 bbs = tt.SizeInBytes();
274 }
275 else
276 {
277 Integer a(staticPrivateKey, StaticPrivateKeyLength());
278 Element A = params.ExponentiateBase(a);
279 params.EncodeElement(true, A, tt);
280
281 XX = ephemeralPrivateKey + StaticPrivateKeyLength();
283 YY = ephemeralOtherPublicKey;
285 AA = tt.BytePtr();
286 aas = tt.SizeInBytes();
287 BB = staticOtherPublicKey;
288 bbs = StaticPublicKeyLength();
289 }
290
291 Element VV1 = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
292 Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, true);
293
294 const Integer& q = params.GetSubgroupOrder();
295 const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8);
296 SecByteBlock dd(len), ee(len);
297
298 Hash(NULLPTR, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes());
299 Integer d(dd.BytePtr(), dd.SizeInBytes());
300
301 Hash(NULLPTR, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes());
302 Integer e(ee.BytePtr(), ee.SizeInBytes());
303
304 Element sigma;
305 if(m_role == RoleServer)
306 {
307 Integer y(ephemeralPrivateKey, StaticPrivateKeyLength());
308 Integer b(staticPrivateKey, StaticPrivateKeyLength());
309 Integer s_B = (y + e * b) % q;
310
311 Element A = params.DecodeElement(AA, false);
312 Element X = params.DecodeElement(XX, false);
313
314 Element t1 = params.ExponentiateElement(A, d);
315 Element t2 = m_groupParameters.MultiplyElements(X, t1);
316
317 sigma = params.ExponentiateElement(t2, s_B);
318 }
319 else
320 {
321 Integer x(ephemeralPrivateKey, StaticPrivateKeyLength());
322 Integer a(staticPrivateKey, StaticPrivateKeyLength());
323 Integer s_A = (x + d * a) % q;
324
325 Element B = params.DecodeElement(BB, false);
326 Element Y = params.DecodeElement(YY, false);
327
328 Element t1 = params.ExponentiateElement(B, e);
329 Element t2 = m_groupParameters.MultiplyElements(Y, t1);
330
331 sigma = params.ExponentiateElement(t2, s_A);
332 }
333
334 Hash(&sigma, XX, xxs, YY, yys, AA, aas, BB, bbs, agreedValue, AgreedValueLength());
335 }
336 catch (DL_BadElement &)
337 {
339 return false;
340 }
341 return true;
342 }
343
344protected:
345
346 inline void Hash(const Element* sigma,
347 const byte* e1, size_t e1len, const byte* e2, size_t e2len,
348 const byte* s1, size_t s1len, const byte* s2, size_t s2len,
349 byte* digest, size_t dlen) const
350 {
351 HASH hash;
352 size_t idx = 0, req = dlen;
353 size_t blk = STDMIN(dlen, (size_t)HASH::DIGESTSIZE);
354
355 if(sigma)
356 {
357 //Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma);
358 //SecByteBlock sbb(x.MinEncodedSize());
359 //x.Encode(sbb.BytePtr(), sbb.SizeInBytes());
360 SecByteBlock sbb(GetAbstractGroupParameters().GetEncodedElementSize(false));
361 GetAbstractGroupParameters().EncodeElement(false, *sigma, sbb);
362 hash.Update(sbb.BytePtr(), sbb.SizeInBytes());
363 }
364
365 hash.Update(e1, e1len);
366 hash.Update(e2, e2len);
367 hash.Update(s1, s1len);
368 hash.Update(s2, s2len);
369
370 hash.TruncatedFinal(digest, blk);
371 req -= blk;
372
373 // All this to catch tail bytes for large curves and small hashes
374 while(req != 0)
375 {
376 hash.Update(&digest[idx], (size_t)HASH::DIGESTSIZE);
377
378 idx += (size_t)HASH::DIGESTSIZE;
379 blk = STDMIN(req, (size_t)HASH::DIGESTSIZE);
380 hash.TruncatedFinal(&digest[idx], blk);
381
382 req -= blk;
383 }
384 }
385
386private:
387
388 // The paper uses Initiator and Recipient - make it classical.
389 enum KeyAgreementRole { RoleServer = 1, RoleClient };
390
391 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
392 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const{return m_groupParameters;}
393
394 GroupParameters m_groupParameters;
395 KeyAgreementRole m_role;
396};
397
398/// \brief Fully Hashed Menezes-Qu-Vanstone in GF(p)
399/// \details This implementation follows Augustin P. Sarr and Philippe Elbaz–Vincent, and Jean–Claude Bajard's
400/// <a href="http://eprint.iacr.org/2009/408">A Secure and Efficient Authenticated Diffie-Hellman Protocol</a>.
401/// Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C.
402/// \sa FHMQV, MQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain
403/// \since Crypto++ 5.6.4
405
406NAMESPACE_END
407
408#endif
Classes for performing mathematics over different fields.
Interface for domains of authenticated key agreement protocols.
Definition: cryptlib.h:3072
Interface for buffered transformations.
Definition: cryptlib.h:1652
void DoQuickSanityCheck() const
Perform a quick sanity check.
Definition: cryptlib.h:2493
Interface for crypto parameters.
Definition: cryptlib.h:2546
Exception thrown when an invalid group element is encountered.
Definition: pubkey.h:772
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:782
virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
Exponentiates an element.
Definition: pubkey.h:879
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
virtual Integer GetMaxExponent() const =0
Retrieves the maximum exponent for the group.
virtual const Integer & GetSubgroupOrder() const =0
Retrieves the subgroup order.
virtual Element ExponentiateBase(const Integer &exponent) const
Exponentiates the base.
Definition: pubkey.h:869
virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0
Decodes the element.
Fully Hashed Menezes-Qu-Vanstone in GF(p)
Definition: fhmqv.h:25
FHMQV_Domain(bool clientRole=true)
Construct a FHMQV domain.
Definition: fhmqv.h:37
unsigned int AgreedValueLength() const
Provides the size of the agreed value.
Definition: fhmqv.h:137
FHMQV_Domain(const GroupParameters &params, bool clientRole=true)
Construct a FHMQV domain.
Definition: fhmqv.h:45
unsigned int EphemeralPublicKeyLength() const
Provides the size of the ephemeral public key.
Definition: fhmqv.h:194
FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole=true)
Construct a FHMQV domain.
Definition: fhmqv.h:95
CryptoParameters & AccessCryptoParameters()
Retrieves the crypto parameters for this domain.
Definition: fhmqv.h:129
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a static public key from a private key in this domain.
Definition: fhmqv.h:175
unsigned int EphemeralPrivateKeyLength() const
Provides the size of the ephemeral private key.
Definition: fhmqv.h:188
FHMQV_Domain(BufferedTransformation &bt, bool clientRole=true)
Construct a FHMQV domain.
Definition: fhmqv.h:53
FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole=true)
Construct a FHMQV domain.
Definition: fhmqv.h:113
const GroupParameters & GetGroupParameters() const
Retrieves the group parameters for this domain.
Definition: fhmqv.h:121
GroupParameters & AccessGroupParameters()
Retrieves the group parameters for this domain.
Definition: fhmqv.h:125
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate ephemeral public key from a private key in this domain.
Definition: fhmqv.h:214
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate static private key in this domain.
Definition: fhmqv.h:161
bool Agree(byte *agreedValue, const byte *staticPrivateKey, const byte *ephemeralPrivateKey, const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, bool validateStaticOtherPublicKey=true) const
Derive agreed value or shared secret.
Definition: fhmqv.h:243
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate ephemeral private key in this domain.
Definition: fhmqv.h:200
FHMQV_Domain(T1 v1, bool clientRole=true)
Construct a FHMQV domain.
Definition: fhmqv.h:65
unsigned int StaticPrivateKeyLength() const
Provides the size of the static private key.
Definition: fhmqv.h:143
FHMQV_Domain(T1 v1, T2 v2, bool clientRole=true)
Construct a FHMQV domain.
Definition: fhmqv.h:79
unsigned int StaticPublicKeyLength() const
Provides the size of the static public key.
Definition: fhmqv.h:152
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
static const Integer & One()
Integer representing 1.
const CryptoMaterial & GetMaterial() const
Retrieves a reference to Crypto Parameters.
Definition: cryptlib.h:2647
Interface for random number generators.
Definition: cryptlib.h:1435
size_type SizeInBytes() const
Provides the number of bytes in the SecBlock.
Definition: secblock.h:885
byte * BytePtr()
Provides a byte pointer to the first element in the memory block.
Definition: secblock.h:876
SecBlock<byte> typedef.
Definition: secblock.h:1226
FHMQV_Domain< DL_GroupParameters_GFP_DefaultSafePrime > FHMQV
Fully Hashed Menezes-Qu-Vanstone in GF(p)
Definition: fhmqv.h:404
Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:655
Crypto++ library namespace.
Classes for SHA-1 and SHA-2 family of message digests.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68