Crypto++  5.6.5
Free C++ class library of cryptographic schemes
gfpcrypt.h
Go to the documentation of this file.
1 // gfpcrypt.h - written and placed in the public domain by Wei Dai
2 // deterministic signatures added by by Douglas Roark
3 
4 //! \file gfpcrypt.h
5 //! \brief Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
6 
7 #ifndef CRYPTOPP_GFPCRYPT_H
8 #define CRYPTOPP_GFPCRYPT_H
9 
10 #include "config.h"
11 
12 #if CRYPTOPP_MSC_VERSION
13 # pragma warning(push)
14 # pragma warning(disable: 4189)
15 #endif
16 
17 #include "cryptlib.h"
18 #include "pubkey.h"
19 #include "integer.h"
20 #include "modexppc.h"
21 #include "algparam.h"
22 #include "smartptr.h"
23 #include "sha.h"
24 #include "asn.h"
25 #include "hmac.h"
26 #include "misc.h"
27 
28 NAMESPACE_BEGIN(CryptoPP)
29 
30 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters<Integer>;
31 
32 //! \class DL_GroupParameters_IntegerBased
33 //! \brief Integer-based GroupParameters specialization
34 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial<DL_GroupParameters<Integer> >
35 {
37 
38 public:
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
69  void BERDecode(BufferedTransformation &bt);
70  void DEREncode(BufferedTransformation &bt) const;
71 
72  // GeneratibleCryptoMaterial interface
73  /*! parameters: (ModulusSize, SubgroupOrderSize (optional)) */
74  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
75  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
76  void AssignFrom(const NameValuePairs &source);
77 
78  // DL_GroupParameters
79  const Integer & GetSubgroupOrder() const {return m_q;}
80  Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();}
81  bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
82  bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const;
83  bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;}
84 
85  // Cygwin i386 crash at -O3; see http://github.com/weidai11/cryptopp/issues/40.
86  void EncodeElement(bool reversible, const Element &element, byte *encoded) const;
87  unsigned int GetEncodedElementSize(bool reversible) const;
88 
89  Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const;
90  Integer ConvertElementToInteger(const Element &element) const
91  {return element;}
92  Integer GetMaxExponent() const;
93  static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
94 
95  OID GetAlgorithmID() const;
96 
97  virtual const Integer & GetModulus() const =0;
98  virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0;
99 
100  void SetSubgroupOrder(const Integer &q)
101  {m_q = q; ParametersChanged();}
102 
103 protected:
104  Integer ComputeGroupOrder(const Integer &modulus) const
105  {return modulus-(GetFieldType() == 1 ? 1 : -1);}
106 
107  // GF(p) = 1, GF(p^2) = 2
108  virtual int GetFieldType() const =0;
109  virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const;
110 
111 private:
112  Integer m_q;
113 };
114 
115 //! \class DL_GroupParameters_IntegerBasedImpl
116 //! \brief Integer-based GroupParameters default implementation
117 //! \tparam GROUP_PRECOMP group parameters precomputation specialization
118 //! \tparam BASE_PRECOMP base class precomputation specialization
119 template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<typename GROUP_PRECOMP::Element> >
120 class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl<GROUP_PRECOMP, BASE_PRECOMP, DL_GroupParameters_IntegerBased>
121 {
123 
124 public:
125  typedef typename GROUP_PRECOMP::Element Element;
126 
128 
129  // GeneratibleCryptoMaterial interface
130  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
131  {return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();}
132 
133  void AssignFrom(const NameValuePairs &source)
134  {AssignFromHelper<DL_GroupParameters_IntegerBased>(this, source);}
135 
136  // DL_GroupParameters
137  const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
139 
140  // IntegerGroupParameters
141  const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();}
142  const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());}
143 
144  void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together
145  {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();}
146 
147  // non-inherited
149  {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();}
151  {return !operator==(rhs);}
152 };
153 
155 
156 //! \class DL_GroupParameters_GFP
157 //! \brief GF(p) group parameters
158 class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>
159 {
160 public:
161  virtual ~DL_GroupParameters_GFP() {}
162 
163  // DL_GroupParameters
164  bool IsIdentity(const Integer &element) const {return element == Integer::One();}
165  void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
166 
167  // NameValuePairs interface
168  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
169  {
170  return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();
171  }
172 
173  // used by MQV
174  Element MultiplyElements(const Element &a, const Element &b) const;
175  Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
176 
177 protected:
178  int GetFieldType() const {return 1;}
179 };
180 
181 //! \class DL_GroupParameters_GFP
182 //! \brief GF(p) group parameters that default to safe primes
184 {
185 public:
187 
189 
190 protected:
191  unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;}
192 };
193 
194 //! \class DL_Algorithm_GDSA
195 //! \brief GDSA algorithm
196 //! \tparam T FieldElement type or class
197 template <class T>
199 {
200 public:
201  CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";}
202 
203  virtual ~DL_Algorithm_GDSA() {}
204 
205  void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
206  {
207  const Integer &q = params.GetSubgroupOrder();
208  r %= q;
209  Integer kInv = k.InverseMod(q);
210  s = (kInv * (x*r + e)) % q;
211  CRYPTOPP_ASSERT(!!r && !!s);
212  }
213 
214  bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
215  {
216  const Integer &q = params.GetSubgroupOrder();
217  if (r>=q || r<1 || s>=q || s<1)
218  return false;
219 
220  Integer w = s.InverseMod(q);
221  Integer u1 = (e * w) % q;
222  Integer u2 = (r * w) % q;
223  // verify r == (g^u1 * y^u2 mod p) mod q
224  return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
225  }
226 };
227 
228 //! \class DL_Algorithm_DSA_RFC6979
229 //! \brief DSA signature algorithm based on RFC 6979
230 //! \tparam T FieldElement type or class
231 //! \tparam H HashTransformation derived class
232 //! \sa <a href="http://tools.ietf.org/rfc/rfc6979.txt">RFC 6979, Deterministic Usage of the
233 //! Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)</a>
234 //! \since Crypto++ 5.7
235 template <class T, class H>
237 {
238 public:
239  CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-RFC6979";}
240 
241  virtual ~DL_Algorithm_DSA_RFC6979() {}
242 
243  bool IsProbabilistic() const
244  {return false;}
245  bool IsDeterministic() const
246  {return true;}
247 
248  // Deterministic K
249  Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const
250  {
251  static const byte zero = 0, one = 1;
252  const size_t qlen = q.BitCount();
253  const size_t rlen = BitsToBytes(qlen);
254 
255  // Step (a) - formatted E(m)
257  e.Encode(BH, BH.size());
258  BH = bits2octets(BH, q);
259 
260  // Step (a) - private key to byte array
261  SecByteBlock BX(STDMAX(rlen, x.MinEncodedSize()));
262  x.Encode(BX, BX.size());
263 
264  // Step (b)
265  SecByteBlock V(H::DIGESTSIZE);
266  std::fill(V.begin(), V.begin()+H::DIGESTSIZE, one);
267 
268  // Step (c)
269  SecByteBlock K(H::DIGESTSIZE);
270  std::fill(K.begin(), K.begin()+H::DIGESTSIZE, zero);
271 
272  // Step (d)
273  m_hmac.SetKey(K, K.size());
274  m_hmac.Update(V, V.size());
275  m_hmac.Update(&zero, 1);
276  m_hmac.Update(BX, BX.size());
277  m_hmac.Update(BH, BH.size());
278  m_hmac.TruncatedFinal(K, K.size());
279 
280  // Step (e)
281  m_hmac.SetKey(K, K.size());
282  m_hmac.Update(V, V.size());
283  m_hmac.TruncatedFinal(V, V.size());
284 
285  // Step (f)
286  m_hmac.SetKey(K, K.size());
287  m_hmac.Update(V, V.size());
288  m_hmac.Update(&one, 1);
289  m_hmac.Update(BX, BX.size());
290  m_hmac.Update(BH, BH.size());
291  m_hmac.TruncatedFinal(K, K.size());
292 
293  // Step (g)
294  m_hmac.SetKey(K, K.size());
295  m_hmac.Update(V, V.size());
296  m_hmac.TruncatedFinal(V, V.size());
297 
298  Integer k;
299  SecByteBlock temp(rlen);
300  for (;;)
301  {
302  // We want qlen bits, but we support only hash functions with an output length
303  // multiple of 8; hence, we will gather rlen bits, i.e., rolen octets.
304  size_t toff = 0;
305  while (toff < rlen)
306  {
307  m_hmac.Update(V, V.size());
308  m_hmac.TruncatedFinal(V, V.size());
309 
310  size_t cc = STDMIN(V.size(), temp.size() - toff);
311  memcpy_s(temp+toff, temp.size() - toff, V, cc);
312  toff += cc;
313  }
314 
315  k = bits2int(temp, qlen);
316  if (k > 0 && k < q)
317  break;
318 
319  // k is not in the proper range; update K and V, and loop.
320  m_hmac.Update(V, V.size());
321  m_hmac.Update(&zero, 1);
322  m_hmac.TruncatedFinal(K, K.size());
323 
324  m_hmac.SetKey(K, K.size());
325  m_hmac.Update(V, V.size());
326  m_hmac.TruncatedFinal(V, V.size());
327  }
328 
329  return k;
330  }
331 
332 protected:
333 
334 #if 0
335  // Determine bits without converting to an Integer
336  inline unsigned int BitCount(const byte* buffer, size_t size) const
337  {
338  unsigned int idx = 0;
339  while (idx < size && buffer[idx] == 0) { idx++; }
340  return (size-idx)*8 - (8-BitPrecision(buffer[idx]));
341  }
342 #endif
343 
344  Integer bits2int(const SecByteBlock& bits, size_t qlen) const
345  {
346  Integer ret(bits, bits.size());
347  size_t blen = bits.size()*8;
348 
349  if (blen > qlen)
350  ret >>= blen - qlen;
351 
352  return ret;
353  }
354 
355  // RFC 6979 support function. Takes an integer and converts it into bytes that
356  // are the same length as an elliptic curve's order.
357  SecByteBlock int2octets(const Integer& val, size_t rlen) const
358  {
359  SecByteBlock block(val.MinEncodedSize());
360  val.Encode(block, val.MinEncodedSize());
361 
362  if (block.size() == rlen)
363  return block;
364 
365  // The least significant bytes are the ones we need to preserve.
366  SecByteBlock t(rlen);
367  if (block.size() > rlen)
368  {
369  size_t offset = block.size() - rlen;
370  memcpy(t, block + offset, rlen);
371  }
372  else // block.size() < rlen
373  {
374  size_t offset = rlen - block.size();
375  memset(t, '\x00', offset);
376  memcpy(t + offset, block, rlen - offset);
377  }
378 
379  return t;
380  }
381 
382  // Turn a stream of bits into a set of bytes with the same length as an elliptic
383  // curve's order.
384  SecByteBlock bits2octets(const SecByteBlock& in, const Integer& q) const
385  {
386  Integer b2 = bits2int(in, in.size()*8);
387  Integer b1 = b2 - q;
388  return int2octets(b1.IsNegative() ? b2 : b1, q.ByteCount());
389  }
390 
391 private:
392  mutable H m_hash;
393  mutable HMAC<H> m_hmac;
394 };
395 
396 //! \class DL_Algorithm_GDSA_ISO15946
397 //! \brief German Digital Signature Algorithm
398 //! \tparam T FieldElement type or class
399 //! \sa Erwin Hess, Marcus Schafheutle, and Pascale Serf <A HREF="http://www.teletrust.de/fileadmin/files/oid/ecgdsa_final.pdf">The
400 //! Digital Signature Scheme ECGDSA (October 24, 2006)</A>
401 template <class T>
403 {
404 public:
405  CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "GDSA-ISO15946";}
406 
407  virtual ~DL_Algorithm_GDSA_ISO15946() {}
408 
409  void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
410  {
411  const Integer &q = params.GetSubgroupOrder();
412  // r = x(k * G) mod q
413  r = params.ConvertElementToInteger(params.ExponentiateBase(k)) % q;
414  // s = (k * r − h(m)) * d_A mod q
415  s = (k * r - e) * x % q;
416  CRYPTOPP_ASSERT(!!r && !!s);
417  }
418 
419  bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
420  {
421  const Integer &q = params.GetSubgroupOrder();
422  if (r>=q || r<1 || s>=q || s<1)
423  return false;
424 
425  const Integer& rInv = r.InverseMod(q);
426  Integer u1 = (rInv * e) % q;
427  Integer u2 = (rInv * s) % q;
428  // verify x(G^u1 + P_A^u2) mod q
429  return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
430  }
431 };
432 
433 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer>;
434 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA1>;
435 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA224>;
436 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA256>;
437 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA384>;
438 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA512>;
439 
440 //! \class DL_Algorithm_NR
441 //! \brief NR algorithm
442 //! \tparam T FieldElement type or class
443 template <class T>
445 {
446 public:
447  CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "NR";}
448 
449  virtual ~DL_Algorithm_NR() {}
450 
451  void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
452  {
453  const Integer &q = params.GetSubgroupOrder();
454  r = (r + e) % q;
455  s = (k - x*r) % q;
456  CRYPTOPP_ASSERT(!!r);
457  }
458 
459  bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
460  {
461  const Integer &q = params.GetSubgroupOrder();
462  if (r>=q || r<1 || s>=q)
463  return false;
464 
465  // check r == (m_g^s * m_y^r + m) mod m_q
466  return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q;
467  }
468 };
469 
470 //! \class DL_PublicKey_GFP
471 //! \brief Discrete Log (DL) public key in GF(p) groups
472 //! \tparam GP GroupParameters derived class
473 //! \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.
474 template <class GP>
476 {
477 public:
478  virtual ~DL_PublicKey_GFP() {}
479 
480  //! \brief Initialize a public key over GF(p)
481  //! \param params the group parameters
482  //! \param y the public element
483  void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &y)
484  {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);}
485 
486  //! \brief Initialize a public key over GF(p)
487  //! \param p the modulus
488  //! \param g the generator
489  //! \param y the public element
490  void Initialize(const Integer &p, const Integer &g, const Integer &y)
491  {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);}
492 
493  //! \brief Initialize a public key over GF(p)
494  //! \param p the modulus
495  //! \param q the subgroup order
496  //! \param g the generator
497  //! \param y the public element
498  void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
499  {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);}
500 
501  // X509PublicKey
503  {this->SetPublicElement(Integer(bt));}
505  {this->GetPublicElement().DEREncode(bt);}
506 };
507 
508 //! \class DL_PrivateKey_GFP
509 //! \brief Discrete Log (DL) private key in GF(p) groups
510 //! \tparam GP GroupParameters derived class
511 template <class GP>
513 {
514 public:
515  virtual ~DL_PrivateKey_GFP() {}
516 
517  //! \brief Create a private key
518  //! \param rng a RandomNumberGenerator derived class
519  //! \param modulusBits the size of the modulus, in bits
520  //! \details This function overload of Initialize() creates a new private key because it
521  //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,
522  //! then use one of the other Initialize() overloads.
523  void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
524  {this->GenerateRandomWithKeySize(rng, modulusBits);}
525 
526  //! \brief Create a private key
527  //! \param rng a RandomNumberGenerator derived class
528  //! \param p the modulus
529  //! \param g the generator
530  //! \details This function overload of Initialize() creates a new private key because it
531  //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,
532  //! then use one of the other Initialize() overloads.
533  void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
534  {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));}
535 
536  //! \brief Create a private key
537  //! \param rng a RandomNumberGenerator derived class
538  //! \param p the modulus
539  //! \param q the subgroup order
540  //! \param g the generator
541  //! \details This function overload of Initialize() creates a new private key because it
542  //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,
543  //! then use one of the other Initialize() overloads.
544  void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g)
545  {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));}
546 
547  //! \brief Initialize a private key over GF(p)
548  //! \param params the group parameters
549  //! \param x the private exponent
550  void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &x)
551  {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);}
552 
553  //! \brief Initialize a private key over GF(p)
554  //! \param p the modulus
555  //! \param g the generator
556  //! \param x the private exponent
557  void Initialize(const Integer &p, const Integer &g, const Integer &x)
558  {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);}
559 
560  //! \brief Initialize a private key over GF(p)
561  //! \param p the modulus
562  //! \param q the subgroup order
563  //! \param g the generator
564  //! \param x the private exponent
565  void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x)
566  {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);}
567 };
568 
569 //! \class DL_SignatureKeys_GFP
570 //! \brief Discrete Log (DL) signing/verification keys in GF(p) groups
572 {
576 };
577 
578 //! \class DL_CryptoKeys_GFP
579 //! \brief Discrete Log (DL) encryption/decryption keys in GF(p) groups
581 {
585 };
586 
587 //! \class DL_PublicKey_GFP_OldFormat
588 //! \brief Discrete Log (DL) public key in GF(p) groups
589 //! \tparam BASE GroupParameters derived class
590 //! \deprecated This implementation uses a non-standard Crypto++ key format. New implementations
591 //! should use DL_PublicKey_GFP and DL_PrivateKey_GFP
592 template <class BASE>
593 class DL_PublicKey_GFP_OldFormat : public BASE
594 {
595 public:
596  virtual ~DL_PublicKey_GFP_OldFormat() {}
597 
598  void BERDecode(BufferedTransformation &bt)
599  {
600  BERSequenceDecoder seq(bt);
601  Integer v1(seq);
602  Integer v2(seq);
603  Integer v3(seq);
604 
605  if (seq.EndReached())
606  {
607  this->AccessGroupParameters().Initialize(v1, v1/2, v2);
608  this->SetPublicElement(v3);
609  }
610  else
611  {
612  Integer v4(seq);
613  this->AccessGroupParameters().Initialize(v1, v2, v3);
614  this->SetPublicElement(v4);
615  }
616 
617  seq.MessageEnd();
618  }
619 
620  void DEREncode(BufferedTransformation &bt) const
621  {
622  DERSequenceEncoder seq(bt);
623  this->GetGroupParameters().GetModulus().DEREncode(seq);
624  if (this->GetGroupParameters().GetCofactor() != 2)
625  this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
626  this->GetGroupParameters().GetGenerator().DEREncode(seq);
627  this->GetPublicElement().DEREncode(seq);
628  seq.MessageEnd();
629  }
630 };
631 
632 //! \class DL_PrivateKey_GFP_OldFormat
633 //! \brief Discrete Log (DL) private key in GF(p) groups
634 //! \tparam BASE GroupParameters derived class
635 //! \deprecated This implementation uses a non-standard Crypto++ key format. New implementations
636 //! should use DL_PublicKey_GFP and DL_PrivateKey_GFP
637 template <class BASE>
638 class DL_PrivateKey_GFP_OldFormat : public BASE
639 {
640 public:
641  virtual ~DL_PrivateKey_GFP_OldFormat() {}
642 
643  void BERDecode(BufferedTransformation &bt)
644  {
645  BERSequenceDecoder seq(bt);
646  Integer v1(seq);
647  Integer v2(seq);
648  Integer v3(seq);
649  Integer v4(seq);
650 
651  if (seq.EndReached())
652  {
653  this->AccessGroupParameters().Initialize(v1, v1/2, v2);
654  this->SetPrivateExponent(v4 % (v1/2)); // some old keys may have x >= q
655  }
656  else
657  {
658  Integer v5(seq);
659  this->AccessGroupParameters().Initialize(v1, v2, v3);
660  this->SetPrivateExponent(v5);
661  }
662 
663  seq.MessageEnd();
664  }
665 
666  void DEREncode(BufferedTransformation &bt) const
667  {
668  DERSequenceEncoder seq(bt);
669  this->GetGroupParameters().GetModulus().DEREncode(seq);
670  if (this->GetGroupParameters().GetCofactor() != 2)
671  this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
672  this->GetGroupParameters().GetGenerator().DEREncode(seq);
673  this->GetGroupParameters().ExponentiateBase(this->GetPrivateExponent()).DEREncode(seq);
674  this->GetPrivateExponent().DEREncode(seq);
675  seq.MessageEnd();
676  }
677 };
678 
679 //! \class GDSA
680 //! \brief DSA signature scheme
681 //! \tparam H HashTransformation derived class
682 //! \sa <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a>
683 //! \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2
684 template <class H>
685 struct GDSA : public DL_SS<
686  DL_SignatureKeys_GFP,
687  DL_Algorithm_GDSA<Integer>,
688  DL_SignatureMessageEncodingMethod_DSA,
689  H>
690 {
691 };
692 
693 //! \class NR
694 //! \brief NR signature scheme
695 //! \tparam H HashTransformation derived class
696 //! \sa <a href="http://www.weidai.com/scan-mirror/sig.html#NR">NR</a>
697 template <class H>
698 struct NR : public DL_SS<
699  DL_SignatureKeys_GFP,
700  DL_Algorithm_NR<Integer>,
701  DL_SignatureMessageEncodingMethod_NR,
702  H>
703 {
704 };
705 
706 //! \class DL_GroupParameters_DSA
707 //! \brief DSA group parameters
708 //! \details These are GF(p) group parameters that are allowed by the DSA standard
709 //! \sa DL_Keys_DSA
711 {
712 public:
713  virtual ~DL_GroupParameters_DSA() {}
714 
715  /*! also checks that the lengths of p and q are allowed by the DSA standard */
716  bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
717  /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */
718  /*! ModulusSize must be between DSA::MIN_PRIME_LENGTH and DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE */
719  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
720 
721  static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits)
722  {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;}
723 
724  enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024};
725 };
726 
727 template <class H>
728 class DSA2;
729 
730 //! \class DL_Keys_DSA
731 //! \brief DSA keys
732 //! \sa DL_GroupParameters_DSA
734 {
737 };
738 
739 //! \class DSA2
740 //! \brief DSA signature scheme
741 //! \tparam H HashTransformation derived class
742 //! \details The class is named DSA2 instead of DSA for backwards compatibility because DSA was a non-template class.
743 //! \sa <a href="http://en.wikipedia.org/wiki/Digital_Signature_Algorithm">DSA</a>, as specified in FIPS 186-3
744 //! \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2
745 template <class H>
746 class DSA2 : public DL_SS<
747  DL_Keys_DSA,
748  DL_Algorithm_GDSA<Integer>,
749  DL_SignatureMessageEncodingMethod_DSA,
750  H,
751  DSA2<H> >
752 {
753 public:
754  static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();}
755 };
756 
757 //! \class DSA_RFC6979
758 //! \brief DSA deterministic signature scheme
759 //! \tparam H HashTransformation derived class
760 //! \sa <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a>
761 //! \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2
762 template <class H>
763 struct DSA_RFC6979 : public DL_SS<
764  DL_SignatureKeys_GFP,
765  DL_Algorithm_DSA_RFC6979<Integer, H>,
766  DL_SignatureMessageEncodingMethod_DSA,
767  H,
768  DSA_RFC6979<H> >
769 {
770  static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("DSA-RFC6979/") + H::StaticAlgorithmName();}
771 };
772 
773 //! DSA with SHA-1, typedef'd for backwards compatibility
774 typedef DSA2<SHA1> DSA;
775 
776 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP<DL_GroupParameters_DSA>;
777 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP<DL_GroupParameters_DSA>;
779 
780 //! \class DL_EncryptionAlgorithm_Xor
781 //! \brief P1363 based XOR Encryption Method
782 //! \tparam MAC MessageAuthenticationCode derived class used for MAC computation
783 //! \tparam DHAES_MODE flag indicating DHAES mode
784 //! \tparam LABEL_OCTETS flag indicating the label is octet count
785 //! \details DL_EncryptionAlgorithm_Xor is based on an early P1363 draft, which itself appears to be based on an
786 //! 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
787 //! Ecryption Schemes with <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=false</tt> and <tt>LABEL_OCTETS=true</tt>.
788 //! \details If you need this method for Crypto++ 4.2 compatibility, then use the ECIES template class with
789 //! <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=false</tt> and <tt>LABEL_OCTETS=true</tt>.
790 //! \details If you need this method for Bouncy Castle 1.54 and Botan 1.11 compatibility, then use the ECIES template class with
791 //! <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=ture</tt> and <tt>LABEL_OCTETS=false</tt>.
792 //! \details Bouncy Castle 1.54 and Botan 1.11 compatibility are the default template parameters.
793 //! \since Crypto++ 4.0
794 template <class MAC, bool DHAES_MODE, bool LABEL_OCTETS=false>
796 {
797 public:
798  virtual ~DL_EncryptionAlgorithm_Xor() {}
799 
800  bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
801  size_t GetSymmetricKeyLength(size_t plaintextLength) const
802  {return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);}
803  size_t GetSymmetricCiphertextLength(size_t plaintextLength) const
804  {return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);}
805  size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const
806  {return SaturatingSubtract(ciphertextLength, static_cast<size_t>(MAC::DIGESTSIZE));}
807  void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
808  {
809  CRYPTOPP_UNUSED(rng);
810  const byte *cipherKey = NULL, *macKey = NULL;
811  if (DHAES_MODE)
812  {
813  macKey = key;
814  cipherKey = key + MAC::DEFAULT_KEYLENGTH;
815  }
816  else
817  {
818  cipherKey = key;
819  macKey = key + plaintextLength;
820  }
821 
822  ConstByteArrayParameter encodingParameters;
823  parameters.GetValue(Name::EncodingParameters(), encodingParameters);
824 
825  if (plaintextLength) // Coverity finding
826  xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
827 
828  MAC mac(macKey);
829  mac.Update(ciphertext, plaintextLength);
830  mac.Update(encodingParameters.begin(), encodingParameters.size());
831  if (DHAES_MODE)
832  {
833  byte L[8];
834  PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size())));
835  mac.Update(L, 8);
836  }
837  mac.Final(ciphertext + plaintextLength);
838  }
839  DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
840  {
841  size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength);
842  const byte *cipherKey, *macKey;
843  if (DHAES_MODE)
844  {
845  macKey = key;
846  cipherKey = key + MAC::DEFAULT_KEYLENGTH;
847  }
848  else
849  {
850  cipherKey = key;
851  macKey = key + plaintextLength;
852  }
853 
854  ConstByteArrayParameter encodingParameters;
855  parameters.GetValue(Name::EncodingParameters(), encodingParameters);
856 
857  MAC mac(macKey);
858  mac.Update(ciphertext, plaintextLength);
859  mac.Update(encodingParameters.begin(), encodingParameters.size());
860  if (DHAES_MODE)
861  {
862  byte L[8];
863  PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size())));
864  mac.Update(L, 8);
865  }
866  if (!mac.Verify(ciphertext + plaintextLength))
867  return DecodingResult();
868 
869  if (plaintextLength) // Coverity finding
870  xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
871 
872  return DecodingResult(plaintextLength);
873  }
874 };
875 
876 //! _
877 template <class T, bool DHAES_MODE, class KDF>
879 {
880 public:
881  virtual ~DL_KeyDerivationAlgorithm_P1363() {}
882 
883  bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;}
884  void Derive(const DL_GroupParameters<T> &params, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &parameters) const
885  {
886  SecByteBlock agreedSecret;
887  if (DHAES_MODE)
888  {
889  agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false));
890  params.EncodeElement(true, ephemeralPublicKey, agreedSecret);
891  params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true));
892  }
893  else
894  {
895  agreedSecret.New(params.GetEncodedElementSize(false));
896  params.EncodeElement(false, agreedElement, agreedSecret);
897  }
898 
899  ConstByteArrayParameter derivationParameters;
900  parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters);
901  KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size());
902  }
903 };
904 
905 //! \class DLIES
906 //! \brief Discrete Log Integrated Encryption Scheme
907 //! \tparam COFACTOR_OPTION \ref CofactorMultiplicationOption "cofactor multiplication option"
908 //! \tparam HASH HashTransformation derived class used for key drivation and MAC computation
909 //! \tparam DHAES_MODE flag indicating if the MAC includes addition context parameters such as the label
910 //! \tparam LABEL_OCTETS flag indicating if the label size is specified in octets or bits
911 //! \details DLIES is an Integer based Integrated Encryption Scheme (IES). The scheme combines a Key Encapsulation Method (KEM)
912 //! with a Data Encapsulation Method (DEM) and a MAC tag. The scheme is
913 //! <A HREF="http://en.wikipedia.org/wiki/ciphertext_indistinguishability">IND-CCA2</A>, which is a strong notion of security.
914 //! You should prefer an Integrated Encryption Scheme over homegrown schemes.
915 //! \details The library's original implementation is based on an early P1363 draft, which itself appears to be based on an early Certicom
916 //! 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
917 //! Schemes with <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=false</tt> and <tt>LABEL_OCTETS=true</tt>.
918 //! \details If you desire an Integrated Encryption Scheme with Crypto++ 4.2 compatibility, then use the DLIES template class with
919 //! <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=false</tt> and <tt>LABEL_OCTETS=true</tt>.
920 //! \details If you desire an Integrated Encryption Scheme with Bouncy Castle 1.54 and Botan 1.11 compatibility, then use the DLIES
921 //! template class with <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=true</tt> and <tt>LABEL_OCTETS=false</tt>.
922 //! \details The default template parameters ensure compatibility with Bouncy Castle 1.54 and Botan 1.11. The combination of
923 //! <tt>IncompatibleCofactorMultiplication</tt> and <tt>DHAES_MODE=true</tt> is recommended for best efficiency and security.
924 //! SHA1 is used for compatibility reasons, but it can be changed if desired. SHA-256 or another hash will likely improve the
925 //! security provided by the MAC. The hash is also used in the key derivation function as a PRF.
926 //! \details Below is an example of constructing a Crypto++ 4.2 compatible DLIES encryptor and decryptor.
927 //! <pre>
928 //! AutoSeededRandomPool prng;
929 //! DL_PrivateKey_GFP<DL_GroupParameters_GFP> key;
930 //! key.Initialize(prng, 2048);
931 //!
932 //! DLIES<SHA1,NoCofactorMultiplication,true,true>::Decryptor decryptor(key);
933 //! DLIES<SHA1,NoCofactorMultiplication,true,true>::Encryptor encryptor(decryptor);
934 //! </pre>
935 //! \sa ECIES, <a href="http://www.weidai.com/scan-mirror/ca.html#DLIES">Discrete Log Integrated Encryption Scheme (DLIES)</a>,
936 //! 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
937 //! Curve Integrated Encryption Schemes</A>
938 //! \since Crypto++ 4.0, Crypto++ 5.7 for Bouncy Castle and Botan compatibility
939 template <class HASH = SHA1, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true, bool LABEL_OCTETS=false>
940 struct DLIES
941  : public DL_ES<
942  DL_CryptoKeys_GFP,
943  DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>,
944  DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<HASH> >,
945  DL_EncryptionAlgorithm_Xor<HMAC<HASH>, DHAES_MODE, LABEL_OCTETS>,
946  DLIES<> >
947 {
948  static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized
949 };
950 
951 NAMESPACE_END
952 
953 #if CRYPTOPP_MSC_VERSION
954 # pragma warning(pop)
955 #endif
956 
957 #endif
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:29
void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g)
Create a private key.
Definition: gfpcrypt.h:544
bool IsIdentity(const Integer &element) const
Determines if an element is an identity.
Definition: gfpcrypt.h:164
Discrete Log Integrated Encryption Scheme.
Definition: gfpcrypt.h:940
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: gfpcrypt.h:168
Classes for working with NameValuePairs.
Utility functions for the Crypto++ library.
GF(p) group parameters.
Definition: gfpcrypt.h:158
void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &y)
Initialize a public key over GF(p)
Definition: gfpcrypt.h:483
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition: integer.cpp:3369
Integer GetGroupOrder() const
Retrieves the order of the group.
Definition: gfpcrypt.h:80
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:749
This file contains helper classes/functions for implementing public key algorithms.
Interface for deterministic signers.
Definition: pubkey.h:1281
void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
Create a private key.
Definition: gfpcrypt.h:523
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULL)
Access a block of memory.
Definition: misc.h:2123
void Initialize(const Integer &p, const Integer &g)
Initialize a group parameters over integers.
Definition: gfpcrypt.h:58
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:736
P1363 based XOR Encryption Method.
Definition: gfpcrypt.h:795
Converts an enumeration to a type suitable for use as a template parameter.
Definition: cryptlib.h:116
Abstract base classes that provide a uniform interface to this library.
void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memcpy()
Definition: misc.h:366
virtual Integer ConvertElementToInteger(const Element &element) const =0
Converts an element to an Integer.
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:524
Interface for key derivation algorithms used in DL cryptosystems.
Definition: pubkey.h:1304
Classes for automatic resource management.
size_t size() const
Length of the memory block.
Definition: algparam.h:93
Library configuration file.
DSA keys.
Definition: gfpcrypt.h:733
Interface for random number generators.
Definition: cryptlib.h:1188
void Initialize(RandomNumberGenerator &rng, unsigned int pbits)
Create a group parameters over integers.
Definition: gfpcrypt.h:52
size_t MinEncodedSize(Signedness sign=UNSIGNED) const
Minimum number of bytes to encode this integer.
Definition: integer.cpp:3354
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:647
Discrete Log (DL) encryption scheme.
Definition: pubkey.h:2155
SecBlock<byte> typedef.
Definition: secblock.h:731
BER Sequence Decoder.
Definition: asn.h:303
Interface for buffered transformations.
Definition: cryptlib.h:1352
DSA signature scheme.
Definition: gfpcrypt.h:685
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:89
static const Integer & One()
Integer representing 1.
Definition: integer.cpp:3035
bool operator==(const OID &lhs, const OID &rhs)
Compare two OIDs for equality.
Interface for Discrete Log (DL) public keys.
Definition: pubkey.h:992
virtual const Element & GetSubgroupGenerator() const
Retrieves the subgroup generator.
Definition: pubkey.h:793
void Initialize(const Integer &p, const Integer &q, const Integer &g)
Initialize a group parameters over integers.
Definition: gfpcrypt.h:65
Discrete Log (DL) signature scheme.
Definition: pubkey.h:2132
void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
Create a private key.
Definition: gfpcrypt.h:533
Integer ConvertElementToInteger(const Element &element) const
Converts an element to an Integer.
Definition: gfpcrypt.h:90
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
Definition: integer.cpp:3305
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: gfpcrypt.h:130
bool operator!=(const OID &lhs, const OID &rhs)
Compare two OIDs for inequality.
DL_FixedBasePrecomputation< Element > & AccessBasePrecomputation()
Retrieves the group precomputation.
Definition: gfpcrypt.h:138
Returns a decoding results.
Definition: cryptlib.h:238
DSA2< SHA1 > DSA
DSA with SHA-1, typedef&#39;d for backwards compatibility.
Definition: gfpcrypt.h:774
Classes for HMAC message authentication codes.
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:337
DSA signature scheme.
Definition: gfpcrypt.h:728
Discrete Log (DL) public key in GF(p) groups.
Definition: gfpcrypt.h:593
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:498
Interface for Elgamal-like signature algorithms.
Definition: pubkey.h:1257
void Initialize(const Integer &p, const Integer &g, const Integer &y)
Initialize a public key over GF(p)
Definition: gfpcrypt.h:490
const char * EncodingParameters()
ConstByteArrayParameter.
Definition: argnames.h:66
Discrete Log (DL) signing/verification keys in GF(p) groups.
Definition: gfpcrypt.h:571
DSA deterministic signature scheme.
Definition: gfpcrypt.h:763
Discrete Log (DL) encryption/decryption keys in GF(p) groups.
Definition: gfpcrypt.h:580
const Integer & GetSubgroupOrder() const
Retrieves the subgroup order.
Definition: gfpcrypt.h:79
Multiple precision integer with arithmetic operations.
Definition: integer.h:43
NR signature scheme.
Definition: gfpcrypt.h:698
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
Definition: misc.h:847
Integer-based GroupParameters default implementation.
Definition: gfpcrypt.h:120
const DL_GroupPrecomputation< Element > & GetGroupPrecomputation() const
Retrieves the group precomputation.
Definition: pubkey.h:958
const DL_FixedBasePrecomputation< Element > & GetBasePrecomputation() const
Retrieves the group precomputation.
Definition: gfpcrypt.h:137
byte order is big-endian
Definition: cryptlib.h:128
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:477
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:62
DSA group parameters.
Definition: gfpcrypt.h:710
Classes and functions for working with ANS.1 objects.
Classes for SHA-1 and SHA-2 family of message digests.
void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x)
Initialize a private key over GF(p)
Definition: gfpcrypt.h:565
void Initialize(const DL_GroupParameters_IntegerBased &params)
Initialize a group parameters over integers.
Definition: gfpcrypt.h:43
Discrete Log (DL) public key in GF(p) groups.
Definition: gfpcrypt.h:475
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:499
DSA signature algorithm based on RFC 6979.
Definition: gfpcrypt.h:236
DER Sequence Encoder.
Definition: asn.h:313
Discrete Log (DL) private key in GF(p) groups.
Definition: gfpcrypt.h:638
Discrete Log (DL) private key in GF(p) groups.
Definition: gfpcrypt.h:512
GDSA algorithm.
Definition: gfpcrypt.h:198
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:28
void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &x)
Initialize a private key over GF(p)
Definition: gfpcrypt.h:550
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
Integer InverseMod(const Integer &n) const
calculate multiplicative inverse of *this mod n
Definition: integer.cpp:4370
virtual unsigned int GetEncodedElementSize(bool reversible) const =0
Retrieves the encoded element&#39;s size.
NR algorithm.
Definition: gfpcrypt.h:444
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: gfpcrypt.h:133
Multiple precision integer with arithmetic operations.
void DEREncodePublicKey(BufferedTransformation &bt) const
encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
Definition: gfpcrypt.h:504
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
Definition: misc.h:487
const char * KeyDerivationParameters()
ConstByteArrayParameter.
Definition: argnames.h:67
Crypto++ library namespace.
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition: pubkey.h:1315
Base implementation of Discrete Log (DL) group parameters.
Definition: pubkey.h:947
void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t)
decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
Definition: gfpcrypt.h:502
virtual Element ExponentiateBase(const Integer &exponent) const
Retrieves the subgroup generator.
Definition: pubkey.h:803
German Digital Signature Algorithm.
Definition: gfpcrypt.h:402
void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
Initialize a public key over GF(p)
Definition: gfpcrypt.h:498
Integer-based GroupParameters specialization.
Definition: gfpcrypt.h:34
Encode and decode ASN.1 objects with additional information.
Definition: asn.h:374
void Initialize(const Integer &p, const Integer &g, const Integer &x)
Initialize a private key over GF(p)
Definition: gfpcrypt.h:557
Object Identifier.
Definition: asn.h:166
unsigned int BitPrecision(const T &value)
Returns the number of bits required for a value.
Definition: misc.h:654
unsigned int ByteCount() const
Determines the number of bytes required to represent the Integer.
Definition: integer.cpp:3296
Interface for retrieving values given their names.
Definition: cryptlib.h:279
virtual const Integer & GetSubgroupOrder() const =0
Retrieves the subgroup order.