Crypto++  5.6.4
Free C++ class library of cryptographic schemes
gfpcrypt.h
Go to the documentation of this file.
1 #ifndef CRYPTOPP_GFPCRYPT_H
2 #define CRYPTOPP_GFPCRYPT_H
3 
4 /** \file
5  Implementation of schemes based on DL over GF(p)
6 */
7 
8 #include "config.h"
9 
10 #if CRYPTOPP_MSC_VERSION
11 # pragma warning(push)
12 # pragma warning(disable: 4189)
13 #endif
14 
15 #include "cryptlib.h"
16 #include "pubkey.h"
17 #include "integer.h"
18 #include "modexppc.h"
19 #include "algparam.h"
20 #include "smartptr.h"
21 #include "sha.h"
22 #include "asn.h"
23 #include "hmac.h"
24 #include "misc.h"
25 
26 NAMESPACE_BEGIN(CryptoPP)
27 
28 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters<Integer>;
29 
30 //! _
31 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial<DL_GroupParameters<Integer> >
32 {
34 
35 public:
36  void Initialize(const DL_GroupParameters_IntegerBased &params)
37  {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());}
38  void Initialize(RandomNumberGenerator &rng, unsigned int pbits)
39  {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));}
40  void Initialize(const Integer &p, const Integer &g)
41  {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);}
42  void Initialize(const Integer &p, const Integer &q, const Integer &g)
43  {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);}
44 
45  // ASN1Object interface
46  void BERDecode(BufferedTransformation &bt);
47  void DEREncode(BufferedTransformation &bt) const;
48 
49  // GeneratibleCryptoMaterial interface
50  /*! parameters: (ModulusSize, SubgroupOrderSize (optional)) */
51  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
52  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
53  void AssignFrom(const NameValuePairs &source);
54 
55  // DL_GroupParameters
56  const Integer & GetSubgroupOrder() const {return m_q;}
57  Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();}
58  bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
59  bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const;
60  bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;}
61 
62 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
63  // Cygwin i386 crash at -O3; see .
64  void EncodeElement(bool reversible, const Element &element, byte *encoded) const;
65  unsigned int GetEncodedElementSize(bool reversible) const;
66 #else
67  void EncodeElement(bool reversible, const Element &element, byte *encoded) const
68  {CRYPTOPP_UNUSED(reversible); element.Encode(encoded, GetModulus().ByteCount());}
69  unsigned int GetEncodedElementSize(bool reversible) const
70  {CRYPTOPP_UNUSED(reversible); return GetModulus().ByteCount();}
71 #endif
72 
73  Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const;
74  Integer ConvertElementToInteger(const Element &element) const
75  {return element;}
76  Integer GetMaxExponent() const;
77  static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
78 
79  OID GetAlgorithmID() const;
80 
81  virtual const Integer & GetModulus() const =0;
82  virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0;
83 
84  void SetSubgroupOrder(const Integer &q)
85  {m_q = q; ParametersChanged();}
86 
87 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
89 #endif
90 
91 protected:
92  Integer ComputeGroupOrder(const Integer &modulus) const
93  {return modulus-(GetFieldType() == 1 ? 1 : -1);}
94 
95  // GF(p) = 1, GF(p^2) = 2
96  virtual int GetFieldType() const =0;
97  virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const;
98 
99 private:
100  Integer m_q;
101 };
102 
103 //! _
104 template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element> >
105 class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl<GROUP_PRECOMP, BASE_PRECOMP, DL_GroupParameters_IntegerBased>
106 {
108 
109 public:
110  typedef typename GROUP_PRECOMP::Element Element;
111 
112  // GeneratibleCryptoMaterial interface
113  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
114  {return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();}
115 
116  void AssignFrom(const NameValuePairs &source)
117  {AssignFromHelper<DL_GroupParameters_IntegerBased>(this, source);}
118 
119  // DL_GroupParameters
120  const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
122 
123  // IntegerGroupParameters
124  const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();}
125  const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());}
126 
127  void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together
128  {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();}
129 
130  // non-inherited
132  {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();}
134  {return !operator==(rhs);}
135 
136 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
138 #endif
139 };
140 
142 
143 //! GF(p) group parameters
144 class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>
145 {
146 public:
147  // DL_GroupParameters
148  bool IsIdentity(const Integer &element) const {return element == Integer::One();}
149  void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
150 
151  // NameValuePairs interface
152  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
153  {
154  return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();
155  }
156 
157  // used by MQV
158  Element MultiplyElements(const Element &a, const Element &b) const;
159  Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
160 
161 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
162  virtual ~DL_GroupParameters_GFP() {}
163 #endif
164 
165 protected:
166  int GetFieldType() const {return 1;}
167 };
168 
169 //! GF(p) group parameters that default to same primes
171 {
172 public:
174 
175 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
177 #endif
178 
179 protected:
180  unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;}
181 };
182 
183 //! GDSA algorithm
184 template <class T>
186 {
187 public:
188  CRYPTOPP_CONSTEXPR static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";}
189 
190  void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
191  {
192  const Integer &q = params.GetSubgroupOrder();
193  r %= q;
194  Integer kInv = k.InverseMod(q);
195  s = (kInv * (x*r + e)) % q;
196  CRYPTOPP_ASSERT(!!r && !!s);
197  }
198 
199  bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
200  {
201  const Integer &q = params.GetSubgroupOrder();
202  if (r>=q || r<1 || s>=q || s<1)
203  return false;
204 
205  Integer w = s.InverseMod(q);
206  Integer u1 = (e * w) % q;
207  Integer u2 = (r * w) % q;
208  // verify r == (g^u1 * y^u2 mod p) mod q
209  return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
210  }
211 
212 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
213  virtual ~DL_Algorithm_GDSA() {}
214 #endif
215 };
216 
217 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer>;
218 
219 //! NR algorithm
220 template <class T>
222 {
223 public:
224  CRYPTOPP_CONSTEXPR static const char * CRYPTOPP_API StaticAlgorithmName() {return "NR";}
225 
226  void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
227  {
228  const Integer &q = params.GetSubgroupOrder();
229  r = (r + e) % q;
230  s = (k - x*r) % q;
231  CRYPTOPP_ASSERT(!!r);
232  }
233 
234  bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
235  {
236  const Integer &q = params.GetSubgroupOrder();
237  if (r>=q || r<1 || s>=q)
238  return false;
239 
240  // check r == (m_g^s * m_y^r + m) mod m_q
241  return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q;
242  }
243 
244 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
245  virtual ~DL_Algorithm_NR() {}
246 #endif
247 };
248 
249 /*! DSA public key format is defined in 7.3.3 of RFC 2459. The
250  private key format is defined in 12.9 of PKCS #11 v2.10. */
251 template <class GP>
253 {
254 public:
255  void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &y)
256  {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);}
257  void Initialize(const Integer &p, const Integer &g, const Integer &y)
258  {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);}
259  void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
260  {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);}
261 
262  // X509PublicKey
264  {this->SetPublicElement(Integer(bt));}
266  {this->GetPublicElement().DEREncode(bt);}
267 
268 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
269  virtual ~DL_PublicKey_GFP() {}
270 #endif
271 };
272 
273 //! DL private key (in GF(p) groups)
274 template <class GP>
276 {
277 public:
278  void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
279  {this->GenerateRandomWithKeySize(rng, modulusBits);}
280  void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
281  {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));}
282  void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g)
283  {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));}
284  void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &x)
285  {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);}
286  void Initialize(const Integer &p, const Integer &g, const Integer &x)
287  {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);}
288  void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x)
289  {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);}
290 
291 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
292  virtual ~DL_PrivateKey_GFP() {}
293 #endif
294 };
295 
296 //! DL signing/verification keys (in GF(p) groups)
298 {
302 
303 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
304  virtual ~DL_SignatureKeys_GFP() {}
305 #endif
306 };
307 
308 //! DL encryption/decryption keys (in GF(p) groups)
310 {
314 
315 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
316  virtual ~DL_CryptoKeys_GFP() {}
317 #endif
318 };
319 
320 //! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format
321 template <class BASE>
322 class DL_PublicKey_GFP_OldFormat : public BASE
323 {
324 public:
325  void BERDecode(BufferedTransformation &bt)
326  {
327  BERSequenceDecoder seq(bt);
328  Integer v1(seq);
329  Integer v2(seq);
330  Integer v3(seq);
331 
332  if (seq.EndReached())
333  {
334  this->AccessGroupParameters().Initialize(v1, v1/2, v2);
335  this->SetPublicElement(v3);
336  }
337  else
338  {
339  Integer v4(seq);
340  this->AccessGroupParameters().Initialize(v1, v2, v3);
341  this->SetPublicElement(v4);
342  }
343 
344  seq.MessageEnd();
345  }
346 
347  void DEREncode(BufferedTransformation &bt) const
348  {
349  DERSequenceEncoder seq(bt);
350  this->GetGroupParameters().GetModulus().DEREncode(seq);
351  if (this->GetGroupParameters().GetCofactor() != 2)
352  this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
353  this->GetGroupParameters().GetGenerator().DEREncode(seq);
354  this->GetPublicElement().DEREncode(seq);
355  seq.MessageEnd();
356  }
357 
358 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
359  virtual ~DL_PublicKey_GFP_OldFormat() {}
360 #endif
361 };
362 
363 //! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format
364 template <class BASE>
365 class DL_PrivateKey_GFP_OldFormat : public BASE
366 {
367 public:
368  void BERDecode(BufferedTransformation &bt)
369  {
370  BERSequenceDecoder seq(bt);
371  Integer v1(seq);
372  Integer v2(seq);
373  Integer v3(seq);
374  Integer v4(seq);
375 
376  if (seq.EndReached())
377  {
378  this->AccessGroupParameters().Initialize(v1, v1/2, v2);
379  this->SetPrivateExponent(v4 % (v1/2)); // some old keys may have x >= q
380  }
381  else
382  {
383  Integer v5(seq);
384  this->AccessGroupParameters().Initialize(v1, v2, v3);
385  this->SetPrivateExponent(v5);
386  }
387 
388  seq.MessageEnd();
389  }
390 
391  void DEREncode(BufferedTransformation &bt) const
392  {
393  DERSequenceEncoder seq(bt);
394  this->GetGroupParameters().GetModulus().DEREncode(seq);
395  if (this->GetGroupParameters().GetCofactor() != 2)
396  this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
397  this->GetGroupParameters().GetGenerator().DEREncode(seq);
398  this->GetGroupParameters().ExponentiateBase(this->GetPrivateExponent()).DEREncode(seq);
399  this->GetPrivateExponent().DEREncode(seq);
400  seq.MessageEnd();
401  }
402 
403 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
404  virtual ~DL_PrivateKey_GFP_OldFormat() {}
405 #endif
406 };
407 
408 //! <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a>
409 template <class H>
410 struct GDSA : public DL_SS<
411  DL_SignatureKeys_GFP,
412  DL_Algorithm_GDSA<Integer>,
413  DL_SignatureMessageEncodingMethod_DSA,
414  H>
415 {
416 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
417  virtual ~GDSA() {}
418 #endif
419 };
420 
421 //! <a href="http://www.weidai.com/scan-mirror/sig.html#NR">NR</a>
422 template <class H>
423 struct NR : public DL_SS<
424  DL_SignatureKeys_GFP,
425  DL_Algorithm_NR<Integer>,
426  DL_SignatureMessageEncodingMethod_NR,
427  H>
428 {
429 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
430  virtual ~NR() {}
431 #endif
432 };
433 
434 //! DSA group parameters, these are GF(p) group parameters that are allowed by the DSA standard
436 {
437 public:
438  /*! also checks that the lengths of p and q are allowed by the DSA standard */
439  bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
440  /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */
441  /*! ModulusSize must be between DSA::MIN_PRIME_LENGTH and DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE */
442  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
443 
444  static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits)
445  {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;}
446 
447  enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024};
448 
449 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
450  virtual ~DL_GroupParameters_DSA() {}
451 #endif
452 };
453 
454 template <class H>
455 class DSA2;
456 
457 //! DSA keys
459 {
462 
463 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
464  virtual ~DL_Keys_DSA() {}
465 #endif
466 };
467 
468 //! <a href="http://en.wikipedia.org/wiki/Digital_Signature_Algorithm">DSA</a>, as specified in FIPS 186-3
469 // class named DSA2 instead of DSA for backwards compatibility (DSA was a non-template class)
470 template <class H>
471 class DSA2 : public DL_SS<
472  DL_Keys_DSA,
473  DL_Algorithm_GDSA<Integer>,
474  DL_SignatureMessageEncodingMethod_DSA,
475  H,
476  DSA2<H> >
477 {
478 public:
479  static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();}
480 
481 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
482  enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024};
483 #endif
484 
485 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
486  virtual ~DSA2() {}
487 #endif
488 };
489 
490 //! DSA with SHA-1, typedef'd for backwards compatibility
491 typedef DSA2<SHA> DSA;
492 
493 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP<DL_GroupParameters_DSA>;
494 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP<DL_GroupParameters_DSA>;
496 
497 //! the XOR encryption method, for use with DL-based cryptosystems
498 template <class MAC, bool DHAES_MODE>
500 {
501 public:
502  bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
503  size_t GetSymmetricKeyLength(size_t plaintextLength) const
504  {return plaintextLength + MAC::DEFAULT_KEYLENGTH;}
505  size_t GetSymmetricCiphertextLength(size_t plaintextLength) const
506  {return plaintextLength + MAC::DIGESTSIZE;}
507  size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const
508  {return (unsigned int)SaturatingSubtract(ciphertextLength, (unsigned int)MAC::DIGESTSIZE);}
509  void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
510  {
511  CRYPTOPP_UNUSED(rng);
512  const byte *cipherKey = NULL, *macKey = NULL;
513  if (DHAES_MODE)
514  {
515  macKey = key;
516  cipherKey = key + MAC::DEFAULT_KEYLENGTH;
517  }
518  else
519  {
520  cipherKey = key;
521  macKey = key + plaintextLength;
522  }
523 
524  ConstByteArrayParameter encodingParameters;
525  parameters.GetValue(Name::EncodingParameters(), encodingParameters);
526 
527  if (plaintextLength) // Coverity finding
528  xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
529 
530  MAC mac(macKey);
531  mac.Update(ciphertext, plaintextLength);
532  mac.Update(encodingParameters.begin(), encodingParameters.size());
533  if (DHAES_MODE)
534  {
535  byte L[8] = {0,0,0,0};
536  PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
537  mac.Update(L, 8);
538  }
539  mac.Final(ciphertext + plaintextLength);
540  }
541  DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
542  {
543  size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength);
544  const byte *cipherKey, *macKey;
545  if (DHAES_MODE)
546  {
547  macKey = key;
548  cipherKey = key + MAC::DEFAULT_KEYLENGTH;
549  }
550  else
551  {
552  cipherKey = key;
553  macKey = key + plaintextLength;
554  }
555 
556  ConstByteArrayParameter encodingParameters;
557  parameters.GetValue(Name::EncodingParameters(), encodingParameters);
558 
559  MAC mac(macKey);
560  mac.Update(ciphertext, plaintextLength);
561  mac.Update(encodingParameters.begin(), encodingParameters.size());
562  if (DHAES_MODE)
563  {
564  byte L[8] = {0,0,0,0};
565  PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
566  mac.Update(L, 8);
567  }
568  if (!mac.Verify(ciphertext + plaintextLength))
569  return DecodingResult();
570 
571  if (plaintextLength) // Coverity finding
572  xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
573 
574  return DecodingResult(plaintextLength);
575  }
576 
577 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
578  virtual ~DL_EncryptionAlgorithm_Xor() {}
579 #endif
580 };
581 
582 //! _
583 template <class T, bool DHAES_MODE, class KDF>
585 {
586 public:
587  bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;}
588  void Derive(const DL_GroupParameters<T> &params, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &parameters) const
589  {
590  SecByteBlock agreedSecret;
591  if (DHAES_MODE)
592  {
593  agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false));
594  params.EncodeElement(true, ephemeralPublicKey, agreedSecret);
595  params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true));
596  }
597  else
598  {
599  agreedSecret.New(params.GetEncodedElementSize(false));
600  params.EncodeElement(false, agreedElement, agreedSecret);
601  }
602 
603  ConstByteArrayParameter derivationParameters;
604  parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters);
605  KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size());
606  }
607 
608 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
609  virtual ~DL_KeyDerivationAlgorithm_P1363() {}
610 #endif
611 };
612 
613 //! Discrete Log Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#DLIES">DLIES</a>
614 template <class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true>
615 struct DLIES
616  : public DL_ES<
617  DL_CryptoKeys_GFP,
618  DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>,
619  DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<SHA1> >,
620  DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
621  DLIES<> >
622 {
623  static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized
624 
625 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
626  virtual ~DLIES() {}
627 #endif
628 };
629 
630 NAMESPACE_END
631 
632 #if CRYPTOPP_MSC_VERSION
633 # pragma warning(pop)
634 #endif
635 
636 #endif
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:29
virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0
Exponentiates a base to multiple exponents.
DSA2< SHA > DSA
DSA with SHA-1, typedef'd for backwards compatibility.
Definition: gfpcrypt.h:491
bool IsIdentity(const Integer &element) const
Determines if an element is an identity.
Definition: gfpcrypt.h:148
Discrete Log Integrated Encryption Scheme, AKA DLIES
Definition: gfpcrypt.h:615
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: gfpcrypt.h:152
Classes for working with NameValuePairs.
Utility functions for the Crypto++ library.
GF(p) group parameters.
Definition: gfpcrypt.h:144
Integer GetGroupOrder() const
Retrieves the order of the group.
Definition: gfpcrypt.h:57
This file contains helper classes/functions for implementing public key algorithms.
virtual Integer ConvertElementToInteger(const Element &element) const =0
Converts an element to an Integer.
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:758
the XOR encryption method, for use with DL-based cryptosystems
Definition: gfpcrypt.h:499
Converts a typename to an enumerated value.
Definition: cryptlib.h:120
Abstract base classes that provide a uniform interface to this library.
GF(p) group parameters that default to same primes.
Definition: gfpcrypt.h:170
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:1342
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:458
Interface for random number generators.
Definition: cryptlib.h:1193
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:647
Discrete Log (DL) encryption scheme.
Definition: pubkey.h:2237
SecBlock typedef.
Definition: secblock.h:731
BER Sequence Decoder.
Definition: asn.h:294
Interface for buffered transformations.
Definition: cryptlib.h:1359
DSA-1363
Definition: gfpcrypt.h:410
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:3019
bool operator==(const OID &lhs, const OID &rhs)
Compare two OIDs for equality.
Interface for Discrete Log (DL) public keys.
Definition: pubkey.h:1020
virtual const Element & GetSubgroupGenerator() const
Retrieves the subgroup generator.
Definition: pubkey.h:817
Discrete Log (DL) signature scheme.
Definition: pubkey.h:2214
Integer ConvertElementToInteger(const Element &element) const
Converts an element to an Integer.
Definition: gfpcrypt.h:74
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: gfpcrypt.h:113
bool operator!=(const OID &lhs, const OID &rhs)
Compare two OIDs for inequality.
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
DL_FixedBasePrecomputation< Element > & AccessBasePrecomputation()
Retrieves the group precomputation.
Definition: gfpcrypt.h:121
Returns a decoding results.
Definition: cryptlib.h:241
Classes for HMAC message authentication codes.
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:340
DSA, as specified in FIPS 186-3
Definition: gfpcrypt.h:455
provided for backwards compatibility, this class uses the old non-standard Crypto++ key format ...
Definition: gfpcrypt.h:322
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:554
Interface for Elgamal-like signature algorithms.
Definition: pubkey.h:1304
const char * EncodingParameters()
ConstByteArrayParameter.
Definition: argnames.h:65
DL signing/verification keys (in GF(p) groups)
Definition: gfpcrypt.h:297
DL encryption/decryption keys (in GF(p) groups)
Definition: gfpcrypt.h:309
const Integer & GetSubgroupOrder() const
Retrieves the subgroup order.
Definition: gfpcrypt.h:56
Multiple precision integer with arithmetic operations.
Definition: integer.h:45
NR
Definition: gfpcrypt.h:423
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
Definition: misc.h:970
virtual const Integer & GetSubgroupOrder() const =0
Retrieves the subgroup order.
const DL_GroupPrecomputation< Element > & GetGroupPrecomputation() const
Retrieves the group precomputation.
Definition: pubkey.h:984
const DL_FixedBasePrecomputation< Element > & GetBasePrecomputation() const
Retrieves the group precomputation.
Definition: gfpcrypt.h:120
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
Definition: gfpcrypt.cpp:179
byte order is big-endian
Definition: cryptlib.h:132
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:62
DSA group parameters, these are GF(p) group parameters that are allowed by the DSA standard...
Definition: gfpcrypt.h:435
Classes and functions for working with ANS.1 objects.
Classes for SHA-1 and SHA-2 family of message digests.
DER Sequence Encoder.
Definition: asn.h:304
provided for backwards compatibility, this class uses the old non-standard Crypto++ key format ...
Definition: gfpcrypt.h:365
virtual unsigned int GetEncodedElementSize(bool reversible) const =0
Retrieves the encoded element's size.
DL private key (in GF(p) groups)
Definition: gfpcrypt.h:275
GDSA algorithm.
Definition: gfpcrypt.h:185
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:28
bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
Check the group for errors.
Definition: gfpcrypt.cpp:129
Integer InverseMod(const Integer &n) const
calculate multiplicative inverse of *this mod n
Definition: integer.cpp:4198
void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
Generate a random key or crypto parameters.
Definition: cryptlib.cpp:768
NR algorithm.
Definition: gfpcrypt.h:221
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: gfpcrypt.h:116
Multiple precision integer with arithmetic operations.
void DEREncodePublicKey(BufferedTransformation &bt) const
encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
Definition: gfpcrypt.h:265
const char * KeyDerivationParameters()
ConstByteArrayParameter.
Definition: argnames.h:66
Crypto++ library namespace.
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition: pubkey.h:1355
Base implmentation of Discrete Log (DL) group parameters.
Definition: pubkey.h:971
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: pubkey.h:1175
void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t)
decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
Definition: gfpcrypt.h:263
Encode and decode ASN.1 objects with additional information.
Definition: asn.h:365
Object Identifier.
Definition: asn.h:158
Interface for retrieving values given their names.
Definition: cryptlib.h:282