Fabcoin Core  0.16.2
P2P Digital Currency
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 
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 
29 
31 
35 {
37 
38 public:
40 
44  {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());}
45 
52  void Initialize(RandomNumberGenerator &rng, unsigned int pbits)
53  {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));}
54 
58  void Initialize(const Integer &p, const Integer &g)
59  {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);}
60 
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
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 
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 
134  {AssignFromHelper<DL_GroupParameters_IntegerBased>(this, source);}
135 
136  // DL_GroupParameters
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 
159 {
160 public:
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 
184 {
185 public:
187 
189 
190 protected:
191  unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;}
192 };
193 
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 
235 template <class T, class H>
237 {
238 public:
239  CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-RFC6979";}
240 
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 
401 template <class T>
403 {
404 public:
405  CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "GDSA-ISO15946";}
406 
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 
439 
443 template <class T>
445 {
446 public:
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 
474 template <class GP>
476 {
477 public:
478  virtual ~DL_PublicKey_GFP() {}
479 
483  void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &y)
484  {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);}
485 
490  void Initialize(const Integer &p, const Integer &g, const Integer &y)
491  {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);}
492 
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 
511 template <class GP>
513 {
514 public:
515  virtual ~DL_PrivateKey_GFP() {}
516 
523  void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
524  {this->GenerateRandomWithKeySize(rng, modulusBits);}
525 
533  void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
534  {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));}
535 
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 
551  {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);}
552 
557  void Initialize(const Integer &p, const Integer &g, const Integer &x)
558  {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);}
559 
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 
572 {
576 };
577 
581 {
585 };
586 
592 template <class BASE>
593 class DL_PublicKey_GFP_OldFormat : public BASE
594 {
595 public:
597 
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 
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 
637 template <class BASE>
638 class DL_PrivateKey_GFP_OldFormat : public BASE
639 {
640 public:
642 
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 
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 
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 
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 
711 {
712 public:
714 
716  bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
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 
734 {
737 };
738 
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 
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 
774 typedef DSA2<SHA1> DSA;
775 
779 
794 template <class MAC, bool DHAES_MODE, bool LABEL_OCTETS=false>
796 {
797 public:
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 
877 template <class T, bool DHAES_MODE, class KDF>
879 {
880 public:
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 
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 
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
static std::string CRYPTOPP_API StaticAlgorithmName()
Definition: gfpcrypt.h:770
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.
uint8_t byte
Definition: Common.h:57
Utility functions for the Crypto++ library.
#define CRYPTOPP_STATIC_CONSTEXPR
Definition: config.h:892
DL_PrivateKey_GFP< GroupParameters > PrivateKey
Definition: gfpcrypt.h:584
void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g)
Definition: gfpcrypt.h:144
static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits)
Definition: gfpcrypt.h:721
size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const
Definition: gfpcrypt.h:805
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
DL_GroupParameters_GFP GroupParameters
Definition: gfpcrypt.h:573
DL_PublicKey_GFP< DL_GroupParameters_DSA > PublicKey
Definition: gfpcrypt.h:735
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
Interface for deterministic signers.
Definition: pubkey.h:1281
void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
Create a private key.
Definition: gfpcrypt.h:523
virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
Definition: pubkey.h:1017
#define T(i, x)
void MessageEnd()
Definition: asn.cpp:524
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULL)
Access a block of memory.
Definition: misc.h:2123
size_t GetSymmetricCiphertextLength(size_t plaintextLength) const
Definition: gfpcrypt.h:803
void Initialize(const Integer &p, const Integer &g)
Initialize a group parameters over integers.
Definition: gfpcrypt.h:58
#define NAMESPACE_BEGIN(x)
Definition: config.h:200
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:736
#define CRYPTOPP_DLL_TEMPLATE_CLASS
Definition: config.h:720
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
const Integer & GetModulus() const
Definition: gfpcrypt.h:141
SecByteBlock bits2octets(const SecByteBlock &in, const Integer &q) const
Definition: gfpcrypt.h:384
void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
Definition: gfpcrypt.h:807
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
bool IsDeterministic() const
Definition: gfpcrypt.h:245
SecByteBlock int2octets(const Integer &val, size_t rlen) const
Definition: gfpcrypt.h:357
virtual Integer ConvertElementToInteger(const Element &element) const =0
Converts an element to an Integer.
bool ParameterSupported(const char *name) const
Definition: gfpcrypt.h:800
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:524
#define g(i)
Definition: sha.cpp:735
void SetSubgroupOrder(const Integer &q)
Definition: gfpcrypt.h:100
Interface for key derivation algorithms used in DL cryptosystems.
Definition: pubkey.h:1304
Classes for automatic resource management.
void BERDecode(BufferedTransformation &bt)
Definition: gfpcrypt.h:643
size_t size() const
Length of the memory block.
Definition: algparam.h:93
void BERDecode(BufferedTransformation &bt)
Definition: gfpcrypt.h:598
Library configuration file.
DSA keys.
Definition: gfpcrypt.h:733
bool FastSubgroupCheckAvailable() const
Definition: gfpcrypt.h:83
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
virtual ~DL_EncryptionAlgorithm_Xor()
Definition: gfpcrypt.h:798
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
bool operator!=(const DL_GroupParameters_IntegerBasedImpl< GROUP_PRECOMP, BASE_PRECOMP > &rhs) const
Definition: gfpcrypt.h:150
virtual ~DL_PublicKey_GFP()
Definition: gfpcrypt.h:478
DL_PublicKey_GFP< GroupParameters > PublicKey
Definition: gfpcrypt.h:574
Discrete Log (DL) encryption scheme.
Definition: pubkey.h:2155
BER Sequence Decoder.
Definition: asn.h:303
Interface for buffered transformations.
Definition: cryptlib.h:1352
DSA signature scheme.
Definition: gfpcrypt.h:685
virtual ~DL_Algorithm_DSA_RFC6979()
Definition: gfpcrypt.h:241
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:89
static const Integer &CRYPTOPP_API One()
Integer representing 1.
Definition: integer.cpp:3035
bool Verify(const DL_GroupParameters< T > &params, const DL_PublicKey< T > &publicKey, const Integer &e, const Integer &r, const Integer &s) const
Definition: gfpcrypt.h:419
Interface for Discrete Log (DL) public keys.
Definition: pubkey.h:992
CRYPTOPP_STATIC_CONSTEXPR const char *CRYPTOPP_API StaticAlgorithmName()
Definition: gfpcrypt.h:447
virtual const Element & GetSubgroupGenerator() const
Retrieves the subgroup generator.
Definition: pubkey.h:793
bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs)
Definition: asn.h:558
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
DL_FixedBasePrecomputation< Element > & AccessBasePrecomputation()
Retrieves the group precomputation.
Definition: gfpcrypt.h:138
#define a(i)
Returns a decoding results.
Definition: cryptlib.h:238
bool ParameterSupported(const char *name) const
Definition: gfpcrypt.h:883
virtual ~DL_Algorithm_GDSA_ISO15946()
Definition: gfpcrypt.h:407
#define x(i)
DSA2< SHA1 > DSA
DSA with SHA-1, typedef&#39;d for backwards compatibility.
Definition: gfpcrypt.h:774
Classes for HMAC message authentication codes.
const char * source
Definition: rpcconsole.cpp:60
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:337
DSA signature scheme.
Definition: gfpcrypt.h:728
bool Verify(const DL_GroupParameters< T > &params, const DL_PublicKey< T > &publicKey, const Integer &e, const Integer &r, const Integer &s) const
Definition: gfpcrypt.h:214
Discrete Log (DL) public key in GF(p) groups.
Definition: gfpcrypt.h:593
int GetFieldType() const
Definition: gfpcrypt.h:178
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
DL_GroupParameters_IntegerBasedImpl< GROUP_PRECOMP, BASE_PRECOMP > ThisClass
Definition: gfpcrypt.h:122
const char * name
Definition: rest.cpp:36
Discrete Log (DL) signing/verification keys in GF(p) groups.
Definition: gfpcrypt.h:571
DL_GroupParameters_GFP_DefaultSafePrime GroupParameters
Definition: gfpcrypt.h:582
DSA deterministic signature scheme.
Definition: gfpcrypt.h:763
#define H(x, y, z)
Definition: Hash.cpp:81
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
void Sign(const DL_GroupParameters< T > &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
Definition: gfpcrypt.h:205
Multiple precision integer with arithmetic operations.
Definition: integer.h:43
NR signature scheme.
Definition: gfpcrypt.h:698
CRYPTOPP_STATIC_CONSTEXPR const char *CRYPTOPP_API StaticAlgorithmName()
Definition: gfpcrypt.h:201
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
#define CRYPTOPP_API
Definition: config.h:705
size_t GetSymmetricKeyLength(size_t plaintextLength) const
Definition: gfpcrypt.h:801
GROUP_PRECOMP::Element Element
Definition: gfpcrypt.h:125
void Sign(const DL_GroupParameters< T > &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
Definition: gfpcrypt.h:451
unsigned long long word64
Definition: config.h:240
virtual ~DL_KeyDerivationAlgorithm_P1363()
Definition: gfpcrypt.h:881
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
#define b(i, j)
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:477
#define CRYPTOPP_ASSERT(exp)
Definition: trap.h:92
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:28
static std::string CRYPTOPP_API StaticAlgorithmName()
Definition: gfpcrypt.h:754
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
#define CRYPTOPP_NO_VTABLE
Definition: config.h:369
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
virtual ~DL_GroupParameters_IntegerBased()
Definition: gfpcrypt.h:39
void MessageEnd()
Definition: asn.cpp:456
bool Verify(const DL_GroupParameters< T > &params, const DL_PublicKey< T > &publicKey, const Integer &e, const Integer &r, const Integer &s) const
Definition: gfpcrypt.h:459
Integer ComputeGroupOrder(const Integer &modulus) const
Definition: gfpcrypt.h:104
DSA signature algorithm based on RFC 6979.
Definition: gfpcrypt.h:236
DER Sequence Encoder.
Definition: asn.h:313
virtual ~DL_PrivateKey_GFP_OldFormat()
Definition: gfpcrypt.h:641
void DEREncode(BufferedTransformation &bt) const
Definition: gfpcrypt.h:620
uint8_t const size_t const size
Definition: sha3.h:20
Discrete Log (DL) private key in GF(p) groups.
Definition: gfpcrypt.h:638
void * memcpy(void *a, const void *b, size_t c)
Discrete Log (DL) private key in GF(p) groups.
Definition: gfpcrypt.h:512
#define CRYPTOPP_UNUSED(x)
Definition: config.h:741
static std::string CRYPTOPP_API StaticAlgorithmName()
Definition: gfpcrypt.h:948
GDSA algorithm.
Definition: gfpcrypt.h:198
void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &x)
Initialize a private key over GF(p)
Definition: gfpcrypt.h:550
void DEREncode(BufferedTransformation &bt) const
Definition: gfpcrypt.h:666
Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const
Definition: gfpcrypt.h:249
virtual ~DL_GroupParameters_DSA()
Definition: gfpcrypt.h:713
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
bool EndReached() const
Definition: asn.cpp:430
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
virtual ~DL_Algorithm_GDSA()
Definition: gfpcrypt.h:203
void Derive(const DL_GroupParameters< T > &params, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &parameters) const
Definition: gfpcrypt.h:884
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
virtual ~DL_PublicKey_GFP_OldFormat()
Definition: gfpcrypt.h:596
void Sign(const DL_GroupParameters< T > &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
Definition: gfpcrypt.h:409
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
Definition: misc.h:487
#define NAMESPACE_END
Definition: config.h:201
virtual ~DL_GroupParameters_GFP()
Definition: gfpcrypt.h:161
std::vector< char * > parameters
Definition: boostTest.cpp:46
#define e(i)
Definition: sha.cpp:733
CRYPTOPP_STATIC_CONSTEXPR const char *CRYPTOPP_API StaticAlgorithmName()
Definition: gfpcrypt.h:405
const Integer & GetGenerator() const
Definition: gfpcrypt.h:142
DL_PublicKey_GFP< GroupParameters > PublicKey
Definition: gfpcrypt.h:583
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
DL_PrivateKey_WithSignaturePairwiseConsistencyTest< DL_PrivateKey_GFP< DL_GroupParameters_DSA >, DSA2< SHA > > PrivateKey
Definition: gfpcrypt.h:736
#define CRYPTOPP_DLL
Definition: config.h:704
void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t)
decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
Definition: gfpcrypt.h:502
virtual const Integer & GetModulus() const =0
DL_PrivateKey_GFP< GroupParameters > PrivateKey
Definition: gfpcrypt.h:575
unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const
Definition: gfpcrypt.h:191
DL_GroupParameters_IntegerBased ThisClass
Definition: gfpcrypt.h:36
static std::string CRYPTOPP_API StaticAlgorithmNamePrefix()
Definition: gfpcrypt.h:93
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
CRYPTOPP_STATIC_CONSTEXPR const char *CRYPTOPP_API StaticAlgorithmName()
Definition: gfpcrypt.h:239
bool IsProbabilistic() const
Definition: gfpcrypt.h:243
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
DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
Definition: gfpcrypt.h:839
NoCofactorMultiplication DefaultCofactorOption
Definition: gfpcrypt.h:186
Integer bits2int(const SecByteBlock &bits, size_t qlen) const
Definition: gfpcrypt.h:344
bool operator==(const DL_GroupParameters_IntegerBasedImpl< GROUP_PRECOMP, BASE_PRECOMP > &rhs) const
Definition: gfpcrypt.h:148
virtual ~DL_GroupParameters_IntegerBasedImpl()
Definition: gfpcrypt.h:127
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
virtual ~DL_PrivateKey_GFP()
Definition: gfpcrypt.h:515
Interface for retrieving values given their names.
Definition: cryptlib.h:279
virtual ~DL_Algorithm_NR()
Definition: gfpcrypt.h:449
BASE_PRECOMP m_gpc
Definition: pubkey.h:970
virtual const Integer & GetSubgroupOrder() const =0
Retrieves the subgroup order.