Crypto++
pubkey.h
Go to the documentation of this file.
1 // pubkey.h - written and placed in the public domain by Wei Dai
2 
3 #ifndef CRYPTOPP_PUBKEY_H
4 #define CRYPTOPP_PUBKEY_H
5 
6 /** \file
7 
8  This file contains helper classes/functions for implementing public key algorithms.
9 
10  The class hierachies in this .h file tend to look like this:
11 <pre>
12  x1
13  / \
14  y1 z1
15  | |
16  x2<y1> x2<z1>
17  | |
18  y2 z2
19  | |
20  x3<y2> x3<z2>
21  | |
22  y3 z3
23 </pre>
24  - x1, y1, z1 are abstract interface classes defined in cryptlib.h
25  - x2, y2, z2 are implementations of the interfaces using "abstract policies", which
26  are pure virtual functions that should return interfaces to interchangeable algorithms.
27  These classes have "Base" suffixes.
28  - x3, y3, z3 hold actual algorithms and implement those virtual functions.
29  These classes have "Impl" suffixes.
30 
31  The "TF_" prefix means an implementation using trapdoor functions on integers.
32  The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard).
33 */
34 
35 #include "modarith.h"
36 #include "filters.h"
37 #include "eprecomp.h"
38 #include "fips140.h"
39 #include "argnames.h"
40 #include <memory>
41 
42 // VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file
43 #undef INTERFACE
44 
45 NAMESPACE_BEGIN(CryptoPP)
46 
47 //! _
48 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
49 {
50 public:
51  virtual ~TrapdoorFunctionBounds() {}
52 
53  virtual Integer PreimageBound() const =0;
54  virtual Integer ImageBound() const =0;
55  virtual Integer MaxPreimage() const {return --PreimageBound();}
56  virtual Integer MaxImage() const {return --ImageBound();}
57 };
58 
59 //! _
60 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
61 {
62 public:
63  virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
64  virtual bool IsRandomized() const {return true;}
65 };
66 
67 //! _
68 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
69 {
70 public:
71  Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
72  {return ApplyFunction(x);}
73  bool IsRandomized() const {return false;}
74 
75  virtual Integer ApplyFunction(const Integer &x) const =0;
76 };
77 
78 //! _
79 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
80 {
81 public:
83 
84  virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
85  virtual bool IsRandomized() const {return true;}
86 };
87 
88 //! _
89 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
90 {
91 public:
92  virtual ~TrapdoorFunctionInverse() {}
93 
94  Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
95  {return CalculateInverse(rng, x);}
96  bool IsRandomized() const {return false;}
97 
98  virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
99 };
100 
101 // ********************************************************
102 
103 //! message encoding method for public key encryption
104 class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
105 {
106 public:
108 
109  virtual bool ParameterSupported(const char *name) const {return false;}
110 
111  //! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
112  virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0;
113 
114  virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs &parameters) const =0;
115 
116  virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs &parameters) const =0;
117 };
118 
119 // ********************************************************
120 
121 //! _
122 template <class TFI, class MEI>
123 class CRYPTOPP_NO_VTABLE TF_Base
124 {
125 protected:
126  virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
127 
128  typedef TFI TrapdoorFunctionInterface;
129  virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
130 
131  typedef MEI MessageEncodingInterface;
132  virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
133 };
134 
135 // ********************************************************
136 
137 //! _
138 template <class BASE>
139 class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
140 {
141 public:
142  size_t MaxPlaintextLength(size_t ciphertextLength) const
143  {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
144  size_t CiphertextLength(size_t plaintextLength) const
145  {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
146 
147  virtual size_t FixedMaxPlaintextLength() const =0;
148  virtual size_t FixedCiphertextLength() const =0;
149 };
150 
151 //! _
152 template <class INTERFACE, class BASE>
153 class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE
154 {
155 public:
156  bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);}
157  size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
158  size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
159 
160 protected:
161  size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
162  size_t PaddedBlockBitLength() const {return this->GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;}
163 };
164 
165 //! _
166 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
167 {
168 public:
169  DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
170 };
171 
172 //! _
173 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
174 {
175 public:
176  void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
177 };
178 
179 // ********************************************************
180 
181 typedef std::pair<const byte *, size_t> HashIdentifier;
182 
183 //! interface for message encoding method for public key signature schemes
184 class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
185 {
186 public:
188 
189  virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const
190  {return 0;}
191  virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const
192  {return 0;}
193 
194  bool IsProbabilistic() const
195  {return true;}
196  bool AllowNonrecoverablePart() const
197  {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
198  virtual bool RecoverablePartFirst() const
199  {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
200 
201  // for verification, DL
202  virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const {}
203 
204  // for signature
205  virtual void ProcessRecoverableMessage(HashTransformation &hash,
206  const byte *recoverableMessage, size_t recoverableMessageLength,
207  const byte *presignature, size_t presignatureLength,
208  SecByteBlock &semisignature) const
209  {
210  if (RecoverablePartFirst())
211  assert(!"ProcessRecoverableMessage() not implemented");
212  }
213 
214  virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng,
215  const byte *recoverableMessage, size_t recoverableMessageLength,
216  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
217  byte *representative, size_t representativeBitLength) const =0;
218 
219  virtual bool VerifyMessageRepresentative(
220  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
221  byte *representative, size_t representativeBitLength) const =0;
222 
223  virtual DecodingResult RecoverMessageFromRepresentative( // for TF
224  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
225  byte *representative, size_t representativeBitLength,
226  byte *recoveredMessage) const
227  {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
228 
229  virtual DecodingResult RecoverMessageFromSemisignature( // for DL
230  HashTransformation &hash, HashIdentifier hashIdentifier,
231  const byte *presignature, size_t presignatureLength,
232  const byte *semisignature, size_t semisignatureLength,
233  byte *recoveredMessage) const
234  {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
235 
236  // VC60 workaround
238  {
239  template <class H> struct HashIdentifierLookup2
240  {
241  static HashIdentifier CRYPTOPP_API Lookup()
242  {
243  return HashIdentifier((const byte *)NULL, 0);
244  }
245  };
246  };
247 };
248 
250 {
251 public:
252  bool VerifyMessageRepresentative(
253  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
254  byte *representative, size_t representativeBitLength) const;
255 };
256 
258 {
259 public:
260  bool VerifyMessageRepresentative(
261  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
262  byte *representative, size_t representativeBitLength) const;
263 };
264 
266 {
267 public:
268  void ComputeMessageRepresentative(RandomNumberGenerator &rng,
269  const byte *recoverableMessage, size_t recoverableMessageLength,
270  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
271  byte *representative, size_t representativeBitLength) const;
272 };
273 
275 {
276 public:
277  void ComputeMessageRepresentative(RandomNumberGenerator &rng,
278  const byte *recoverableMessage, size_t recoverableMessageLength,
279  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
280  byte *representative, size_t representativeBitLength) const;
281 };
282 
283 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
284 {
285 public:
286  PK_MessageAccumulatorBase() : m_empty(true) {}
287 
288  virtual HashTransformation & AccessHash() =0;
289 
290  void Update(const byte *input, size_t length)
291  {
292  AccessHash().Update(input, length);
293  m_empty = m_empty && length == 0;
294  }
295 
296  SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
297  Integer m_k, m_s;
298  bool m_empty;
299 };
300 
301 template <class HASH_ALGORITHM>
302 class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
303 {
304 public:
305  HashTransformation & AccessHash() {return this->m_object;}
306 };
307 
308 //! _
309 template <class INTERFACE, class BASE>
310 class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTERFACE, protected BASE
311 {
312 public:
313  size_t SignatureLength() const
314  {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
315  size_t MaxRecoverableLength() const
316  {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
317  size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
318  {return this->MaxRecoverableLength();}
319 
320  bool IsProbabilistic() const
321  {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
322  bool AllowNonrecoverablePart() const
323  {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
324  bool RecoverablePartFirst() const
325  {return this->GetMessageEncodingInterface().RecoverablePartFirst();}
326 
327 protected:
328  size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
329  size_t MessageRepresentativeBitLength() const {return this->GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;}
330  virtual HashIdentifier GetHashIdentifier() const =0;
331  virtual size_t GetDigestSize() const =0;
332 };
333 
334 //! _
335 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
336 {
337 public:
338  void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const;
339  size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
340 };
341 
342 //! _
343 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
344 {
345 public:
346  void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const;
347  bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
348  DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
349 };
350 
351 // ********************************************************
352 
353 //! _
354 template <class T1, class T2, class T3>
356 {
357  typedef T1 AlgorithmInfo;
358  typedef T2 Keys;
359  typedef typename Keys::PrivateKey PrivateKey;
360  typedef typename Keys::PublicKey PublicKey;
361  typedef T3 MessageEncodingMethod;
362 };
363 
364 //! _
365 template <class T1, class T2, class T3, class T4>
367 {
368  typedef T4 HashFunction;
369 };
370 
371 //! _
372 template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
373 class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
374 {
375 public:
376  typedef SCHEME_OPTIONS SchemeOptions;
377  typedef KEY_CLASS KeyClass;
378 
379  PublicKey & AccessPublicKey() {return AccessKey();}
380  const PublicKey & GetPublicKey() const {return GetKey();}
381 
382  PrivateKey & AccessPrivateKey() {return AccessKey();}
383  const PrivateKey & GetPrivateKey() const {return GetKey();}
384 
385  virtual const KeyClass & GetKey() const =0;
386  virtual KeyClass & AccessKey() =0;
387 
388  const KeyClass & GetTrapdoorFunction() const {return GetKey();}
389 
390  PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
391  {
393  }
394  PK_MessageAccumulator * NewVerificationAccumulator() const
395  {
397  }
398 
399 protected:
400  const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const
402  const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const
403  {return GetKey();}
404  const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const
405  {return GetKey();}
406 
407  // for signature scheme
408  HashIdentifier GetHashIdentifier() const
409  {
410  typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L;
411  return L::Lookup();
412  }
413  size_t GetDigestSize() const
414  {
415  typedef CPP_TYPENAME SchemeOptions::HashFunction H;
416  return H::DIGESTSIZE;
417  }
418 };
419 
420 //! _
421 template <class BASE, class SCHEME_OPTIONS, class KEY>
422 class TF_ObjectImplExtRef : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
423 {
424 public:
425  TF_ObjectImplExtRef(const KEY *pKey = NULL) : m_pKey(pKey) {}
426  void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;}
427 
428  const KEY & GetKey() const {return *m_pKey;}
429  KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");}
430 
431 private:
432  const KEY * m_pKey;
433 };
434 
435 //! _
436 template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
437 class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS>
438 {
439 public:
440  typedef KEY_CLASS KeyClass;
441 
442  const KeyClass & GetKey() const {return m_trapdoorFunction;}
443  KeyClass & AccessKey() {return m_trapdoorFunction;}
444 
445 private:
446  KeyClass m_trapdoorFunction;
447 };
448 
449 //! _
450 template <class SCHEME_OPTIONS>
451 class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
452 {
453 };
454 
455 //! _
456 template <class SCHEME_OPTIONS>
457 class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
458 {
459 };
460 
461 //! _
462 template <class SCHEME_OPTIONS>
463 class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
464 {
465 };
466 
467 //! _
468 template <class SCHEME_OPTIONS>
469 class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
470 {
471 };
472 
473 // ********************************************************
474 
475 //! _
476 class CRYPTOPP_NO_VTABLE MaskGeneratingFunction
477 {
478 public:
479  virtual ~MaskGeneratingFunction() {}
480  virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0;
481 };
482 
483 CRYPTOPP_DLL void CRYPTOPP_API P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart);
484 
485 //! _
487 {
488 public:
489  static const char * CRYPTOPP_API StaticAlgorithmName() {return "MGF1";}
490  void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const
491  {
492  P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0);
493  }
494 };
495 
496 // ********************************************************
497 
498 //! _
499 template <class H>
501 {
502 public:
503  static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength)
504  {
505  H h;
506  P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
507  }
508 };
509 
510 // ********************************************************
511 
512 //! to be thrown by DecodeElement and AgreeWithStaticPrivateKey
514 {
515 public:
516  DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {}
517 };
518 
519 //! interface for DL group parameters
520 template <class T>
521 class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters
522 {
524 
525 public:
526  typedef T Element;
527 
528  DL_GroupParameters() : m_validationLevel(0) {}
529 
530  // CryptoMaterial
531  bool Validate(RandomNumberGenerator &rng, unsigned int level) const
532  {
533  if (!GetBasePrecomputation().IsInitialized())
534  return false;
535 
536  if (m_validationLevel > level)
537  return true;
538 
539  bool pass = ValidateGroup(rng, level);
540  pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
541 
542  m_validationLevel = pass ? level+1 : 0;
543 
544  return pass;
545  }
546 
547  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
548  {
549  return GetValueHelper(this, name, valueType, pValue)
550  CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
551  CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
552  ;
553  }
554 
555  bool SupportsPrecomputation() const {return true;}
556 
557  void Precompute(unsigned int precomputationStorage=16)
558  {
559  AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
560  }
561 
562  void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
563  {
564  AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
565  m_validationLevel = 0;
566  }
567 
568  void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
569  {
570  GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
571  }
572 
573  // non-inherited
574  virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
575  virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
576  virtual Element ExponentiateBase(const Integer &exponent) const
577  {
578  return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
579  }
580  virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
581  {
582  Element result;
583  SimultaneousExponentiate(&result, base, &exponent, 1);
584  return result;
585  }
586 
587  virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0;
588  virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0;
589  virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0;
590  virtual const Integer & GetSubgroupOrder() const =0; // order of subgroup generated by base element
591  virtual Integer GetMaxExponent() const =0;
592  virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();} // one of these two needs to be overriden
593  virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();}
594  virtual unsigned int GetEncodedElementSize(bool reversible) const =0;
595  virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0;
596  virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0;
597  virtual Integer ConvertElementToInteger(const Element &element) const =0;
598  virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0;
599  virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0;
600  virtual bool FastSubgroupCheckAvailable() const =0;
601  virtual bool IsIdentity(const Element &element) const =0;
602  virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0;
603 
604 protected:
605  void ParametersChanged() {m_validationLevel = 0;}
606 
607 private:
608  mutable unsigned int m_validationLevel;
609 };
610 
611 //! _
612 template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<CPP_TYPENAME GROUP_PRECOMP::Element> >
613 class DL_GroupParametersImpl : public BASE
614 {
615 public:
616  typedef GROUP_PRECOMP GroupPrecomputation;
617  typedef typename GROUP_PRECOMP::Element Element;
618  typedef BASE_PRECOMP BasePrecomputation;
619 
620  const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;}
621  const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return m_gpc;}
622  DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return m_gpc;}
623 
624 protected:
625  GROUP_PRECOMP m_groupPrecomputation;
626  BASE_PRECOMP m_gpc;
627 };
628 
629 //! _
630 template <class T>
631 class CRYPTOPP_NO_VTABLE DL_Key
632 {
633 public:
634  virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0;
635  virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0;
636 };
637 
638 //! interface for DL public keys
639 template <class T>
640 class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T>
641 {
642  typedef DL_PublicKey<T> ThisClass;
643 
644 public:
645  typedef T Element;
646 
647  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
648  {
649  return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
650  CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
651  }
652 
653  void AssignFrom(const NameValuePairs &source);
654 
655  // non-inherited
656  virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
657  virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
658  virtual Element ExponentiatePublicElement(const Integer &exponent) const
659  {
660  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
661  return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
662  }
663  virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
664  {
665  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
666  return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
667  }
668 
669  virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation() const =0;
670  virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0;
671 };
672 
673 //! interface for DL private keys
674 template <class T>
675 class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T>
676 {
677  typedef DL_PrivateKey<T> ThisClass;
678 
679 public:
680  typedef T Element;
681 
682  void MakePublicKey(DL_PublicKey<T> &pub) const
683  {
684  pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters());
685  pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
686  }
687 
688  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
689  {
690  return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
691  CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
692  }
693 
694  void AssignFrom(const NameValuePairs &source)
695  {
696  this->AccessAbstractGroupParameters().AssignFrom(source);
697  AssignFromHelper(this, source)
698  CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
699  }
700 
701  virtual const Integer & GetPrivateExponent() const =0;
702  virtual void SetPrivateExponent(const Integer &x) =0;
703 };
704 
705 template <class T>
707 {
708  DL_PrivateKey<T> *pPrivateKey = NULL;
709  if (source.GetThisPointer(pPrivateKey))
710  pPrivateKey->MakePublicKey(*this);
711  else
712  {
713  this->AccessAbstractGroupParameters().AssignFrom(source);
714  AssignFromHelper(this, source)
715  CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
716  }
717 }
718 
719 class OID;
720 
721 //! _
722 template <class PK, class GP, class O = OID>
723 class DL_KeyImpl : public PK
724 {
725 public:
726  typedef GP GroupParameters;
727 
728  O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();}
729 // void BERDecode(BufferedTransformation &bt)
730 // {PK::BERDecode(bt);}
731 // void DEREncode(BufferedTransformation &bt) const
732 // {PK::DEREncode(bt);}
733  bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
734  {AccessGroupParameters().BERDecode(bt); return true;}
735  bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
736  {GetGroupParameters().DEREncode(bt); return true;}
737 
738  const GP & GetGroupParameters() const {return m_groupParameters;}
739  GP & AccessGroupParameters() {return m_groupParameters;}
740 
741 private:
742  GP m_groupParameters;
743 };
744 
745 class X509PublicKey;
746 class PKCS8PrivateKey;
747 
748 //! _
749 template <class GP>
750 class DL_PrivateKeyImpl : public DL_PrivateKey<CPP_TYPENAME GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP>
751 {
752 public:
753  typedef typename GP::Element Element;
754 
755  // GeneratableCryptoMaterial
756  bool Validate(RandomNumberGenerator &rng, unsigned int level) const
757  {
758  bool pass = GetAbstractGroupParameters().Validate(rng, level);
759 
760  const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
761  const Integer &x = GetPrivateExponent();
762 
763  pass = pass && x.IsPositive() && x < q;
764  if (level >= 1)
765  pass = pass && Integer::Gcd(x, q) == Integer::One();
766  return pass;
767  }
768 
769  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
770  {
771  return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable();
772  }
773 
774  void AssignFrom(const NameValuePairs &source)
775  {
776  AssignFromHelper<DL_PrivateKey<Element> >(this, source);
777  }
778 
780  {
781  if (!params.GetThisObject(this->AccessGroupParameters()))
782  this->AccessGroupParameters().GenerateRandom(rng, params);
783 // std::pair<const byte *, int> seed;
784  Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
785 // Integer::ANY, Integer::Zero(), Integer::One(),
786 // params.GetValue("DeterministicKeyGenerationSeed", seed) ? &seed : NULL);
787  SetPrivateExponent(x);
788  }
789 
790  bool SupportsPrecomputation() const {return true;}
791 
792  void Precompute(unsigned int precomputationStorage=16)
793  {AccessAbstractGroupParameters().Precompute(precomputationStorage);}
794 
795  void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
796  {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
797 
798  void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
799  {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
800 
801  // DL_Key
802  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
803  DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
804 
805  // DL_PrivateKey
806  const Integer & GetPrivateExponent() const {return m_x;}
807  void SetPrivateExponent(const Integer &x) {m_x = x;}
808 
809  // PKCS8PrivateKey
811  {m_x.BERDecode(bt);}
813  {m_x.DEREncode(bt);}
814 
815 private:
816  Integer m_x;
817 };
818 
819 //! _
820 template <class BASE, class SIGNATURE_SCHEME>
822 {
823 public:
824  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
825  {
826  BASE::GenerateRandom(rng, params);
827 
829  {
830  typename SIGNATURE_SCHEME::Signer signer(*this);
831  typename SIGNATURE_SCHEME::Verifier verifier(signer);
832  SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
833  }
834  }
835 };
836 
837 //! _
838 template <class GP>
839 class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP>
840 {
841 public:
842  typedef typename GP::Element Element;
843 
844  // CryptoMaterial
845  bool Validate(RandomNumberGenerator &rng, unsigned int level) const
846  {
847  bool pass = GetAbstractGroupParameters().Validate(rng, level);
848  pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
849  return pass;
850  }
851 
852  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
853  {
854  return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable();
855  }
856 
857  void AssignFrom(const NameValuePairs &source)
858  {
859  AssignFromHelper<DL_PublicKey<Element> >(this, source);
860  }
861 
862  bool SupportsPrecomputation() const {return true;}
863 
864  void Precompute(unsigned int precomputationStorage=16)
865  {
866  AccessAbstractGroupParameters().Precompute(precomputationStorage);
867  AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
868  }
869 
870  void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
871  {
872  AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
873  AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
874  }
875 
876  void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
877  {
878  GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
879  GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
880  }
881 
882  // DL_Key
883  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
884  DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
885 
886  // DL_PublicKey
887  const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;}
888  DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;}
889 
890  // non-inherited
891  bool operator==(const DL_PublicKeyImpl<GP> &rhs) const
892  {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
893 
894 private:
895  typename GP::BasePrecomputation m_ypc;
896 };
897 
898 //! interface for Elgamal-like signature algorithms
899 template <class T>
900 class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm
901 {
902 public:
903  virtual void Sign(const DL_GroupParameters<T> &params, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
904  virtual bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
905  virtual Integer RecoverPresignature(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
906  {throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");}
907  virtual size_t RLen(const DL_GroupParameters<T> &params) const
908  {return params.GetSubgroupOrder().ByteCount();}
909  virtual size_t SLen(const DL_GroupParameters<T> &params) const
910  {return params.GetSubgroupOrder().ByteCount();}
911 };
912 
913 //! interface for DL key agreement algorithms
914 template <class T>
915 class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm
916 {
917 public:
918  typedef T Element;
919 
920  virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0;
921  virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0;
922 };
923 
924 //! interface for key derivation algorithms used in DL cryptosystems
925 template <class T>
926 class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
927 {
928 public:
929  virtual bool ParameterSupported(const char *name) const {return false;}
930  virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0;
931 };
932 
933 //! interface for symmetric encryption algorithms used in DL cryptosystems
934 class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
935 {
936 public:
937  virtual bool ParameterSupported(const char *name) const {return false;}
938  virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0;
939  virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0;
940  virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0;
941  virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const =0;
942  virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const =0;
943 };
944 
945 //! _
946 template <class KI>
947 class CRYPTOPP_NO_VTABLE DL_Base
948 {
949 protected:
950  typedef KI KeyInterface;
951  typedef typename KI::Element Element;
952 
953  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();}
954  DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();}
955 
956  virtual KeyInterface & AccessKeyInterface() =0;
957  virtual const KeyInterface & GetKeyInterface() const =0;
958 };
959 
960 //! _
961 template <class INTERFACE, class KEY_INTERFACE>
962 class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTERFACE, public DL_Base<KEY_INTERFACE>
963 {
964 public:
965  size_t SignatureLength() const
966  {
967  return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
968  + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
969  }
970  size_t MaxRecoverableLength() const
971  {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
972  size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
973  {assert(false); return 0;} // TODO
974 
975  bool IsProbabilistic() const
976  {return true;}
977  bool AllowNonrecoverablePart() const
978  {return GetMessageEncodingInterface().AllowNonrecoverablePart();}
979  bool RecoverablePartFirst() const
980  {return GetMessageEncodingInterface().RecoverablePartFirst();}
981 
982 protected:
983  size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
984  size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
985 
986  virtual const DL_ElgamalLikeSignatureAlgorithm<CPP_TYPENAME KEY_INTERFACE::Element> & GetSignatureAlgorithm() const =0;
987  virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
988  virtual HashIdentifier GetHashIdentifier() const =0;
989  virtual size_t GetDigestSize() const =0;
990 };
991 
992 //! _
993 template <class T>
994 class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
995 {
996 public:
997  // for validation testing
998  void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
999  {
1000  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1001  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1002  const DL_PrivateKey<T> &key = this->GetKeyInterface();
1003 
1004  r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1005  alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1006  }
1007 
1008  void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
1009  {
1010  PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1011  ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
1012  this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
1013  recoverableMessage, recoverableMessageLength,
1014  ma.m_presignature, ma.m_presignature.size(),
1015  ma.m_semisignature);
1016  }
1017 
1018  size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
1019  {
1020  this->GetMaterial().DoQuickSanityCheck();
1021 
1022  PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1023  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1024  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1025  const DL_PrivateKey<T> &key = this->GetKeyInterface();
1026 
1027  SecByteBlock representative(this->MessageRepresentativeLength());
1028  this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1029  rng,
1030  ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1031  ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1032  representative, this->MessageRepresentativeBitLength());
1033  ma.m_empty = true;
1034  Integer e(representative, representative.size());
1035 
1036  // hash message digest into random number k to prevent reusing the same k on a different messages
1037  // after virtual machine rollback
1038  if (rng.CanIncorporateEntropy())
1039  rng.IncorporateEntropy(representative, representative.size());
1040  Integer k(rng, 1, params.GetSubgroupOrder()-1);
1041  Integer r, s;
1042  r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1043  alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1044 
1045  /*
1046  Integer r, s;
1047  if (this->MaxRecoverableLength() > 0)
1048  r.Decode(ma.m_semisignature, ma.m_semisignature.size());
1049  else
1050  r.Decode(ma.m_presignature, ma.m_presignature.size());
1051  alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s);
1052  */
1053 
1054  size_t rLen = alg.RLen(params);
1055  r.Encode(signature, rLen);
1056  s.Encode(signature+rLen, alg.SLen(params));
1057 
1058  if (restart)
1059  RestartMessageAccumulator(rng, ma);
1060 
1061  return this->SignatureLength();
1062  }
1063 
1064 protected:
1065  void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
1066  {
1067  // k needs to be generated before hashing for signature schemes with recovery
1068  // but to defend against VM rollbacks we need to generate k after hashing.
1069  // so this code is commented out, since no DL-based signature scheme with recovery
1070  // has been implemented in Crypto++ anyway
1071  /*
1072  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1073  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1074  ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
1075  ma.m_presignature.New(params.GetEncodedElementSize(false));
1076  params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size());
1077  */
1078  }
1079 };
1080 
1081 //! _
1082 template <class T>
1083 class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
1084 {
1085 public:
1086  void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
1087  {
1088  PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1089  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1090  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1091 
1092  size_t rLen = alg.RLen(params);
1093  ma.m_semisignature.Assign(signature, rLen);
1094  ma.m_s.Decode(signature+rLen, alg.SLen(params));
1095 
1096  this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
1097  }
1098 
1099  bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
1100  {
1101  this->GetMaterial().DoQuickSanityCheck();
1102 
1103  PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1104  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1105  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1106  const DL_PublicKey<T> &key = this->GetKeyInterface();
1107 
1108  SecByteBlock representative(this->MessageRepresentativeLength());
1109  this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1110  ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1111  representative, this->MessageRepresentativeBitLength());
1112  ma.m_empty = true;
1113  Integer e(representative, representative.size());
1114 
1115  Integer r(ma.m_semisignature, ma.m_semisignature.size());
1116  return alg.Verify(params, key, e, r, ma.m_s);
1117  }
1118 
1119  DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
1120  {
1121  this->GetMaterial().DoQuickSanityCheck();
1122 
1123  PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1124  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1125  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1126  const DL_PublicKey<T> &key = this->GetKeyInterface();
1127 
1128  SecByteBlock representative(this->MessageRepresentativeLength());
1129  this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1130  NullRNG(),
1131  ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1132  ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1133  representative, this->MessageRepresentativeBitLength());
1134  ma.m_empty = true;
1135  Integer e(representative, representative.size());
1136 
1137  ma.m_presignature.New(params.GetEncodedElementSize(false));
1138  Integer r(ma.m_semisignature, ma.m_semisignature.size());
1139  alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
1140 
1141  return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
1142  ma.AccessHash(), this->GetHashIdentifier(),
1143  ma.m_presignature, ma.m_presignature.size(),
1144  ma.m_semisignature, ma.m_semisignature.size(),
1145  recoveredMessage);
1146  }
1147 };
1148 
1149 //! _
1150 template <class PK, class KI>
1151 class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
1152 {
1153 public:
1154  typedef typename DL_Base<KI>::Element Element;
1155 
1156  size_t MaxPlaintextLength(size_t ciphertextLength) const
1157  {
1158  unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
1159  return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
1160  }
1161 
1162  size_t CiphertextLength(size_t plaintextLength) const
1163  {
1164  size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
1165  return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
1166  }
1167 
1168  bool ParameterSupported(const char *name) const
1169  {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
1170 
1171 protected:
1172  virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
1173  virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
1174  virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
1175 };
1176 
1177 //! _
1178 template <class T>
1179 class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
1180 {
1181 public:
1182  typedef T Element;
1183 
1184  DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
1185  {
1186  try
1187  {
1188  const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
1189  const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
1190  const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
1191  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1192  const DL_PrivateKey<T> &key = this->GetKeyInterface();
1193 
1194  Element q = params.DecodeElement(ciphertext, true);
1195  size_t elementSize = params.GetEncodedElementSize(true);
1196  ciphertext += elementSize;
1197  ciphertextLength -= elementSize;
1198 
1199  Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
1200 
1201  SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
1202  derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1203 
1204  return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
1205  }
1206  catch (DL_BadElement &)
1207  {
1208  return DecodingResult();
1209  }
1210  }
1211 };
1212 
1213 //! _
1214 template <class T>
1215 class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
1216 {
1217 public:
1218  typedef T Element;
1219 
1220  void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const
1221  {
1222  const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
1223  const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
1224  const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
1225  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1226  const DL_PublicKey<T> &key = this->GetKeyInterface();
1227 
1228  Integer x(rng, Integer::One(), params.GetMaxExponent());
1229  Element q = params.ExponentiateBase(x);
1230  params.EncodeElement(true, q, ciphertext);
1231  unsigned int elementSize = params.GetEncodedElementSize(true);
1232  ciphertext += elementSize;
1233 
1234  Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
1235 
1236  SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
1237  derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1238 
1239  encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
1240  }
1241 };
1242 
1243 //! _
1244 template <class T1, class T2>
1246 {
1247  typedef T1 AlgorithmInfo;
1248  typedef T2 GroupParameters;
1249  typedef typename GroupParameters::Element Element;
1250 };
1251 
1252 //! _
1253 template <class T1, class T2>
1254 struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
1255 {
1256  typedef T2 Keys;
1257  typedef typename Keys::PrivateKey PrivateKey;
1258  typedef typename Keys::PublicKey PublicKey;
1259 };
1260 
1261 //! _
1262 template <class T1, class T2, class T3, class T4, class T5>
1264 {
1265  typedef T3 SignatureAlgorithm;
1266  typedef T4 MessageEncodingMethod;
1267  typedef T5 HashFunction;
1268 };
1269 
1270 //! _
1271 template <class T1, class T2, class T3, class T4, class T5>
1273 {
1274  typedef T3 KeyAgreementAlgorithm;
1275  typedef T4 KeyDerivationAlgorithm;
1276  typedef T5 SymmetricEncryptionAlgorithm;
1277 };
1278 
1279 //! _
1280 template <class BASE, class SCHEME_OPTIONS, class KEY>
1281 class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
1282 {
1283 public:
1284  typedef SCHEME_OPTIONS SchemeOptions;
1285  typedef typename KEY::Element Element;
1286 
1287  PrivateKey & AccessPrivateKey() {return m_key;}
1288  PublicKey & AccessPublicKey() {return m_key;}
1289 
1290  // KeyAccessor
1291  const KEY & GetKey() const {return m_key;}
1292  KEY & AccessKey() {return m_key;}
1293 
1294 protected:
1295  typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
1296  const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
1297 
1298  // for signature scheme
1299  HashIdentifier GetHashIdentifier() const
1300  {
1301  typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
1302  return HashLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction>::Lookup();
1303  }
1304  size_t GetDigestSize() const
1305  {
1306  typedef CPP_TYPENAME SchemeOptions::HashFunction H;
1307  return H::DIGESTSIZE;
1308  }
1309 
1310 private:
1311  KEY m_key;
1312 };
1313 
1314 //! _
1315 template <class BASE, class SCHEME_OPTIONS, class KEY>
1316 class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
1317 {
1318 public:
1319  typedef typename KEY::Element Element;
1320 
1321 protected:
1322  const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
1324  const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
1326  const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
1328  const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
1330  HashIdentifier GetHashIdentifier() const
1331  {return HashIdentifier();}
1332  const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
1334 };
1335 
1336 //! _
1337 template <class SCHEME_OPTIONS>
1338 class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
1339 {
1340 public:
1342  {
1343  std::auto_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>);
1344  this->RestartMessageAccumulator(rng, *p);
1345  return p.release();
1346  }
1347 };
1348 
1349 //! _
1350 template <class SCHEME_OPTIONS>
1351 class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
1352 {
1353 public:
1355  {
1357  }
1358 };
1359 
1360 //! _
1361 template <class SCHEME_OPTIONS>
1362 class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
1363 {
1364 };
1365 
1366 //! _
1367 template <class SCHEME_OPTIONS>
1368 class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
1369 {
1370 };
1371 
1372 // ********************************************************
1373 
1374 //! _
1375 template <class T>
1377 {
1378 public:
1379  typedef T Element;
1380 
1381  CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
1382  unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
1383  unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
1384  unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
1385 
1386  void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
1387  {
1388  Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
1389  x.Encode(privateKey, PrivateKeyLength());
1390  }
1391 
1392  void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
1393  {
1394  const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1395  Integer x(privateKey, PrivateKeyLength());
1396  Element y = params.ExponentiateBase(x);
1397  params.EncodeElement(true, y, publicKey);
1398  }
1399 
1400  bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
1401  {
1402  try
1403  {
1404  const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1405  Integer x(privateKey, PrivateKeyLength());
1406  Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
1407 
1408  Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
1409  GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
1410  params.EncodeElement(false, z, agreedValue);
1411  }
1412  catch (DL_BadElement &)
1413  {
1414  return false;
1415  }
1416  return true;
1417  }
1418 
1419  const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
1420 
1421 protected:
1422  virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
1423  virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
1424  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
1425 };
1426 
1427 enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION};
1431 
1432 //! DH key agreement algorithm
1433 template <class ELEMENT, class COFACTOR_OPTION>
1435 {
1436 public:
1437  typedef ELEMENT Element;
1438 
1439  static const char * CRYPTOPP_API StaticAlgorithmName()
1440  {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
1441 
1442  Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
1443  {
1444  return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
1445  COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
1446  }
1447 
1448  Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
1449  {
1450  if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
1451  {
1452  const Integer &k = params.GetCofactor();
1453  return params.ExponentiateElement(publicElement,
1454  ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
1455  }
1456  else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
1457  return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
1458  else
1459  {
1460  assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
1461 
1462  if (!validateOtherPublicKey)
1463  return params.ExponentiateElement(publicElement, privateExponent);
1464 
1465  if (params.FastSubgroupCheckAvailable())
1466  {
1467  if (!params.ValidateElement(2, publicElement, NULL))
1468  throw DL_BadElement();
1469  return params.ExponentiateElement(publicElement, privateExponent);
1470  }
1471  else
1472  {
1473  const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
1474  Element r[2];
1475  params.SimultaneousExponentiate(r, publicElement, e, 2);
1476  if (!params.IsIdentity(r[0]))
1477  throw DL_BadElement();
1478  return r[1];
1479  }
1480  }
1481  }
1482 };
1483 
1484 // ********************************************************
1485 
1486 //! A template implementing constructors for public key algorithm classes
1487 template <class BASE>
1488 class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
1489 {
1490 public:
1491  PK_FinalTemplate() {}
1492 
1493  PK_FinalTemplate(const CryptoMaterial &key)
1494  {this->AccessKey().AssignFrom(key);}
1495 
1497  {this->AccessKey().BERDecode(bt);}
1498 
1499  PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
1500  {this->AccessKey().AssignFrom(algorithm.GetMaterial());}
1501 
1502  PK_FinalTemplate(const Integer &v1)
1503  {this->AccessKey().Initialize(v1);}
1504 
1505 #if (defined(_MSC_VER) && _MSC_VER < 1300)
1506 
1507  template <class T1, class T2>
1508  PK_FinalTemplate(T1 &v1, T2 &v2)
1509  {this->AccessKey().Initialize(v1, v2);}
1510 
1511  template <class T1, class T2, class T3>
1512  PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3)
1513  {this->AccessKey().Initialize(v1, v2, v3);}
1514 
1515  template <class T1, class T2, class T3, class T4>
1516  PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4)
1517  {this->AccessKey().Initialize(v1, v2, v3, v4);}
1518 
1519  template <class T1, class T2, class T3, class T4, class T5>
1520  PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5)
1521  {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
1522 
1523  template <class T1, class T2, class T3, class T4, class T5, class T6>
1524  PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6)
1525  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1526 
1527  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1528  PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7)
1529  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1530 
1531  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
1532  PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
1533  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1534 
1535 #else
1536 
1537  template <class T1, class T2>
1538  PK_FinalTemplate(const T1 &v1, const T2 &v2)
1539  {this->AccessKey().Initialize(v1, v2);}
1540 
1541  template <class T1, class T2, class T3>
1542  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
1543  {this->AccessKey().Initialize(v1, v2, v3);}
1544 
1545  template <class T1, class T2, class T3, class T4>
1546  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
1547  {this->AccessKey().Initialize(v1, v2, v3, v4);}
1548 
1549  template <class T1, class T2, class T3, class T4, class T5>
1550  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
1551  {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
1552 
1553  template <class T1, class T2, class T3, class T4, class T5, class T6>
1554  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
1555  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1556 
1557  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1558  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
1559  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1560 
1561  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
1562  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8)
1563  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1564 
1565  template <class T1, class T2>
1566  PK_FinalTemplate(T1 &v1, const T2 &v2)
1567  {this->AccessKey().Initialize(v1, v2);}
1568 
1569  template <class T1, class T2, class T3>
1570  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
1571  {this->AccessKey().Initialize(v1, v2, v3);}
1572 
1573  template <class T1, class T2, class T3, class T4>
1574  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
1575  {this->AccessKey().Initialize(v1, v2, v3, v4);}
1576 
1577  template <class T1, class T2, class T3, class T4, class T5>
1578  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
1579  {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
1580 
1581  template <class T1, class T2, class T3, class T4, class T5, class T6>
1582  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
1583  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1584 
1585  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1586  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
1587  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1588 
1589  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
1590  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8)
1591  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1592 
1593 #endif
1594 };
1595 
1596 //! Base class for public key encryption standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms.
1598 
1599 //! Base class for public key signature standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms.
1601 
1602 template <class STANDARD, class KEYS, class ALG_INFO>
1603 class TF_ES;
1604 
1605 //! Trapdoor Function Based Encryption Scheme
1606 template <class STANDARD, class KEYS, class ALG_INFO = TF_ES<STANDARD, KEYS, int> >
1607 class TF_ES : public KEYS
1608 {
1609  typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
1610 
1611 public:
1612  //! see EncryptionStandard for a list of standards
1613  typedef STANDARD Standard;
1615 
1616  static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
1617 
1618  //! implements PK_Decryptor interface
1620  //! implements PK_Encryptor interface
1622 };
1623 
1624 template <class STANDARD, class H, class KEYS, class ALG_INFO> // VC60 workaround: doesn't work if KEYS is first parameter
1625 class TF_SS;
1626 
1627 //! Trapdoor Function Based Signature Scheme
1628 template <class STANDARD, class H, class KEYS, class ALG_INFO = TF_SS<STANDARD, H, KEYS, int> > // VC60 workaround: doesn't work if KEYS is first parameter
1629 class TF_SS : public KEYS
1630 {
1631 public:
1632  //! see SignatureStandard for a list of standards
1633  typedef STANDARD Standard;
1634  typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
1636 
1637  static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
1638 
1639  //! implements PK_Signer interface
1641  //! implements PK_Verifier interface
1643 };
1644 
1645 template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
1646 class DL_SS;
1647 
1648 //! Discrete Log Based Signature Scheme
1649 template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
1650 class DL_SS : public KEYS
1651 {
1653 
1654 public:
1655  static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
1656 
1657  //! implements PK_Signer interface
1659  //! implements PK_Verifier interface
1661 };
1662 
1663 //! Discrete Log Based Encryption Scheme
1664 template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
1665 class DL_ES : public KEYS
1666 {
1668 
1669 public:
1670  //! implements PK_Decryptor interface
1672  //! implements PK_Encryptor interface
1674 };
1675 
1676 NAMESPACE_END
1677 
1678 #endif
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: pubkey.h:812
virtual const CryptoMaterial & GetMaterial() const =0
returns a const reference to the crypto material used by this object
bool GetThisObject(T &object) const
get a copy of this object or a subobject of it
Definition: cryptlib.h:247
PK_FinalTemplate< DL_DecryptorImpl< SchemeOptions > > Decryptor
implements PK_Decryptor interface
Definition: pubkey.h:1671
void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters=g_nullNameValuePairs) const
encrypt a byte string
Definition: pubkey.h:1220
bool SupportsPrecomputation() const
Definition: pubkey.h:790
interface for asymmetric algorithms
Definition: cryptlib.h:1133
DH key agreement algorithm.
Definition: pubkey.h:1434
static const Integer & One()
avoid calling constructors for these frequently used integers
Discrete Log Based Signature Scheme.
Definition: pubkey.h:1646
void AssignFrom(const NameValuePairs &source)
assign values from source to this object
Definition: pubkey.h:774
PK_MessageAccumulator * NewVerificationAccumulator() const
create a new HashTransformation to accumulate the message to be verified
Definition: pubkey.h:1354
DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters=g_nullNameValuePairs) const
decrypt a byte string, and return the length of plaintext
Definition: pubkey.h:1184
encodes/decodes privateKeyInfo
Definition: asn.h:264
void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: pubkey.h:810
_
Definition: pubkey.h:123
interface for DL group parameters
Definition: pubkey.h:521
static Integer Gcd(const Integer &a, const Integer &n)
greatest common divisor
interface for message encoding method for public key signature schemes
Definition: pubkey.h:184
virtual unsigned int PrivateKeyLength() const =0
return length of private keys in this domain
message encoding method for public key encryption
Definition: pubkey.h:104
interface for key derivation algorithms used in DL cryptosystems
Definition: pubkey.h:926
PK_FinalTemplate< DL_SignerImpl< SchemeOptions > > Signer
implements PK_Signer interface
Definition: pubkey.h:1658
interface for DL private keys
Definition: pubkey.h:675
virtual bool CanIncorporateEntropy() const
returns true if IncorporateEntropy is implemented
Definition: cryptlib.h:675
ring of congruence classes modulo n
Definition: modarith.h:19
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
sign and restart messageAccumulator
Definition: pubkey.h:1018
interface for random number generators
Definition: cryptlib.h:668
PK_FinalTemplate< TF_EncryptorImpl< SchemeOptions > > Encryptor
implements PK_Encryptor interface
Definition: pubkey.h:1621
_
Definition: pubkey.h:947
void New(size_type newSize)
change size, without preserving contents
Definition: secblock.h:361
Discrete Log Based Encryption Scheme.
Definition: pubkey.h:1665
interface for buffered transformations
Definition: cryptlib.h:770
interface for private keys
Definition: cryptlib.h:1121
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
recover a message from its signature
Definition: pubkey.h:1119
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
Definition: pubkey.h:1099
bool GetThisPointer(T *&p) const
get a pointer to this object, as a pointer to T
Definition: cryptlib.h:254
interface for DL public keys
Definition: pubkey.h:640
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
generate private key
Definition: pubkey.h:1386
Base class for public key signature standard classes. These classes are used to select from variants ...
Definition: pubkey.h:1600
void Precompute(unsigned int precomputationStorage=16)
do precomputation
Definition: pubkey.h:864
unsigned int PublicKeyLength() const
return length of public keys in this domain
Definition: pubkey.h:1384
unsigned int AgreedValueLength() const
return length of agreed value produced
Definition: pubkey.h:1382
_
Definition: pubkey.h:631
interface for domains of simple key agreement protocols
Definition: cryptlib.h:1430
bool FIPS_140_2_ComplianceEnabled()
returns whether FIPS 140-2 compliance features were enabled at compile time
used to return decoding results
Definition: cryptlib.h:197
PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
create a new HashTransformation to accumulate the message to be signed
Definition: pubkey.h:1341
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
retrieve previously saved precomputation
Definition: pubkey.h:795
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
Definition: pubkey.h:547
exception thrown by a class if a non-implemented method is called
Definition: cryptlib.h:165
bool SupportsPrecomputation() const
Definition: pubkey.h:555
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
Definition: pubkey.h:769
interface for Elgamal-like signature algorithms
Definition: pubkey.h:900
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
derive agreed value from your private key and couterparty's public key, return false in case of failu...
Definition: pubkey.h:1400
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
check this object for errors
Definition: pubkey.h:845
Base class for public key encryption standard classes. These classes are used to select from variants...
Definition: pubkey.h:1597
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
retrieve previously saved precomputation
Definition: pubkey.h:870
multiple precision integer and basic arithmetics
Definition: integer.h:26
void Assign(const T *t, size_type len)
set contents and size
Definition: secblock.h:310
void Precompute(unsigned int precomputationStorage=16)
do precomputation
Definition: pubkey.h:792
const NameValuePairs & g_nullNameValuePairs
empty set of name-value pairs
unsigned int PrivateKeyLength() const
return length of private keys in this domain
Definition: pubkey.h:1383
void Precompute(unsigned int precomputationStorage=16)
do precomputation
Definition: pubkey.h:557
PK_FinalTemplate< TF_DecryptorImpl< SchemeOptions > > Decryptor
implements PK_Decryptor interface
Definition: pubkey.h:1619
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
check this object for errors
Definition: pubkey.h:756
PK_FinalTemplate< DL_EncryptorImpl< SchemeOptions > > Encryptor
implements PK_Encryptor interface
Definition: pubkey.h:1673
to be thrown by DecodeElement and AgreeWithStaticPrivateKey
Definition: pubkey.h:513
RandomNumberGenerator & NullRNG()
returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it ...
STANDARD Standard
see EncryptionStandard for a list of standards
Definition: pubkey.h:1613
void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const
encode in big-endian format
void Update(const byte *input, size_t length)
process more input
Definition: pubkey.h:290
interface for accumulating messages to be signed or verified
Definition: cryptlib.h:1333
interface for key agreement algorithms
Definition: cryptlib.h:1176
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
Definition: pubkey.h:852
void DEREncode(BufferedTransformation &bt) const
encode using Distinguished Encoding Rules, put result into a BufferedTransformation object ...
PK_FinalTemplate< TF_SignerImpl< SchemeOptions > > Signer
implements PK_Signer interface
Definition: pubkey.h:1640
void AssignFrom(const NameValuePairs &source)
assign values from source to this object
Definition: pubkey.h:857
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
save precomputation for later use
Definition: pubkey.h:876
PK_FinalTemplate< DL_VerifierImpl< SchemeOptions > > Verifier
implements PK_Verifier interface
Definition: pubkey.h:1660
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
generate public key
Definition: pubkey.h:1392
interface for hash functions and data processing part of MACs
Definition: cryptlib.h:530
interface for crypto material, such as public and private keys, and crypto parameters ...
Definition: cryptlib.h:1034
Trapdoor Function Based Signature Scheme.
Definition: pubkey.h:1625
PK_FinalTemplate< TF_VerifierImpl< SchemeOptions > > Verifier
implements PK_Verifier interface
Definition: pubkey.h:1642
interface for crypto prameters
Definition: cryptlib.h:1127
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
save precomputation for later use
Definition: pubkey.h:798
interface for public keys
Definition: cryptlib.h:1115
Trapdoor Function Based Encryption Scheme.
Definition: pubkey.h:1603
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
check this object for errors
Definition: pubkey.h:531
interface for symmetric encryption algorithms used in DL cryptosystems
Definition: pubkey.h:934
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
generate a random key or crypto parameters
Definition: pubkey.h:779
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
save precomputation for later use
Definition: pubkey.h:568
encodes/decodes subjectPublicKeyInfo
Definition: asn.h:245
exception thrown when input data is received that doesn't conform to expected format ...
Definition: cryptlib.h:151
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
retrieve previously saved precomputation
Definition: pubkey.h:562
Object Identifier.
Definition: asn.h:82
bool SupportsPrecomputation() const
Definition: pubkey.h:862
interface for DL key agreement algorithms
Definition: pubkey.h:915
unsigned int ByteCount() const
number of significant bytes = ceiling(BitCount()/8)
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
input signature into a message accumulator
Definition: pubkey.h:1086
virtual void IncorporateEntropy(const byte *input, size_t length)
update RNG state with additional unpredictable values
Definition: cryptlib.h:672
STANDARD Standard
see SignatureStandard for a list of standards
Definition: pubkey.h:1633
interface for retrieving values given their names
Definition: cryptlib.h:224
A template implementing constructors for public key algorithm classes.
Definition: pubkey.h:1488