Crypto++ 8.7
Free C++ class library of cryptographic schemes
gfpcrypt.h
Go to the documentation of this file.
1// gfpcrypt.h - originally written and placed in the public domain by Wei Dai
2// RFC6979 deterministic signatures added by Douglas Roark
3// ECGDSA added by Jeffrey Walton
4
5/// \file gfpcrypt.h
6/// \brief Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
7
8#ifndef CRYPTOPP_GFPCRYPT_H
9#define CRYPTOPP_GFPCRYPT_H
10
11#include "config.h"
12
13#if CRYPTOPP_MSC_VERSION
14# pragma warning(push)
15# pragma warning(disable: 4189 4231 4275)
16#endif
17
18#include "cryptlib.h"
19#include "pubkey.h"
20#include "integer.h"
21#include "modexppc.h"
22#include "algparam.h"
23#include "smartptr.h"
24#include "sha.h"
25#include "asn.h"
26#include "hmac.h"
27#include "misc.h"
28
29NAMESPACE_BEGIN(CryptoPP)
30
32
33/// \brief Integer-based GroupParameters specialization
34class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial<DL_GroupParameters<Integer> >
35{
37
38public:
40
41 /// \brief Initialize a group parameters over integers
42 /// \param params the group parameters
44 {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());}
45
46 /// \brief Create a group parameters over integers
47 /// \param rng a RandomNumberGenerator derived class
48 /// \param pbits the size of p, in bits
49 /// \details This function overload of Initialize() creates a new private key because it
50 /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,
51 /// then use one of the other Initialize() overloads.
52 void Initialize(RandomNumberGenerator &rng, unsigned int pbits)
53 {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));}
54
55 /// \brief Initialize a group parameters over integers
56 /// \param p the modulus
57 /// \param g the generator
58 void Initialize(const Integer &p, const Integer &g)
59 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);}
60
61 /// \brief Initialize a group parameters over integers
62 /// \param p the modulus
63 /// \param q the subgroup order
64 /// \param g the generator
65 void Initialize(const Integer &p, const Integer &q, const Integer &g)
66 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);}
67
68 // ASN1Object interface
71
72 /// \brief Generate a random key
73 /// \param rng a RandomNumberGenerator to produce keying material
74 /// \param alg additional initialization parameters
75 /// \details Recognised NameValuePairs are ModulusSize and
76 /// SubgroupOrderSize (optional)
77 /// \throw KeyingErr if a key can't be generated or algorithm parameters
78 /// are invalid
80
81 /// \brief Get a named value
82 /// \param name the name of the object or value to retrieve
83 /// \param valueType reference to a variable that receives the value
84 /// \param pValue void pointer to a variable that receives the value
85 /// \return true if the value was retrieved, false otherwise
86 /// \details GetVoidValue() retrieves the value of name if it exists.
87 /// \note GetVoidValue() is an internal function and should be implemented
88 /// by derived classes. Users should use one of the other functions instead.
89 /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
90 /// GetRequiredParameter() and GetRequiredIntParameter()
91 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
92
93 /// \brief Initialize or reinitialize this key
94 /// \param source NameValuePairs to assign
95 void AssignFrom(const NameValuePairs &source);
96
97 // DL_GroupParameters
98 const Integer & GetSubgroupOrder() const {return m_q;}
99 Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();}
100 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
101 bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const;
102
103 /// \brief Determine if subgroup membership check is fast
104 /// \return true or false
105 bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;}
106
107 /// \brief Encodes the element
108 /// \param reversible flag indicating the encoding format
109 /// \param element reference to the element to encode
110 /// \param encoded destination byte array for the encoded element
111 /// \details EncodeElement() must be implemented in a derived class.
112 /// \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
113 /// \sa GetEncodedElementSize(), DecodeElement(), <A
114 /// HREF="http://github.com/weidai11/cryptopp/issues/40">Cygwin
115 /// i386 crash at -O3</A>
116 void EncodeElement(bool reversible, const Element &element, byte *encoded) const;
117
118 /// \brief Retrieve the encoded element's size
119 /// \param reversible flag indicating the encoding format
120 /// \return encoded element's size, in bytes
121 /// \details The format of the encoded element varies by the underlying
122 /// type of the element and the reversible flag.
123 /// \sa EncodeElement(), DecodeElement()
124 unsigned int GetEncodedElementSize(bool reversible) const;
125
126 /// \brief Decodes the element
127 /// \param encoded byte array with the encoded element
128 /// \param checkForGroupMembership flag indicating if the element should be validated
129 /// \return Element after decoding
130 /// \details DecodeElement() must be implemented in a derived class.
131 /// \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
132 /// \sa GetEncodedElementSize(), EncodeElement()
133 Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const;
134
135 /// \brief Converts an element to an Integer
136 /// \param element the element to convert to an Integer
137 /// \return Element after converting to an Integer
138 /// \details ConvertElementToInteger() must be implemented in a derived class.
140 {return element;}
141
142 /// \brief Retrieve the maximum exponent for the group
143 /// \return the maximum exponent for the group
145
146 /// \brief Retrieve the OID of the algorithm
147 /// \return OID of the algorithm
149
150 /// \brief Retrieve the modulus for the group
151 /// \return the modulus for the group
152 virtual const Integer & GetModulus() const =0;
153
154 /// \brief Set group parameters
155 /// \param p the prime modulus
156 /// \param g the group generator
157 virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0;
158
159 /// \brief Set subgroup order
160 /// \param q the subgroup order
162 {m_q = q; ParametersChanged();}
163
164 static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
165
166protected:
167 Integer ComputeGroupOrder(const Integer &modulus) const
168 {return modulus-(GetFieldType() == 1 ? 1 : -1);}
169
170 // GF(p) = 1, GF(p^2) = 2
171 virtual int GetFieldType() const =0;
172 virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const;
173
174private:
175 Integer m_q;
176};
177
178/// \brief Integer-based GroupParameters default implementation
179/// \tparam GROUP_PRECOMP group parameters precomputation specialization
180/// \tparam BASE_PRECOMP base class precomputation specialization
181template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<typename GROUP_PRECOMP::Element> >
182class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl<GROUP_PRECOMP, BASE_PRECOMP, DL_GroupParameters_IntegerBased>
183{
185
186public:
187 typedef typename GROUP_PRECOMP::Element Element;
188
190
191 // GeneratibleCryptoMaterial interface
192 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
193 {return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();}
194
195 void AssignFrom(const NameValuePairs &source)
196 {AssignFromHelper<DL_GroupParameters_IntegerBased>(this, source);}
197
198 // DL_GroupParameters
199 const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
201
202 // IntegerGroupParameters
203 /// \brief Retrieve the modulus for the group
204 /// \return the modulus for the group
205 const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();}
206
207 /// \brief Retrieves a reference to the group generator
208 /// \return const reference to the group generator
209 const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());}
210
211 void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together
212 {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();}
213
214 // non-inherited
216 {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();}
218 {return !operator==(rhs);}
219};
220
222
223/// \brief GF(p) group parameters
224class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>
225{
226public:
227 virtual ~DL_GroupParameters_GFP() {}
228
229 /// \brief Determines if an element is an identity
230 /// \param element element to check
231 /// \return true if the element is an identity, false otherwise
232 /// \details The identity element or or neutral element is a special element
233 /// in a group that leaves other elements unchanged when combined with it.
234 /// \details IsIdentity() must be implemented in a derived class.
235 bool IsIdentity(const Integer &element) const {return element == Integer::One();}
236
237 /// \brief Exponentiates a base to multiple exponents
238 /// \param results an array of Elements
239 /// \param base the base to raise to the exponents
240 /// \param exponents an array of exponents
241 /// \param exponentsCount the number of exponents in the array
242 /// \details SimultaneousExponentiate() raises the base to each exponent in
243 /// the exponents array and stores the result at the respective position in
244 /// the results array.
245 /// \details SimultaneousExponentiate() must be implemented in a derived class.
246 /// \pre <tt>COUNTOF(results) == exponentsCount</tt>
247 /// \pre <tt>COUNTOF(exponents) == exponentsCount</tt>
248 void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
249
250 /// \brief Get a named value
251 /// \param name the name of the object or value to retrieve
252 /// \param valueType reference to a variable that receives the value
253 /// \param pValue void pointer to a variable that receives the value
254 /// \return true if the value was retrieved, false otherwise
255 /// \details GetVoidValue() retrieves the value of name if it exists.
256 /// \note GetVoidValue() is an internal function and should be implemented
257 /// by derived classes. Users should use one of the other functions instead.
258 /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
259 /// GetRequiredParameter() and GetRequiredIntParameter()
260 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
261 {
262 return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();
263 }
264
265 // used by MQV
266 Element MultiplyElements(const Element &a, const Element &b) const;
267 Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
268
269protected:
270 int GetFieldType() const {return 1;}
271};
272
273/// \brief GF(p) group parameters that default to safe primes
275{
276public:
278
280
281protected:
282 unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;}
283};
284
285/// ElGamal encryption for safe interop
286/// \sa <A HREF="https://eprint.iacr.org/2021/923.pdf">On the
287/// (in)security of ElGamal in OpenPGP</A>,
288/// <A HREF="https://github.com/weidai11/cryptopp/issues/1059">Issue 1059</A>,
289/// <A HREF="https://nvd.nist.gov/vuln/detail/CVE-2021-40530">CVE-2021-40530</A>
290/// \since Crypto++ 8.6
292{
293public:
295
296 virtual ~DL_GroupParameters_ElGamal() {}
297
299 {
300 return GetSubgroupOrder()-1;
301 }
302};
303
304/// \brief GDSA algorithm
305/// \tparam T FieldElement type or class
306/// \details FieldElement <tt>T</tt> can be Integer, ECP or EC2N.
307template <class T>
309{
310public:
311 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";}
312
313 virtual ~DL_Algorithm_GDSA() {}
314
315 void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
316 {
317 const Integer &q = params.GetSubgroupOrder();
318 r %= q;
319 Integer kInv = k.InverseMod(q);
320 s = (kInv * (x*r + e)) % q;
321 CRYPTOPP_ASSERT(!!r && !!s);
322 }
323
324 bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
325 {
326 const Integer &q = params.GetSubgroupOrder();
327 if (r>=q || r<1 || s>=q || s<1)
328 return false;
329
330 Integer w = s.InverseMod(q);
331 Integer u1 = (e * w) % q;
332 Integer u2 = (r * w) % q;
333 // verify r == (g^u1 * y^u2 mod p) mod q
334 return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
335 }
336};
337
338/// \brief DSA signature algorithm based on RFC 6979
339/// \tparam T FieldElement type or class
340/// \tparam H HashTransformation derived class
341/// \details FieldElement <tt>T</tt> can be Integer, ECP or EC2N.
342/// \sa <a href="http://tools.ietf.org/rfc/rfc6979.txt">RFC 6979, Deterministic Usage of the
343/// Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)</a>
344/// \since Crypto++ 6.0
345template <class T, class H>
347{
348public:
349 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-RFC6979";}
350
351 virtual ~DL_Algorithm_DSA_RFC6979() {}
352
353 bool IsProbabilistic() const
354 {return false;}
355 bool IsDeterministic() const
356 {return true;}
357
358 // Deterministic K
359 Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const
360 {
361 static const byte zero = 0, one = 1;
362 const size_t qlen = q.BitCount();
363 const size_t rlen = BitsToBytes(qlen);
364
365 // Step (a) - formatted E(m)
367 e.Encode(BH, BH.size());
368 BH = bits2octets(BH, q);
369
370 // Step (a) - private key to byte array
371 SecByteBlock BX(STDMAX(rlen, x.MinEncodedSize()));
372 x.Encode(BX, BX.size());
373
374 // Step (b)
375 SecByteBlock V(H::DIGESTSIZE);
376 std::fill(V.begin(), V.begin()+H::DIGESTSIZE, one);
377
378 // Step (c)
379 SecByteBlock K(H::DIGESTSIZE);
380 std::fill(K.begin(), K.begin()+H::DIGESTSIZE, zero);
381
382 // Step (d)
383 m_hmac.SetKey(K, K.size());
384 m_hmac.Update(V, V.size());
385 m_hmac.Update(&zero, 1);
386 m_hmac.Update(BX, BX.size());
387 m_hmac.Update(BH, BH.size());
388 m_hmac.TruncatedFinal(K, K.size());
389
390 // Step (e)
391 m_hmac.SetKey(K, K.size());
392 m_hmac.Update(V, V.size());
393 m_hmac.TruncatedFinal(V, V.size());
394
395 // Step (f)
396 m_hmac.SetKey(K, K.size());
397 m_hmac.Update(V, V.size());
398 m_hmac.Update(&one, 1);
399 m_hmac.Update(BX, BX.size());
400 m_hmac.Update(BH, BH.size());
401 m_hmac.TruncatedFinal(K, K.size());
402
403 // Step (g)
404 m_hmac.SetKey(K, K.size());
405 m_hmac.Update(V, V.size());
406 m_hmac.TruncatedFinal(V, V.size());
407
408 Integer k;
409 SecByteBlock temp(rlen);
410 for (;;)
411 {
412 // We want qlen bits, but we support only hash functions with an output length
413 // multiple of 8; hence, we will gather rlen bits, i.e., rolen octets.
414 size_t toff = 0;
415 while (toff < rlen)
416 {
417 m_hmac.Update(V, V.size());
418 m_hmac.TruncatedFinal(V, V.size());
419
420 size_t cc = STDMIN(V.size(), temp.size() - toff);
421 memcpy_s(temp+toff, temp.size() - toff, V, cc);
422 toff += cc;
423 }
424
425 k = bits2int(temp, qlen);
426 if (k > 0 && k < q)
427 break;
428
429 // k is not in the proper range; update K and V, and loop.
430 m_hmac.Update(V, V.size());
431 m_hmac.Update(&zero, 1);
432 m_hmac.TruncatedFinal(K, K.size());
433
434 m_hmac.SetKey(K, K.size());
435 m_hmac.Update(V, V.size());
436 m_hmac.TruncatedFinal(V, V.size());
437 }
438
439 return k;
440 }
441
442protected:
443
444 Integer bits2int(const SecByteBlock& bits, size_t qlen) const
445 {
446 Integer ret(bits, bits.size());
447 size_t blen = bits.size()*8;
448
449 if (blen > qlen)
450 ret >>= blen - qlen;
451
452 return ret;
453 }
454
455 // RFC 6979 support function. Takes an integer and converts it into bytes that
456 // are the same length as an elliptic curve's order.
457 SecByteBlock int2octets(const Integer& val, size_t rlen) const
458 {
459 SecByteBlock block(val.MinEncodedSize());
460 val.Encode(block, val.MinEncodedSize());
461
462 if (block.size() == rlen)
463 return block;
464
465 // The least significant bytes are the ones we need to preserve.
466 SecByteBlock t(rlen);
467 if (block.size() > rlen)
468 {
469 size_t offset = block.size() - rlen;
470 std::memcpy(t, block + offset, rlen);
471 }
472 else // block.size() < rlen
473 {
474 size_t offset = rlen - block.size();
475 memset(t, '\x00', offset);
476 std::memcpy(t + offset, block, rlen - offset);
477 }
478
479 return t;
480 }
481
482 // Turn a stream of bits into a set of bytes with the same length as an elliptic
483 // curve's order.
484 SecByteBlock bits2octets(const SecByteBlock& in, const Integer& q) const
485 {
486 Integer b2 = bits2int(in, q.BitCount());
487 Integer b1 = b2 - q;
488 return int2octets(b1.IsNegative() ? b2 : b1, q.ByteCount());
489 }
490
491private:
492 mutable H m_hash;
493 mutable HMAC<H> m_hmac;
494};
495
496/// \brief German Digital Signature Algorithm
497/// \tparam T FieldElement type or class
498/// \details FieldElement <tt>T</tt> can be Integer, ECP or EC2N.
499/// \details The Digital Signature Scheme ECGDSA does not define the algorithm over integers. Rather, the
500/// signature algorithm is only defined over elliptic curves. However, the library design is such that the
501/// generic algorithm reside in <tt>gfpcrypt.h</tt>.
502/// \sa Erwin Hess, Marcus Schafheutle, and Pascale Serf <A HREF="http://www.teletrust.de/fileadmin/files/oid/ecgdsa_final.pdf">
503/// The Digital Signature Scheme ECGDSA (October 24, 2006)</A>
504template <class T>
506{
507public:
508 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "GDSA-ISO15946";}
509
510 virtual ~DL_Algorithm_GDSA_ISO15946() {}
511
512 void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
513 {
514 const Integer &q = params.GetSubgroupOrder();
515 // r = x(k * G) mod q
516 r = params.ConvertElementToInteger(params.ExponentiateBase(k)) % q;
517 // s = (k * r - h(m)) * d_A mod q
518 s = (k * r - e) * x % q;
519 CRYPTOPP_ASSERT(!!r && !!s);
520 }
521
522 bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
523 {
524 const Integer &q = params.GetSubgroupOrder();
525 if (r>=q || r<1 || s>=q || s<1)
526 return false;
527
528 const Integer& rInv = r.InverseMod(q);
529 const Integer u1 = (rInv * e) % q;
530 const Integer u2 = (rInv * s) % q;
531 // verify x(G^u1 + P_A^u2) mod q
532 return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
533 }
534};
535
542
543/// \brief NR algorithm
544/// \tparam T FieldElement type or class
545/// \details FieldElement <tt>T</tt> can be Integer, ECP or EC2N.
546template <class T>
548{
549public:
550 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "NR";}
551
552 virtual ~DL_Algorithm_NR() {}
553
554 void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
555 {
556 const Integer &q = params.GetSubgroupOrder();
557 r = (r + e) % q;
558 s = (k - x*r) % q;
559 CRYPTOPP_ASSERT(!!r);
560 }
561
562 bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
563 {
564 const Integer &q = params.GetSubgroupOrder();
565 if (r>=q || r<1 || s>=q)
566 return false;
567
568 // check r == (m_g^s * m_y^r + m) mod m_q
569 return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q;
570 }
571};
572
573/// \brief Discrete Log (DL) public key in GF(p) groups
574/// \tparam GP GroupParameters derived class
575/// \details DSA public key format is defined in 7.3.3 of RFC 2459. The private key format is defined in 12.9 of PKCS #11 v2.10.
576template <class GP>
578{
579public:
580 virtual ~DL_PublicKey_GFP() {}
581
582 /// \brief Initialize a public key over GF(p)
583 /// \param params the group parameters
584 /// \param y the public element
586 {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);}
587
588 /// \brief Initialize a public key over GF(p)
589 /// \param p the modulus
590 /// \param g the generator
591 /// \param y the public element
592 void Initialize(const Integer &p, const Integer &g, const Integer &y)
593 {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);}
594
595 /// \brief Initialize a public key over GF(p)
596 /// \param p the modulus
597 /// \param q the subgroup order
598 /// \param g the generator
599 /// \param y the public element
600 void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
601 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);}
602
603 // X509PublicKey
605 {this->SetPublicElement(Integer(bt));}
607 {this->GetPublicElement().DEREncode(bt);}
608};
609
610/// \brief Discrete Log (DL) private key in GF(p) groups
611/// \tparam GP GroupParameters derived class
612template <class GP>
614{
615public:
616 virtual ~DL_PrivateKey_GFP();
617
618 /// \brief Create a private key
619 /// \param rng a RandomNumberGenerator derived class
620 /// \param modulusBits the size of the modulus, in bits
621 /// \details This function overload of Initialize() creates a new private key because it
622 /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,
623 /// then use one of the other Initialize() overloads.
624 void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
625 {this->GenerateRandomWithKeySize(rng, modulusBits);}
626
627 /// \brief Create a private key
628 /// \param rng a RandomNumberGenerator derived class
629 /// \param p the modulus
630 /// \param g the generator
631 /// \details This function overload of Initialize() creates a new private key because it
632 /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,
633 /// then use one of the other Initialize() overloads.
634 void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
635 {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));}
636
637 /// \brief Create a private key
638 /// \param rng a RandomNumberGenerator derived class
639 /// \param p the modulus
640 /// \param q the subgroup order
641 /// \param g the generator
642 /// \details This function overload of Initialize() creates a new private key because it
643 /// takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,
644 /// then use one of the other Initialize() overloads.
645 void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g)
646 {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));}
647
648 /// \brief Initialize a private key over GF(p)
649 /// \param params the group parameters
650 /// \param x the private exponent
652 {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);}
653
654 /// \brief Initialize a private key over GF(p)
655 /// \param p the modulus
656 /// \param g the generator
657 /// \param x the private exponent
658 void Initialize(const Integer &p, const Integer &g, const Integer &x)
659 {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);}
660
661 /// \brief Initialize a private key over GF(p)
662 /// \param p the modulus
663 /// \param q the subgroup order
664 /// \param g the generator
665 /// \param x the private exponent
666 void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x)
667 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);}
668};
669
670// Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499
671template <class GP>
673
674/// \brief Discrete Log (DL) signing/verification keys in GF(p) groups
676{
680};
681
682/// \brief Discrete Log (DL) encryption/decryption keys in GF(p) groups
684{
688};
689
690/// ElGamal encryption keys for safe interop
691/// \sa <A HREF="https://eprint.iacr.org/2021/923.pdf">On the
692/// (in)security of ElGamal in OpenPGP</A>,
693/// <A HREF="https://github.com/weidai11/cryptopp/issues/1059">Issue 1059</A>,
694/// <A HREF="https://nvd.nist.gov/vuln/detail/CVE-2021-40530">CVE-2021-40530</A>
695/// \since Crypto++ 8.6
697{
701};
702
703/// \brief DSA signature scheme
704/// \tparam H HashTransformation derived class
705/// \sa <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a>
706/// \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2
707template <class H>
708struct GDSA : public DL_SS<
709 DL_SignatureKeys_GFP,
710 DL_Algorithm_GDSA<Integer>,
711 DL_SignatureMessageEncodingMethod_DSA,
712 H>
713{
714};
715
716/// \brief NR signature scheme
717/// \tparam H HashTransformation derived class
718/// \sa <a href="http://www.weidai.com/scan-mirror/sig.html#NR">NR</a>
719template <class H>
720struct NR : public DL_SS<
721 DL_SignatureKeys_GFP,
722 DL_Algorithm_NR<Integer>,
723 DL_SignatureMessageEncodingMethod_NR,
724 H>
725{
726};
727
728/// \brief DSA group parameters
729/// \details These are GF(p) group parameters that are allowed by the DSA standard
730/// \sa DL_Keys_DSA
731/// \since Crypto++ 1.0
733{
734public:
735 virtual ~DL_GroupParameters_DSA() {}
736
737 /// \brief Check the group for errors
738 /// \param rng RandomNumberGenerator for objects which use randomized testing
739 /// \param level level of thoroughness
740 /// \return true if the tests succeed, false otherwise
741 /// \details ValidateGroup() also checks that the lengths of p and q are allowed
742 /// by the DSA standard.
743 /// \details There are four levels of thoroughness:
744 /// <ul>
745 /// <li>0 - using this object won't cause a crash or exception
746 /// <li>1 - this object will probably function, and encrypt, sign, other operations correctly
747 /// <li>2 - ensure this object will function correctly, and perform reasonable security checks
748 /// <li>3 - perform reasonable security checks, and do checks that may take a long time
749 /// </ul>
750 /// \details Level 0 does not require a RandomNumberGenerator. A NullRNG() can be used for level 0.
751 /// Level 1 may not check for weak keys and such. Levels 2 and 3 are recommended.
752 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
753
754 /// \brief Generate a random key or crypto parameters
755 /// \param rng a RandomNumberGenerator to produce keying material
756 /// \param alg additional initialization parameters
757 /// \details NameValuePairs can be ModulusSize alone; or Modulus, SubgroupOrder, and
758 /// SubgroupGenerator. ModulusSize must be between <tt>DSA::MIN_PRIME_LENGTH</tt> and
759 /// <tt>DSA::MAX_PRIME_LENGTH</tt>, and divisible by <tt>DSA::PRIME_LENGTH_MULTIPLE</tt>.
760 /// \details An example of changing the modulus size using NameValuePairs is shown below.
761 /// <pre>
762 /// AlgorithmParameters params = MakeParameters
763 /// (Name::ModulusSize(), 2048);
764 ///
765 /// DL_GroupParameters_DSA groupParams;
766 /// groupParams.GenerateRandom(prng, params);
767 /// </pre>
768 /// \throw KeyingErr if a key can't be generated or algorithm parameters are invalid.
770
771 /// \brief Check the prime length for errors
772 /// \param pbits number of bits in the prime number
773 /// \return true if the tests succeed, false otherwise
774 static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits)
775 {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;}
776
777 /// \brief DSA prime length
778 enum {
779 /// \brief Minimum prime length
780 MIN_PRIME_LENGTH = 1024,
781 /// \brief Maximum prime length
782 MAX_PRIME_LENGTH = 3072,
783 /// \brief Prime length multiple
784 PRIME_LENGTH_MULTIPLE = 1024
785 };
786};
787
788template <class H>
789class DSA2;
790
791/// \brief DSA keys
792/// \sa DL_GroupParameters_DSA
793/// \since Crypto++ 1.0
795{
798};
799
800/// \brief DSA signature scheme
801/// \tparam H HashTransformation derived class
802/// \details The class is named DSA2 instead of DSA for backwards compatibility because
803/// DSA was a non-template class.
804/// \details DSA default method GenerateRandom uses a 2048-bit modulus and a 224-bit subgoup by default.
805/// The modulus can be changed using the following code:
806/// <pre>
807/// DSA::PrivateKey privateKey;
808/// privateKey.GenerateRandomWithKeySize(prng, 2048);
809/// </pre>
810/// \details The subgroup order can be changed using the following code:
811/// <pre>
812/// AlgorithmParameters params = MakeParameters
813/// (Name::ModulusSize(), 2048)
814/// (Name::SubgroupOrderSize(), 256);
815///
816/// DSA::PrivateKey privateKey;
817/// privateKey.GenerateRandom(prng, params);
818/// </pre>
819/// \sa <a href="http://en.wikipedia.org/wiki/Digital_Signature_Algorithm">DSA</a>, as specified in FIPS 186-3,
820/// <a href="https://www.cryptopp.com/wiki/Digital_Signature_Algorithm">Digital Signature Algorithm</a> on the wiki, and
821/// <a href="https://www.cryptopp.com/wiki/NameValuePairs">NameValuePairs</a> on the wiki.
822/// \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2, Crypto++ 6.1 for 2048-bit modulus.
823template <class H>
824class DSA2 : public DL_SS<
825 DL_Keys_DSA,
826 DL_Algorithm_GDSA<Integer>,
827 DL_SignatureMessageEncodingMethod_DSA,
828 H,
829 DSA2<H> >
830{
831public:
832 static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();}
833};
834
835/// \brief DSA deterministic signature scheme
836/// \tparam H HashTransformation derived class
837/// \sa <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a>
838/// \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2
839template <class H>
840struct DSA_RFC6979 : public DL_SS<
841 DL_SignatureKeys_GFP,
842 DL_Algorithm_DSA_RFC6979<Integer, H>,
843 DL_SignatureMessageEncodingMethod_DSA,
844 H,
845 DSA_RFC6979<H> >
846{
847 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("DSA-RFC6979/") + H::StaticAlgorithmName();}
848};
849
850/// DSA with SHA-1, typedef'd for backwards compatibility
852
856
857/// \brief P1363 based XOR Encryption Method
858/// \tparam MAC MessageAuthenticationCode derived class used for MAC computation
859/// \tparam DHAES_MODE flag indicating DHAES mode
860/// \tparam LABEL_OCTETS flag indicating the label is octet count
861/// \details DL_EncryptionAlgorithm_Xor is based on an early P1363 draft, which itself appears to be based on an
862/// early Certicom SEC-1 draft (or an early SEC-1 draft was based on a P1363 draft). Crypto++ 4.2 used it in its Integrated
863/// Ecryption Schemes with <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=false</tt> and <tt>LABEL_OCTETS=true</tt>.
864/// \details If you need this method for Crypto++ 4.2 compatibility, then use the ECIES template class with
865/// <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=false</tt> and <tt>LABEL_OCTETS=true</tt>.
866/// \details If you need this method for Bouncy Castle 1.54 and Botan 1.11 compatibility, then use the ECIES template class with
867/// <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=true</tt> and <tt>LABEL_OCTETS=false</tt>.
868/// \details Bouncy Castle 1.54 and Botan 1.11 compatibility are the default template parameters.
869/// \since Crypto++ 4.0
870template <class MAC, bool DHAES_MODE, bool LABEL_OCTETS=false>
872{
873public:
874 virtual ~DL_EncryptionAlgorithm_Xor() {}
875
876 bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
877 size_t GetSymmetricKeyLength(size_t plaintextLength) const
878 {return plaintextLength + static_cast<size_t>(MAC::DEFAULT_KEYLENGTH);}
879 size_t GetSymmetricCiphertextLength(size_t plaintextLength) const
880 {return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);}
881 size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const
882 {return SaturatingSubtract(ciphertextLength, static_cast<size_t>(MAC::DIGESTSIZE));}
883 void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
884 {
885 CRYPTOPP_UNUSED(rng);
886 const byte *cipherKey = NULLPTR, *macKey = NULLPTR;
887 if (DHAES_MODE)
888 {
889 macKey = key;
890 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
891 }
892 else
893 {
894 cipherKey = key;
895 macKey = key + plaintextLength;
896 }
897
898 ConstByteArrayParameter encodingParameters;
899 parameters.GetValue(Name::EncodingParameters(), encodingParameters);
900
901 if (plaintextLength) // Coverity finding
902 xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
903
904 MAC mac(macKey);
905 mac.Update(ciphertext, plaintextLength);
906 mac.Update(encodingParameters.begin(), encodingParameters.size());
907 if (DHAES_MODE)
908 {
909 byte L[8];
910 PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size())));
911 mac.Update(L, 8);
912 }
913 mac.Final(ciphertext + plaintextLength);
914 }
915 DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
916 {
917 size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength);
918 const byte *cipherKey, *macKey;
919 if (DHAES_MODE)
920 {
921 macKey = key;
922 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
923 }
924 else
925 {
926 cipherKey = key;
927 macKey = key + plaintextLength;
928 }
929
930 ConstByteArrayParameter encodingParameters;
931 parameters.GetValue(Name::EncodingParameters(), encodingParameters);
932
933 MAC mac(macKey);
934 mac.Update(ciphertext, plaintextLength);
935 mac.Update(encodingParameters.begin(), encodingParameters.size());
936 if (DHAES_MODE)
937 {
938 byte L[8];
939 PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size())));
940 mac.Update(L, 8);
941 }
942 if (!mac.Verify(ciphertext + plaintextLength))
943 return DecodingResult();
944
945 if (plaintextLength) // Coverity finding
946 xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
947
948 return DecodingResult(plaintextLength);
949 }
950};
951
952/// \brief P1363 based Key Derivation Method
953/// \tparam T FieldElement type or class
954/// \tparam DHAES_MODE flag indicating DHAES mode
955/// \tparam KDF key derivation function
956/// \details FieldElement <tt>T</tt> can be Integer, ECP or EC2N.
957template <class T, bool DHAES_MODE, class KDF>
959{
960public:
962
963 bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;}
964 void Derive(const DL_GroupParameters<T> &params, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &parameters) const
965 {
966 SecByteBlock agreedSecret;
967 if (DHAES_MODE)
968 {
969 agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false));
970 params.EncodeElement(true, ephemeralPublicKey, agreedSecret);
971 params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true));
972 }
973 else
974 {
975 agreedSecret.New(params.GetEncodedElementSize(false));
976 params.EncodeElement(false, agreedElement, agreedSecret);
977 }
978
979 ConstByteArrayParameter derivationParameters;
980 parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters);
981 KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size());
982 }
983};
984
985/// \brief Discrete Log Integrated Encryption Scheme
986/// \tparam COFACTOR_OPTION cofactor multiplication option
987/// \tparam HASH HashTransformation derived class used for key drivation and MAC computation
988/// \tparam DHAES_MODE flag indicating if the MAC includes addition context parameters such as the label
989/// \tparam LABEL_OCTETS flag indicating if the label size is specified in octets or bits
990/// \details DLIES is an Integer based Integrated Encryption Scheme (IES). The scheme combines a Key Encapsulation Method (KEM)
991/// with a Data Encapsulation Method (DEM) and a MAC tag. The scheme is
992/// <A HREF="http://en.wikipedia.org/wiki/ciphertext_indistinguishability">IND-CCA2</A>, which is a strong notion of security.
993/// You should prefer an Integrated Encryption Scheme over homegrown schemes.
994/// \details The library's original implementation is based on an early P1363 draft, which itself appears to be based on an early Certicom
995/// SEC-1 draft (or an early SEC-1 draft was based on a P1363 draft). Crypto++ 4.2 used the early draft in its Integrated Ecryption
996/// Schemes with <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=false</tt> and <tt>LABEL_OCTETS=true</tt>.
997/// \details If you desire an Integrated Encryption Scheme with Crypto++ 4.2 compatibility, then use the DLIES template class with
998/// <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=false</tt> and <tt>LABEL_OCTETS=true</tt>.
999/// \details If you desire an Integrated Encryption Scheme with Bouncy Castle 1.54 and Botan 1.11 compatibility, then use the DLIES
1000/// template class with <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=true</tt> and <tt>LABEL_OCTETS=false</tt>.
1001/// \details The default template parameters ensure compatibility with Bouncy Castle 1.54 and Botan 1.11. The combination of
1002/// <tt>IncompatibleCofactorMultiplication</tt> and <tt>DHAES_MODE=true</tt> is recommended for best efficiency and security.
1003/// SHA1 is used for compatibility reasons, but it can be changed if desired. SHA-256 or another hash will likely improve the
1004/// security provided by the MAC. The hash is also used in the key derivation function as a PRF.
1005/// \details Below is an example of constructing a Crypto++ 4.2 compatible DLIES encryptor and decryptor.
1006/// <pre>
1007/// AutoSeededRandomPool prng;
1008/// DL_PrivateKey_GFP<DL_GroupParameters_GFP> key;
1009/// key.Initialize(prng, 2048);
1010///
1011/// DLIES<SHA1,NoCofactorMultiplication,true,true>::Decryptor decryptor(key);
1012/// DLIES<SHA1,NoCofactorMultiplication,true,true>::Encryptor encryptor(decryptor);
1013/// </pre>
1014/// \sa ECIES, <a href="http://www.weidai.com/scan-mirror/ca.html#DLIES">Discrete Log Integrated Encryption Scheme (DLIES)</a>,
1015/// Martínez, Encinas, and Ávila's <A HREF="http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf">A Survey of the Elliptic
1016/// Curve Integrated Encryption Schemes</A>
1017/// \since Crypto++ 4.0, Crypto++ 5.7 for Bouncy Castle and Botan compatibility
1018template <class HASH = SHA1, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true, bool LABEL_OCTETS=false>
1019struct DLIES
1020 : public DL_ES<
1021 DL_CryptoKeys_GFP,
1022 DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>,
1023 DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<HASH> >,
1024 DL_EncryptionAlgorithm_Xor<HMAC<HASH>, DHAES_MODE, LABEL_OCTETS>,
1025 DLIES<> >
1026{
1027 static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized
1028};
1029
1030NAMESPACE_END
1031
1032#if CRYPTOPP_MSC_VERSION
1033# pragma warning(pop)
1034#endif
1035
1036#endif
Classes for working with NameValuePairs.
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:508
Classes and functions for working with ANS.1 objects.
bool operator==(const OID &lhs, const OID &rhs)
Compare two OIDs for equality.
bool operator!=(const OID &lhs, const OID &rhs)
Compare two OIDs for inequality.
Encode and decode ASN.1 objects with additional information.
Definition: asn.h:684
Interface for buffered transformations.
Definition: cryptlib.h:1652
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:25
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:84
size_t size() const
Length of the memory block.
Definition: algparam.h:88
DSA signature algorithm based on RFC 6979.
Definition: gfpcrypt.h:347
Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const
Generate k.
Definition: gfpcrypt.h:359
bool IsDeterministic() const
Signature scheme flag.
Definition: gfpcrypt.h:355
German Digital Signature Algorithm.
Definition: gfpcrypt.h:506
void Sign(const DL_GroupParameters< T > &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
Sign a message using a private key.
Definition: gfpcrypt.h:512
bool Verify(const DL_GroupParameters< T > &params, const DL_PublicKey< T > &publicKey, const Integer &e, const Integer &r, const Integer &s) const
Verify a message using a public key.
Definition: gfpcrypt.h:522
GDSA algorithm.
Definition: gfpcrypt.h:309
bool Verify(const DL_GroupParameters< T > &params, const DL_PublicKey< T > &publicKey, const Integer &e, const Integer &r, const Integer &s) const
Verify a message using a public key.
Definition: gfpcrypt.h:324
void Sign(const DL_GroupParameters< T > &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
Sign a message using a private key.
Definition: gfpcrypt.h:315
NR algorithm.
Definition: gfpcrypt.h:548
bool Verify(const DL_GroupParameters< T > &params, const DL_PublicKey< T > &publicKey, const Integer &e, const Integer &r, const Integer &s) const
Verify a message using a public key.
Definition: gfpcrypt.h:562
void Sign(const DL_GroupParameters< T > &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
Sign a message using a private key.
Definition: gfpcrypt.h:554
Discrete Log (DL) encryption scheme.
Definition: pubkey.h:2362
Interface for Elgamal-like signature algorithms.
Definition: pubkey.h:1407
P1363 based XOR Encryption Method.
Definition: gfpcrypt.h:872
DSA group parameters.
Definition: gfpcrypt.h:733
bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
Check the group for errors.
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
Generate a random key or crypto parameters.
static bool IsValidPrimeLength(unsigned int pbits)
Check the prime length for errors.
Definition: gfpcrypt.h:774
ElGamal encryption for safe interop.
Definition: gfpcrypt.h:292
Integer GetMaxExponent() const
Retrieve the maximum exponent for the group.
Definition: gfpcrypt.h:298
GF(p) group parameters that default to safe primes.
Definition: gfpcrypt.h:275
GF(p) group parameters.
Definition: gfpcrypt.h:225
void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
Exponentiates a base to multiple exponents.
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: gfpcrypt.h:260
bool IsIdentity(const Integer &element) const
Determines if an element is an identity.
Definition: gfpcrypt.h:235
Integer-based GroupParameters specialization.
Definition: gfpcrypt.h:35
void AssignFrom(const NameValuePairs &source)
Initialize or reinitialize this key.
void Initialize(const Integer &p, const Integer &g)
Initialize a group parameters over integers.
Definition: gfpcrypt.h:58
Integer GetGroupOrder() const
Retrieves the order of the group.
Definition: gfpcrypt.h:99
virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g)=0
Set group parameters.
void Initialize(RandomNumberGenerator &rng, unsigned int pbits)
Create a group parameters over integers.
Definition: gfpcrypt.h:52
OID GetAlgorithmID() const
Retrieve the OID of the algorithm.
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Integer GetMaxExponent() const
Retrieve the maximum exponent for the group.
void SetSubgroupOrder(const Integer &q)
Set subgroup order.
Definition: gfpcrypt.h:161
Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const
Decodes the element.
Integer ConvertElementToInteger(const Element &element) const
Converts an element to an Integer.
Definition: gfpcrypt.h:139
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
Generate a random key.
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
virtual const Integer & GetModulus() const =0
Retrieve the modulus for the group.
bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
Check the group for errors.
void Initialize(const DL_GroupParameters_IntegerBased &params)
Initialize a group parameters over integers.
Definition: gfpcrypt.h:43
bool FastSubgroupCheckAvailable() const
Determine if subgroup membership check is fast.
Definition: gfpcrypt.h:105
unsigned int GetEncodedElementSize(bool reversible) const
Retrieve the encoded element's size.
void Initialize(const Integer &p, const Integer &q, const Integer &g)
Initialize a group parameters over integers.
Definition: gfpcrypt.h:65
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation< Integer > *precomp) const
Check the element for errors.
const Integer & GetSubgroupOrder() const
Retrieves the subgroup order.
Definition: gfpcrypt.h:98
void EncodeElement(bool reversible, const Element &element, byte *encoded) const
Encodes the element.
Integer-based GroupParameters default implementation.
Definition: gfpcrypt.h:183
void AssignFrom(const NameValuePairs &source)
Initialize or reinitialize this key.
Definition: gfpcrypt.h:195
const DL_FixedBasePrecomputation< Element > & GetBasePrecomputation() const
Retrieves the group precomputation.
Definition: gfpcrypt.h:199
void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g)
Set group parameters.
Definition: gfpcrypt.h:211
DL_FixedBasePrecomputation< Element > & AccessBasePrecomputation()
Retrieves the group precomputation.
Definition: gfpcrypt.h:200
const Integer & GetGenerator() const
Retrieves a reference to the group generator.
Definition: gfpcrypt.h:209
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: gfpcrypt.h:192
const Integer & GetModulus() const
Retrieve the modulus for the group.
Definition: gfpcrypt.h:205
virtual const Element & GetSubgroupGenerator() const
Retrieves the subgroup generator.
Definition: pubkey.h:859
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
virtual unsigned int GetEncodedElementSize(bool reversible) const =0
Retrieves the encoded element's size.
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 Integer ConvertElementToInteger(const Element &element) const =0
Converts an element to an Integer.
Base implementation of Discrete Log (DL) group parameters.
Definition: pubkey.h:1014
const DL_GroupPrecomputation< Element > & GetGroupPrecomputation() const
Retrieves the group precomputation.
Definition: pubkey.h:1024
P1363 based Key Derivation Method.
Definition: gfpcrypt.h:959
Interface for key derivation algorithms used in DL cryptosystems.
Definition: pubkey.h:1493
Discrete Log (DL) private key in GF(p) groups.
Definition: gfpcrypt.h:614
void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g)
Create a private key.
Definition: gfpcrypt.h:645
void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
Create a private key.
Definition: gfpcrypt.h:634
void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
Create a private key.
Definition: gfpcrypt.h:624
void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x)
Initialize a private key over GF(p)
Definition: gfpcrypt.h:666
void Initialize(const Integer &p, const Integer &g, const Integer &x)
Initialize a private key over GF(p)
Definition: gfpcrypt.h:658
void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &x)
Initialize a private key over GF(p)
Definition: gfpcrypt.h:651
Discrete Log (DL) private key base implementation.
Definition: pubkey.h:1239
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: pubkey.h:1276
void SetPrivateExponent(const Integer &x)
Sets the private exponent.
Definition: pubkey.h:1301
Discrete Log (DL) public key in GF(p) groups.
Definition: gfpcrypt.h:578
void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &y)
Initialize a public key over GF(p)
Definition: gfpcrypt.h:585
void Initialize(const Integer &p, const Integer &g, const Integer &y)
Initialize a public key over GF(p)
Definition: gfpcrypt.h:592
void DEREncodePublicKey(BufferedTransformation &bt) const
Encode subjectPublicKey part of subjectPublicKeyInfo.
Definition: gfpcrypt.h:606
void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t)
Decode subjectPublicKey part of subjectPublicKeyInfo.
Definition: gfpcrypt.h:604
void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
Initialize a public key over GF(p)
Definition: gfpcrypt.h:600
Interface for Discrete Log (DL) public keys.
Definition: pubkey.h:1059
virtual const Element & GetPublicElement() const
Retrieves the public element.
Definition: pubkey.h:1089
virtual void SetPublicElement(const Element &y)
Sets the public element.
Definition: pubkey.h:1093
virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
Exponentiates an element.
Definition: pubkey.h:1110
Discrete Log (DL) public key base implementation.
Definition: pubkey.h:1336
Discrete Log (DL) signature scheme.
Definition: pubkey.h:2342
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition: pubkey.h:1505
DSA signature scheme.
Definition: gfpcrypt.h:830
Interface for deterministic signers.
Definition: pubkey.h:1460
void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
Generate a random key or crypto parameters.
void TruncatedFinal(byte *mac, size_t size)
Computes the hash of the current message.
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
size_t MinEncodedSize(Signedness sign=UNSIGNED) const
Minimum number of bytes to encode this integer.
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
bool IsNegative() const
Determines if the Integer is negative.
Definition: integer.h:341
unsigned int ByteCount() const
Determines the number of bytes required to represent the Integer.
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Integer InverseMod(const Integer &n) const
Calculate multiplicative inverse.
static const Integer & One()
Integer representing 1.
Interface for retrieving values given their names.
Definition: cryptlib.h:322
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:379
Object Identifier.
Definition: asn.h:265
Interface for random number generators.
Definition: cryptlib.h:1435
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:836
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:1126
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:867
SecBlock<byte> typedef.
Definition: secblock.h:1226
virtual void SetKey(const byte *key, size_t length, const NameValuePairs &params=g_nullNameValuePairs)
Sets or reset the key of this object.
Library configuration file.
#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
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:91
Abstract base classes that provide a uniform interface to this library.
@ BIG_ENDIAN_ORDER
byte order is big-endian
Definition: cryptlib.h:147
DSA2< SHA1 > DSA
DSA with SHA-1, typedef'd for backwards compatibility.
Definition: gfpcrypt.h:851
Classes for HMAC message authentication codes.
Multiple precision integer with arithmetic operations.
Utility functions for the Crypto++ library.
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
Definition: misc.h:1093
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
Definition: misc.h:666
void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memcpy()
Definition: misc.h:525
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:655
size_t BitsToBytes(size_t bitCount)
Returns the number of 8-bit bytes or octets required for the specified number of bits.
Definition: misc.h:938
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULL)
Access a block of memory.
Definition: misc.h:2739
CRYPTOPP_DLL void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Crypto++ library namespace.
const char * KeyDerivationParameters()
ConstByteArrayParameter.
Definition: argnames.h:67
const char * EncodingParameters()
ConstByteArrayParameter.
Definition: argnames.h:66
This file contains helper classes/functions for implementing public key algorithms.
Classes for SHA-1 and SHA-2 family of message digests.
Classes for automatic resource management.
ElGamal encryption keys for safe interop.
Definition: gfpcrypt.h:697
Discrete Log (DL) encryption/decryption keys in GF(p) groups.
Definition: gfpcrypt.h:684
DSA keys.
Definition: gfpcrypt.h:795
Discrete Log (DL) signing/verification keys in GF(p) groups.
Definition: gfpcrypt.h:676
Discrete Log Integrated Encryption Scheme.
Definition: gfpcrypt.h:1026
DSA deterministic signature scheme.
Definition: gfpcrypt.h:846
Returns a decoding results.
Definition: cryptlib.h:278
Converts an enumeration to a type suitable for use as a template parameter.
Definition: cryptlib.h:136
DSA signature scheme.
Definition: gfpcrypt.h:713
NR signature scheme.
Definition: gfpcrypt.h:725
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68