Crypto++  5.6.5
Free C++ class library of cryptographic schemes
pubkey.h
Go to the documentation of this file.
1 // pubkey.h - written and placed in the public domain by Wei Dai
2 
3 //! \file pubkey.h
4 //! \brief This file contains helper classes/functions for implementing public key algorithms.
5 //! \details The class hierachies in this header file tend to look like this:
6 //!
7 //! <pre>
8 //! x1
9 //! +--+
10 //! | |
11 //! y1 z1
12 //! | |
13 //! x2<y1> x2<z1>
14 //! | |
15 //! y2 z2
16 //! | |
17 //! x3<y2> x3<z2>
18 //! | |
19 //! y3 z3
20 //! </pre>
21 //!
22 //! <ul>
23 //! <li>x1, y1, z1 are abstract interface classes defined in cryptlib.h
24 //! <li>x2, y2, z2 are implementations of the interfaces using "abstract policies", which
25 //! are pure virtual functions that should return interfaces to interchangeable algorithms.
26 //! These classes have \p Base suffixes.
27 //! <li>x3, y3, z3 hold actual algorithms and implement those virtual functions.
28 //! These classes have \p Impl suffixes.
29 //! </ul>
30 //!
31 //! \details The \p TF_ prefix means an implementation using trapdoor functions on integers.
32 //! \details The \p DL_ prefix means an implementation using group operations in groups where discrete log is hard.
33 
34 #ifndef CRYPTOPP_PUBKEY_H
35 #define CRYPTOPP_PUBKEY_H
36 
37 #include "config.h"
38 
39 #if CRYPTOPP_MSC_VERSION
40 # pragma warning(push)
41 # pragma warning(disable: 4702)
42 #endif
43 
44 #include "cryptlib.h"
45 #include "integer.h"
46 #include "algebra.h"
47 #include "modarith.h"
48 #include "filters.h"
49 #include "eprecomp.h"
50 #include "fips140.h"
51 #include "argnames.h"
52 #include "smartptr.h"
53 #include "stdcpp.h"
54 
55 #if defined(__SUNPRO_CC)
56 # define MAYBE_RETURN(x) return x
57 #else
58 # define MAYBE_RETURN(x) CRYPTOPP_UNUSED(x)
59 #endif
60 
61 NAMESPACE_BEGIN(CryptoPP)
62 
63 //! \class TrapdoorFunctionBounds
64 //! \brief Provides range for plaintext and ciphertext lengths
65 //! \details A trapdoor function is a function that is easy to compute in one direction,
66 //! but difficult to compute in the opposite direction without special knowledge.
67 //! The special knowledge is usually the private key.
68 //! \details Trapdoor functions only handle messages of a limited length or size.
69 //! \p MaxPreimage is the plaintext's maximum length, and \p MaxImage is the
70 //! ciphertext's maximum length.
71 //! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
72 //! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
73 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
74 {
75 public:
76  virtual ~TrapdoorFunctionBounds() {}
77 
78  //! \brief Returns the maximum size of a message before the trapdoor function is applied
79  //! \returns the maximum size of a message before the trapdoor function is applied
80  //! \details Derived classes must implement \p PreimageBound().
81  virtual Integer PreimageBound() const =0;
82  //! \brief Returns the maximum size of a message after the trapdoor function is applied
83  //! \returns the maximum size of a message after the trapdoor function is applied
84  //! \details Derived classes must implement \p ImageBound().
85  virtual Integer ImageBound() const =0;
86  //! \brief Returns the maximum size of a message before the trapdoor function is applied bound to a public key
87  //! \returns the maximum size of a message before the trapdoor function is applied bound to a public key
88  //! \details The default implementation returns <tt>PreimageBound() - 1</tt>.
89  virtual Integer MaxPreimage() const {return --PreimageBound();}
90  //! \brief Returns the maximum size of a message after the trapdoor function is applied bound to a public key
91  //! \returns the the maximum size of a message after the trapdoor function is applied bound to a public key
92  //! \details The default implementation returns <tt>ImageBound() - 1</tt>.
93  virtual Integer MaxImage() const {return --ImageBound();}
94 };
95 
96 //! \class RandomizedTrapdoorFunction
97 //! \brief Applies the trapdoor function, using random data if required
98 //! \details \p ApplyFunction() is the foundation for encrypting a message under a public key.
99 //! Derived classes will override it at some point.
100 //! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
101 //! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
102 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
103 {
104 public:
105  virtual ~RandomizedTrapdoorFunction() {}
106 
107  //! \brief Applies the trapdoor function, using random data if required
108  //! \param rng a \p RandomNumberGenerator derived class
109  //! \param x the message on which the encryption function is applied
110  //! \returns the message \p x encrypted under the public key
111  //! \details \p ApplyRandomizedFunction is a generalization of encryption under a public key
112  //! cryptosystem. The \p RandomNumberGenerator may (or may not) be required.
113  //! Derived classes must implement it.
114  virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
115 
116  //! \brief Determines if the encryption algorithm is randomized
117  //! \returns \p true if the encryption algorithm is randomized, \p false otherwise
118  //! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
119  virtual bool IsRandomized() const {return true;}
120 };
121 
122 //! \class TrapdoorFunction
123 //! \brief Applies the trapdoor function
124 //! \details \p ApplyFunction() is the foundation for encrypting a message under a public key.
125 //! Derived classes will override it at some point.
126 //! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
127 //! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
128 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
129 {
130 public:
131  virtual ~TrapdoorFunction() {}
132 
133  //! \brief Applies the trapdoor function
134  //! \param rng a \p RandomNumberGenerator derived class
135  //! \param x the message on which the encryption function is applied
136  //! \details \p ApplyRandomizedFunction is a generalization of encryption under a public key
137  //! cryptosystem. The \p RandomNumberGenerator may (or may not) be required.
138  //! \details Internally, \p ApplyRandomizedFunction() calls \p ApplyFunction() \a
139  //! without the \p RandomNumberGenerator.
141  {CRYPTOPP_UNUSED(rng); return ApplyFunction(x);}
142  bool IsRandomized() const {return false;}
143 
144  //! \brief Applies the trapdoor
145  //! \param x the message on which the encryption function is applied
146  //! \returns the message \p x encrypted under the public key
147  //! \details \p ApplyFunction is a generalization of encryption under a public key
148  //! cryptosystem. Derived classes must implement it.
149  virtual Integer ApplyFunction(const Integer &x) const =0;
150 };
151 
152 //! \class RandomizedTrapdoorFunctionInverse
153 //! \brief Applies the inverse of the trapdoor function, using random data if required
154 //! \details \p CalculateInverse() is the foundation for decrypting a message under a private key
155 //! in a public key cryptosystem. Derived classes will override it at some point.
156 //! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
157 //! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
158 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
159 {
160 public:
162 
163  //! \brief Applies the inverse of the trapdoor function, using random data if required
164  //! \param rng a \p RandomNumberGenerator derived class
165  //! \param x the message on which the decryption function is applied
166  //! \returns the message \p x decrypted under the private key
167  //! \details \p CalculateRandomizedInverse is a generalization of decryption using the private key
168  //! The \p RandomNumberGenerator may (or may not) be required. Derived classes must implement it.
169  virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
170 
171  //! \brief Determines if the decryption algorithm is randomized
172  //! \returns \p true if the decryption algorithm is randomized, \p false otherwise
173  //! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
174  virtual bool IsRandomized() const {return true;}
175 };
176 
177 //! \class TrapdoorFunctionInverse
178 //! \brief Applies the inverse of the trapdoor function
179 //! \details \p CalculateInverse() is the foundation for decrypting a message under a private key
180 //! in a public key cryptosystem. Derived classes will override it at some point.
181 //! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
182 //! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
183 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
184 {
185 public:
186  virtual ~TrapdoorFunctionInverse() {}
187 
188  //! \brief Applies the inverse of the trapdoor function
189  //! \param rng a \p RandomNumberGenerator derived class
190  //! \param x the message on which the decryption function is applied
191  //! \returns the message \p x decrypted under the private key
192  //! \details \p CalculateRandomizedInverse is a generalization of decryption using the private key
193  //! \details Internally, \p CalculateRandomizedInverse() calls \p CalculateInverse() \a
194  //! without the \p RandomNumberGenerator.
196  {return CalculateInverse(rng, x);}
197 
198  //! \brief Determines if the decryption algorithm is randomized
199  //! \returns \p true if the decryption algorithm is randomized, \p false otherwise
200  //! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
201  bool IsRandomized() const {return false;}
202 
203  //! \brief Calculates the inverse of an element
204  //! \param rng a \p RandomNumberGenerator derived class
205  //! \param x the element
206  //! \returns the inverse of the element in the group
207  virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
208 };
209 
210 // ********************************************************
211 
212 //! \class PK_EncryptionMessageEncodingMethod
213 //! \brief Message encoding method for public key encryption
214 class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
215 {
216 public:
218 
219  virtual bool ParameterSupported(const char *name) const
220  {CRYPTOPP_UNUSED(name); return false;}
221 
222  //! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
223  virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0;
224 
225  virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs &parameters) const =0;
226 
227  virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs &parameters) const =0;
228 };
229 
230 // ********************************************************
231 
232 //! \class TF_Base
233 //! \brief The base for trapdoor based cryptosystems
234 //! \tparam TFI trapdoor function interface derived class
235 //! \tparam MEI message encoding interface derived class
236 template <class TFI, class MEI>
237 class CRYPTOPP_NO_VTABLE TF_Base
238 {
239 protected:
240  virtual ~TF_Base() {}
241 
242  virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
243 
244  typedef TFI TrapdoorFunctionInterface;
245  virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
246 
247  typedef MEI MessageEncodingInterface;
248  virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
249 };
250 
251 // ********************************************************
252 
253 //! \class PK_FixedLengthCryptoSystemImpl
254 //! \brief Public key trapdoor function default implementation
255 //! \tparam BASE public key cryptosystem with a fixed length
256 template <class BASE>
257 class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
258 {
259 public:
260  virtual ~PK_FixedLengthCryptoSystemImpl() {}
261 
262  size_t MaxPlaintextLength(size_t ciphertextLength) const
263  {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
264  size_t CiphertextLength(size_t plaintextLength) const
265  {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
266 
267  virtual size_t FixedMaxPlaintextLength() const =0;
268  virtual size_t FixedCiphertextLength() const =0;
269 };
270 
271 //! \class TF_CryptoSystemBase
272 //! \brief Trapdoor function cryptosystem base class
273 //! \tparam INTFACE public key cryptosystem base interface
274 //! \tparam BASE public key cryptosystem implementation base
275 template <class INTFACE, class BASE>
276 class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTFACE>, protected BASE
277 {
278 public:
279  virtual ~TF_CryptoSystemBase() {}
280 
281  bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);}
282  size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
283  size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
284 
285 protected:
286  size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
287  // Coverity finding on potential overflow/underflow.
288  size_t PaddedBlockBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().PreimageBound().BitCount(),1U);}
289 };
290 
291 //! \class TF_DecryptorBase
292 //! \brief Trapdoor function cryptosystems decryption base class
293 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
294 {
295 public:
296  virtual ~TF_DecryptorBase() {}
297 
298  DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
299 };
300 
301 //! \class TF_DecryptorBase
302 //! \brief Trapdoor function cryptosystems encryption base class
303 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
304 {
305 public:
306  virtual ~TF_EncryptorBase() {}
307 
308  void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
309 };
310 
311 // ********************************************************
312 
313 // Typedef change due to Clang, http://github.com/weidai11/cryptopp/issues/300
314 typedef std::pair<const byte *, unsigned int> HashIdentifier;
315 
316 //! \class PK_SignatureMessageEncodingMethod
317 //! \brief Interface for message encoding method for public key signature schemes.
318 //! \details \p PK_SignatureMessageEncodingMethod provides interfaces for message
319 //! encoding method for public key signature schemes. The methods support both
320 //! trapdoor functions (<tt>TF_*</tt>) and discrete logarithm (<tt>DL_*</tt>)
321 //! based schemes.
322 class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
323 {
324 public:
326 
327  virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const
328  {CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
329  virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const
330  {CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
331 
332  bool IsProbabilistic() const
333  {return true;}
334  bool AllowNonrecoverablePart() const
335  {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
336  virtual bool RecoverablePartFirst() const
337  {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
338 
339  // for verification, DL
340  virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const
341  {CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength);}
342 
343  // for signature
344  virtual void ProcessRecoverableMessage(HashTransformation &hash,
345  const byte *recoverableMessage, size_t recoverableMessageLength,
346  const byte *presignature, size_t presignatureLength,
347  SecByteBlock &semisignature) const
348  {
349  CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength);
350  CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength); CRYPTOPP_UNUSED(semisignature);
351  if (RecoverablePartFirst())
352  CRYPTOPP_ASSERT(!"ProcessRecoverableMessage() not implemented");
353  }
354 
355  virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng,
356  const byte *recoverableMessage, size_t recoverableMessageLength,
357  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
358  byte *representative, size_t representativeBitLength) const =0;
359 
360  virtual bool VerifyMessageRepresentative(
361  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
362  byte *representative, size_t representativeBitLength) const =0;
363 
364  virtual DecodingResult RecoverMessageFromRepresentative( // for TF
365  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
366  byte *representative, size_t representativeBitLength,
367  byte *recoveredMessage) const
368  {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty);
369  CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(recoveredMessage);
370  throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
371 
372  virtual DecodingResult RecoverMessageFromSemisignature( // for DL
373  HashTransformation &hash, HashIdentifier hashIdentifier,
374  const byte *presignature, size_t presignatureLength,
375  const byte *semisignature, size_t semisignatureLength,
376  byte *recoveredMessage) const
377  {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength);
378  CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength); CRYPTOPP_UNUSED(recoveredMessage);
379  throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
380 
381  // VC60 workaround
383  {
384  template <class H> struct HashIdentifierLookup2
385  {
386  static HashIdentifier CRYPTOPP_API Lookup()
387  {
388  return HashIdentifier((const byte *)NULL, 0);
389  }
390  };
391  };
392 };
393 
394 //! \class PK_DeterministicSignatureMessageEncodingMethod
395 //! \brief Interface for message encoding method for public key signature schemes.
396 //! \details \p PK_DeterministicSignatureMessageEncodingMethod provides interfaces
397 //! for message encoding method for public key signature schemes.
399 {
400 public:
401  bool VerifyMessageRepresentative(
402  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
403  byte *representative, size_t representativeBitLength) const;
404 };
405 
406 //! \class PK_RecoverableSignatureMessageEncodingMethod
407 //! \brief Interface for message encoding method for public key signature schemes.
408 //! \details \p PK_RecoverableSignatureMessageEncodingMethod provides interfaces
409 //! for message encoding method for public key signature schemes.
411 {
412 public:
413  bool VerifyMessageRepresentative(
414  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
415  byte *representative, size_t representativeBitLength) const;
416 };
417 
418 //! \class DL_SignatureMessageEncodingMethod_DSA
419 //! \brief Interface for message encoding method for public key signature schemes.
420 //! \details \p DL_SignatureMessageEncodingMethod_DSA provides interfaces
421 //! for message encoding method for DSA.
423 {
424 public:
425  void ComputeMessageRepresentative(RandomNumberGenerator &rng,
426  const byte *recoverableMessage, size_t recoverableMessageLength,
427  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
428  byte *representative, size_t representativeBitLength) const;
429 };
430 
431 //! \class DL_SignatureMessageEncodingMethod_NR
432 //! \brief Interface for message encoding method for public key signature schemes.
433 //! \details \p DL_SignatureMessageEncodingMethod_NR provides interfaces
434 //! for message encoding method for Nyberg-Rueppel.
436 {
437 public:
438  void ComputeMessageRepresentative(RandomNumberGenerator &rng,
439  const byte *recoverableMessage, size_t recoverableMessageLength,
440  HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
441  byte *representative, size_t representativeBitLength) const;
442 };
443 
444 //! \class PK_MessageAccumulatorBase
445 //! \brief Interface for message encoding method for public key signature schemes.
446 //! \details \p PK_MessageAccumulatorBase provides interfaces
447 //! for message encoding method.
448 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
449 {
450 public:
451  PK_MessageAccumulatorBase() : m_empty(true) {}
452 
453  virtual HashTransformation & AccessHash() =0;
454 
455  void Update(const byte *input, size_t length)
456  {
457  AccessHash().Update(input, length);
458  m_empty = m_empty && length == 0;
459  }
460 
461  SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
462  Integer m_k, m_s;
463  bool m_empty;
464 };
465 
466 //! \class PK_MessageAccumulatorImpl
467 //! \brief Interface for message encoding method for public key signature schemes.
468 //! \details \p PK_MessageAccumulatorBase provides interfaces
469 //! for message encoding method.
470 template <class HASH_ALGORITHM>
471 class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
472 {
473 public:
474  HashTransformation & AccessHash() {return this->m_object;}
475 };
476 
477 //! _
478 template <class INTFACE, class BASE>
479 class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTFACE, protected BASE
480 {
481 public:
482  virtual ~TF_SignatureSchemeBase() {}
483 
484  size_t SignatureLength() const
485  {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
486  size_t MaxRecoverableLength() const
487  {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
488  size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
489  {CRYPTOPP_UNUSED(signatureLength); return this->MaxRecoverableLength();}
490 
491  bool IsProbabilistic() const
492  {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
493  bool AllowNonrecoverablePart() const
494  {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
495  bool RecoverablePartFirst() const
496  {return this->GetMessageEncodingInterface().RecoverablePartFirst();}
497 
498 protected:
499  size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
500  // Coverity finding on potential overflow/underflow.
501  size_t MessageRepresentativeBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().ImageBound().BitCount(),1U);}
502  virtual HashIdentifier GetHashIdentifier() const =0;
503  virtual size_t GetDigestSize() const =0;
504 };
505 
506 //! _
507 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
508 {
509 public:
510  virtual ~TF_SignerBase() {}
511 
512  void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const;
513  size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
514 };
515 
516 //! _
517 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
518 {
519 public:
520  virtual ~TF_VerifierBase() {}
521 
522  void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const;
523  bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
524  DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
525 };
526 
527 // ********************************************************
528 
529 //! _
530 template <class T1, class T2, class T3>
532 {
533  typedef T1 AlgorithmInfo;
534  typedef T2 Keys;
535  typedef typename Keys::PrivateKey PrivateKey;
536  typedef typename Keys::PublicKey PublicKey;
537  typedef T3 MessageEncodingMethod;
538 };
539 
540 //! _
541 template <class T1, class T2, class T3, class T4>
543 {
544  typedef T4 HashFunction;
545 };
546 
547 //! _
548 template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
549 class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
550 {
551 public:
552  typedef SCHEME_OPTIONS SchemeOptions;
553  typedef KEY_CLASS KeyClass;
554 
555  virtual ~TF_ObjectImplBase() {}
556 
557  PublicKey & AccessPublicKey() {return AccessKey();}
558  const PublicKey & GetPublicKey() const {return GetKey();}
559 
560  PrivateKey & AccessPrivateKey() {return AccessKey();}
561  const PrivateKey & GetPrivateKey() const {return GetKey();}
562 
563  virtual const KeyClass & GetKey() const =0;
564  virtual KeyClass & AccessKey() =0;
565 
566  const KeyClass & GetTrapdoorFunction() const {return GetKey();}
567 
568  PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
569  {
570  CRYPTOPP_UNUSED(rng);
572  }
573  PK_MessageAccumulator * NewVerificationAccumulator() const
574  {
576  }
577 
578 protected:
579  const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const
581  const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const
582  {return GetKey();}
583  const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const
584  {return GetKey();}
585 
586  // for signature scheme
587  HashIdentifier GetHashIdentifier() const
588  {
589  typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<typename SchemeOptions::HashFunction> L;
590  return L::Lookup();
591  }
592  size_t GetDigestSize() const
593  {
594  typedef typename SchemeOptions::HashFunction H;
595  return H::DIGESTSIZE;
596  }
597 };
598 
599 //! _
600 template <class BASE, class SCHEME_OPTIONS, class KEY>
601 class TF_ObjectImplExtRef : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
602 {
603 public:
604  virtual ~TF_ObjectImplExtRef() {}
605 
606  TF_ObjectImplExtRef(const KEY *pKey = NULL) : m_pKey(pKey) {}
607  void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;}
608 
609  const KEY & GetKey() const {return *m_pKey;}
610  KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");}
611 
612 private:
613  const KEY * m_pKey;
614 };
615 
616 //! _
617 template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
618 class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS>
619 {
620 public:
621  typedef KEY_CLASS KeyClass;
622 
623  virtual ~TF_ObjectImpl() {}
624 
625  const KeyClass & GetKey() const {return m_trapdoorFunction;}
626  KeyClass & AccessKey() {return m_trapdoorFunction;}
627 
628 private:
629  KeyClass m_trapdoorFunction;
630 };
631 
632 //! _
633 template <class SCHEME_OPTIONS>
634 class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
635 {
636 };
637 
638 //! _
639 template <class SCHEME_OPTIONS>
640 class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
641 {
642 };
643 
644 //! _
645 template <class SCHEME_OPTIONS>
646 class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
647 {
648 };
649 
650 //! _
651 template <class SCHEME_OPTIONS>
652 class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
653 {
654 };
655 
656 // ********************************************************
657 
658 //! \class MaskGeneratingFunction
659 //! \brief Mask generation function interface
660 class CRYPTOPP_NO_VTABLE MaskGeneratingFunction
661 {
662 public:
663  virtual ~MaskGeneratingFunction() {}
664 
665  //! \brief Generate and apply mask
666  //! \param hash HashTransformation derived class
667  //! \param output the destination byte array
668  //! \param outputLength the size fo the the destination byte array
669  //! \param input the message to hash
670  //! \param inputLength the size of the message
671  //! \param mask flag indicating whether to apply the mask
672  virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0;
673 };
674 
675 //! \fn P1363_MGF1KDF2_Common
676 //! \brief P1363 mask generation function
677 //! \param hash HashTransformation derived class
678 //! \param output the destination byte array
679 //! \param outputLength the size fo the the destination byte array
680 //! \param input the message to hash
681 //! \param inputLength the size of the message
682 //! \param derivationParams additional derivation parameters
683 //! \param derivationParamsLength the size of the additional derivation parameters
684 //! \param mask flag indicating whether to apply the mask
685 //! \param counterStart starting counter value used in generation function
686 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);
687 
688 //! \class P1363_MGF1
689 //! \brief P1363 mask generation function
691 {
692 public:
693  CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "MGF1";}
694  void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const
695  {
696  P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0);
697  }
698 };
699 
700 // ********************************************************
701 
702 //! \class MaskGeneratingFunction
703 //! \brief P1363 key derivation function
704 //! \tparam H hash function used in the derivation
705 template <class H>
707 {
708 public:
709  static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength)
710  {
711  H h;
712  P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
713  }
714 };
715 
716 // ********************************************************
717 
718 //! \brief Exception thrown when an invalid group element is encountered
719 //! \details Thrown by DecodeElement and AgreeWithStaticPrivateKey
721 {
722 public:
723  DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {}
724 };
725 
726 //! \brief Interface for Discrete Log (DL) group parameters
727 //! \tparam T element in the group
728 //! \details The element is usually an Integer, \ref ECP "ECP::Point" or \ref EC2N "EC2N::Point"
729 template <class T>
730 class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters
731 {
733 
734 public:
735  typedef T Element;
736 
737  virtual ~DL_GroupParameters() {}
738 
739  DL_GroupParameters() : m_validationLevel(0) {}
740 
741  // CryptoMaterial
742  bool Validate(RandomNumberGenerator &rng, unsigned int level) const
743  {
744  if (!GetBasePrecomputation().IsInitialized())
745  return false;
746 
747  if (m_validationLevel > level)
748  return true;
749 
750  bool pass = ValidateGroup(rng, level);
751  pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
752 
753  m_validationLevel = pass ? level+1 : 0;
754 
755  return pass;
756  }
757 
758  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
759  {
760  return GetValueHelper(this, name, valueType, pValue)
761  CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
762  CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
763  ;
764  }
765 
766  bool SupportsPrecomputation() const {return true;}
767 
768  void Precompute(unsigned int precomputationStorage=16)
769  {
770  AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
771  }
772 
773  void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
774  {
775  AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
776  m_validationLevel = 0;
777  }
778 
779  void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
780  {
781  GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
782  }
783 
784  //! \brief Retrieves the subgroup generator
785  //! \return the subgroup generator
786  //! \details The subgroup generator is retrieved from the base precomputation
787  virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
788 
789  //! \brief Set the subgroup generator
790  //! \param base the new subgroup generator
791  //! \details The subgroup generator is set in the base precomputation
792  virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
793 
794  //! \brief Retrieves the subgroup generator
795  //! \return the subgroup generator
796  //! \details The subgroup generator is retrieved from the base precomputation.
797  virtual Element ExponentiateBase(const Integer &exponent) const
798  {
799  return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
800  }
801 
802  //! \brief Exponentiates an element
803  //! \param base the base elemenet
804  //! \param exponent the exponent to raise the base
805  //! \return the result of the exponentiation
806  //! \details Internally, ExponentiateElement() calls SimultaneousExponentiate().
807  virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
808  {
809  Element result;
810  SimultaneousExponentiate(&result, base, &exponent, 1);
811  return result;
812  }
813 
814  //! \brief Retrieves the group precomputation
815  //! \return a const reference to the group precomputation
816  virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0;
817 
818  //! \brief Retrieves the group precomputation
819  //! \return a const reference to the group precomputation using a fixed base
820  virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0;
821 
822  //! \brief Retrieves the group precomputation
823  //! \return a non-const reference to the group precomputation using a fixed base
824  virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0;
825 
826  //! \brief Retrieves the subgroup order
827  //! \return the order of subgroup generated by the base element
828  virtual const Integer & GetSubgroupOrder() const =0;
829 
830  //! \brief Retrieves the maximum exponent for the group
831  //! \return the maximum exponent for the group
832  virtual Integer GetMaxExponent() const =0;
833 
834  //! \brief Retrieves the order of the group
835  //! \return the order of the group
836  //! \details Either GetGroupOrder() or GetCofactor() must be overriden in a derived class.
837  virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();}
838 
839  //! \brief Retrieves the cofactor
840  //! \return the cofactor
841  //! \details Either GetGroupOrder() or GetCofactor() must be overriden in a derived class.
842  virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();}
843 
844  //! \brief Retrieves the encoded element's size
845  //! \param reversible flag indicating the encoding format
846  //! \return encoded element's size, in bytes
847  //! \details The format of the encoded element varies by the underlyinhg type of the element and the
848  //! reversible flag. GetEncodedElementSize() must be implemented in a derived class.
849  //! \sa GetEncodedElementSize(), EncodeElement(), DecodeElement()
850  virtual unsigned int GetEncodedElementSize(bool reversible) const =0;
851 
852  //! \brief Encodes the element
853  //! \param reversible flag indicating the encoding format
854  //! \param element reference to the element to encode
855  //! \param encoded destination byte array for the encoded element
856  //! \details EncodeElement() must be implemented in a derived class.
857  //! \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
858  virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0;
859 
860  //! \brief Decodes the element
861  //! \param encoded byte array with the encoded element
862  //! \param checkForGroupMembership flag indicating if the element should be validated
863  //! \return Element after decoding
864  //! \details DecodeElement() must be implemented in a derived class.
865  //! \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
866  virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0;
867 
868  //! \brief Converts an element to an Integer
869  //! \param element the element to convert to an Integer
870  //! \return Element after converting to an Integer
871  //! \details ConvertElementToInteger() must be implemented in a derived class.
872  virtual Integer ConvertElementToInteger(const Element &element) const =0;
873 
874  //! \brief Check the group for errors
875  //! \param rng RandomNumberGenerator for objects which use randomized testing
876  //! \param level level of thoroughness
877  //! \return true if the tests succeed, false otherwise
878  //! \details There are four levels of thoroughness:
879  //! <ul>
880  //! <li>0 - using this object won't cause a crash or exception
881  //! <li>1 - this object will probably function, and encrypt, sign, other operations correctly
882  //! <li>2 - ensure this object will function correctly, and perform reasonable security checks
883  //! <li>3 - perform reasonable security checks, and do checks that may take a long time
884  //! </ul>
885  //! \details Level 0 does not require a RandomNumberGenerator. A NullRNG() can be used for level 0.
886  //! Level 1 may not check for weak keys and such. Levels 2 and 3 are recommended.
887  //! \details ValidateGroup() must be implemented in a derived class.
888  virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0;
889 
890  //! \brief Check the element for errors
891  //! \param level level of thoroughness
892  //! \param element element to check
893  //! \param precomp optional pointer to DL_FixedBasePrecomputation
894  //! \return true if the tests succeed, false otherwise
895  //! \details There are four levels of thoroughness:
896  //! <ul>
897  //! <li>0 - using this object won't cause a crash or exception
898  //! <li>1 - this object will probably function, and encrypt, sign, other operations correctly
899  //! <li>2 - ensure this object will function correctly, and perform reasonable security checks
900  //! <li>3 - perform reasonable security checks, and do checks that may take a long time
901  //! </ul>
902  //! \details Level 0 performs group membership checks. Level 1 may not check for weak keys and such.
903  //! Levels 2 and 3 are recommended.
904  //! \details ValidateElement() must be implemented in a derived class.
905  virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0;
906 
907  virtual bool FastSubgroupCheckAvailable() const =0;
908 
909  //! \brief Determines if an element is an identity
910  //! \param element element to check
911  //! \return true if the element is an identity, false otherwise
912  //! \details The identity element or or neutral element is a special element in a group that leaves
913  //! other elements unchanged when combined with it.
914  //! \details IsIdentity() must be implemented in a derived class.
915  virtual bool IsIdentity(const Element &element) const =0;
916 
917  //! \brief Exponentiates a base to multiple exponents
918  //! \param results an array of Elements
919  //! \param base the base to raise to the exponents
920  //! \param exponents an array of exponents
921  //! \param exponentsCount the number of exponents in the array
922  //! \details SimultaneousExponentiate() raises the base to each exponent in the exponents array and stores the
923  //! result at the respective position in the results array.
924  //! \details SimultaneousExponentiate() must be implemented in a derived class.
925  //! \pre <tt>COUNTOF(results) == exponentsCount</tt>
926  //! \pre <tt>COUNTOF(exponents) == exponentsCount</tt>
927  virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0;
928 
929 protected:
930  void ParametersChanged() {m_validationLevel = 0;}
931 
932 private:
933  mutable unsigned int m_validationLevel;
934 };
935 
936 //! \brief Base implmentation of Discrete Log (DL) group parameters
937 //! \tparam GROUP_PRECOMP group precomputation class
938 //! \tparam BASE_PRECOMP fixed base precomputation class
939 //! \tparam BASE class or type of an element
940 template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<typename GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<typename GROUP_PRECOMP::Element> >
941 class DL_GroupParametersImpl : public BASE
942 {
943 public:
944  typedef GROUP_PRECOMP GroupPrecomputation;
945  typedef typename GROUP_PRECOMP::Element Element;
946  typedef BASE_PRECOMP BasePrecomputation;
947 
948  virtual ~DL_GroupParametersImpl() {}
949 
950  //! \brief Retrieves the group precomputation
951  //! \return a const reference to the group precomputation
952  const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;}
953 
954  //! \brief Retrieves the group precomputation
955  //! \return a const reference to the group precomputation using a fixed base
957 
958  //! \brief Retrieves the group precomputation
959  //! \return a non-const reference to the group precomputation using a fixed base
961 
962 protected:
963  GROUP_PRECOMP m_groupPrecomputation;
964  BASE_PRECOMP m_gpc;
965 };
966 
967 //! \brief Base class for a Discrete Log (DL) key
968 //! \tparam T class or type of an element
969 //! \details The element is usually an Integer, \ref ECP "ECP::Point" or \ref EC2N "EC2N::Point"
970 template <class T>
971 class CRYPTOPP_NO_VTABLE DL_Key
972 {
973 public:
974  virtual ~DL_Key() {}
975 
976  //! \brief Retrieves abstract group parameters
977  //! \return a const reference to the group parameters
978  virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0;
979  //! \brief Retrieves abstract group parameters
980  //! \return a non-const reference to the group parameters
981  virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0;
982 };
983 
984 //! \brief Interface for Discrete Log (DL) public keys
985 template <class T>
986 class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T>
987 {
988  typedef DL_PublicKey<T> ThisClass;
989 
990 public:
991  typedef T Element;
992 
993  virtual ~DL_PublicKey() {}
994 
995  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
996  {
997  return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
998  CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
999  }
1000 
1001  void AssignFrom(const NameValuePairs &source);
1002 
1003  // non-inherited
1004  virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
1005  virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
1006  virtual Element ExponentiatePublicElement(const Integer &exponent) const
1007  {
1008  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1009  return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
1010  }
1011  virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
1012  {
1013  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1014  return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
1015  }
1016 
1017  virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation() const =0;
1018  virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0;
1019 };
1020 
1021 //! \brief Interface for Discrete Log (DL) private keys
1022 template <class T>
1023 class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T>
1024 {
1025  typedef DL_PrivateKey<T> ThisClass;
1026 
1027 public:
1028  typedef T Element;
1029 
1030  virtual ~DL_PrivateKey() {}
1031 
1032  void MakePublicKey(DL_PublicKey<T> &pub) const
1033  {
1035  pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
1036  }
1037 
1038  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1039  {
1040  return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
1041  CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
1042  }
1043 
1044  void AssignFrom(const NameValuePairs &source)
1045  {
1046  this->AccessAbstractGroupParameters().AssignFrom(source);
1047  AssignFromHelper(this, source)
1048  CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
1049  }
1050 
1051  virtual const Integer & GetPrivateExponent() const =0;
1052  virtual void SetPrivateExponent(const Integer &x) =0;
1053 };
1054 
1055 template <class T>
1056 void DL_PublicKey<T>::AssignFrom(const NameValuePairs &source)
1057 {
1058  DL_PrivateKey<T> *pPrivateKey = NULL;
1059  if (source.GetThisPointer(pPrivateKey))
1060  pPrivateKey->MakePublicKey(*this);
1061  else
1062  {
1063  this->AccessAbstractGroupParameters().AssignFrom(source);
1064  AssignFromHelper(this, source)
1065  CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
1066  }
1067 }
1068 
1069 class OID;
1070 
1071 //! _
1072 template <class PK, class GP, class O = OID>
1073 class DL_KeyImpl : public PK
1074 {
1075 public:
1076  typedef GP GroupParameters;
1077 
1078  virtual ~DL_KeyImpl() {}
1079 
1080  O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();}
1081  bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
1082  {AccessGroupParameters().BERDecode(bt); return true;}
1083  bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
1084  {GetGroupParameters().DEREncode(bt); return true;}
1085 
1086  const GP & GetGroupParameters() const {return m_groupParameters;}
1087  GP & AccessGroupParameters() {return m_groupParameters;}
1088 
1089 private:
1090  GP m_groupParameters;
1091 };
1092 
1093 class X509PublicKey;
1094 class PKCS8PrivateKey;
1095 
1096 //! _
1097 template <class GP>
1098 class DL_PrivateKeyImpl : public DL_PrivateKey<typename GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP>
1099 {
1100 public:
1101  typedef typename GP::Element Element;
1102 
1103  virtual ~DL_PrivateKeyImpl() {}
1104 
1105  // GeneratableCryptoMaterial
1106  bool Validate(RandomNumberGenerator &rng, unsigned int level) const
1107  {
1108  bool pass = GetAbstractGroupParameters().Validate(rng, level);
1109 
1110  const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
1111  const Integer &x = GetPrivateExponent();
1112 
1113  pass = pass && x.IsPositive() && x < q;
1114  if (level >= 1)
1115  pass = pass && Integer::Gcd(x, q) == Integer::One();
1116  return pass;
1117  }
1118 
1119  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1120  {
1121  return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable();
1122  }
1123 
1124  void AssignFrom(const NameValuePairs &source)
1125  {
1126  AssignFromHelper<DL_PrivateKey<Element> >(this, source);
1127  }
1128 
1130  {
1131  if (!params.GetThisObject(this->AccessGroupParameters()))
1132  this->AccessGroupParameters().GenerateRandom(rng, params);
1133  Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
1134  SetPrivateExponent(x);
1135  }
1136 
1137  bool SupportsPrecomputation() const {return true;}
1138 
1139  void Precompute(unsigned int precomputationStorage=16)
1140  {AccessAbstractGroupParameters().Precompute(precomputationStorage);}
1141 
1142  void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
1143  {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
1144 
1145  void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
1146  {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
1147 
1148  // DL_Key
1149  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
1150  DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
1151 
1152  // DL_PrivateKey
1153  const Integer & GetPrivateExponent() const {return m_x;}
1154  void SetPrivateExponent(const Integer &x) {m_x = x;}
1155 
1156  // PKCS8PrivateKey
1158  {m_x.BERDecode(bt);}
1160  {m_x.DEREncode(bt);}
1161 
1162 private:
1163  Integer m_x;
1164 };
1165 
1166 //! _
1167 template <class BASE, class SIGNATURE_SCHEME>
1169 {
1170 public:
1172 
1173  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
1174  {
1175  BASE::GenerateRandom(rng, params);
1176 
1178  {
1179  typename SIGNATURE_SCHEME::Signer signer(*this);
1180  typename SIGNATURE_SCHEME::Verifier verifier(signer);
1181  SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
1182  }
1183  }
1184 };
1185 
1186 //! _
1187 template <class GP>
1188 class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP>
1189 {
1190 public:
1191  typedef typename GP::Element Element;
1192 
1193  virtual ~DL_PublicKeyImpl() {}
1194 
1195  // CryptoMaterial
1196  bool Validate(RandomNumberGenerator &rng, unsigned int level) const
1197  {
1198  bool pass = GetAbstractGroupParameters().Validate(rng, level);
1199  pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
1200  return pass;
1201  }
1202 
1203  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1204  {
1205  return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable();
1206  }
1207 
1208  void AssignFrom(const NameValuePairs &source)
1209  {
1210  AssignFromHelper<DL_PublicKey<Element> >(this, source);
1211  }
1212 
1213  bool SupportsPrecomputation() const {return true;}
1214 
1215  void Precompute(unsigned int precomputationStorage=16)
1216  {
1217  AccessAbstractGroupParameters().Precompute(precomputationStorage);
1218  AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
1219  }
1220 
1221  void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
1222  {
1223  AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
1224  AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
1225  }
1226 
1227  void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
1228  {
1229  GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
1230  GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
1231  }
1232 
1233  // DL_Key
1234  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
1235  DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
1236 
1237  // DL_PublicKey
1238  const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;}
1239  DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;}
1240 
1241  // non-inherited
1242  bool operator==(const DL_PublicKeyImpl<GP> &rhs) const
1243  {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
1244 
1245 private:
1246  typename GP::BasePrecomputation m_ypc;
1247 };
1248 
1249 //! \brief Interface for Elgamal-like signature algorithms
1250 template <class T>
1251 class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm
1252 {
1253 public:
1254  virtual ~DL_ElgamalLikeSignatureAlgorithm() {}
1255 
1256  virtual void Sign(const DL_GroupParameters<T> &params, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
1257  virtual bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
1258  virtual Integer RecoverPresignature(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
1259  {
1260  CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(publicKey); CRYPTOPP_UNUSED(r); CRYPTOPP_UNUSED(s);
1261  throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");
1262  MAYBE_RETURN(Integer::Zero());
1263  }
1264  virtual size_t RLen(const DL_GroupParameters<T> &params) const
1265  {return params.GetSubgroupOrder().ByteCount();}
1266  virtual size_t SLen(const DL_GroupParameters<T> &params) const
1267  {return params.GetSubgroupOrder().ByteCount();}
1268 };
1269 
1270 //! \brief Interface for DL key agreement algorithms
1271 template <class T>
1272 class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm
1273 {
1274 public:
1275  typedef T Element;
1276 
1277  virtual ~DL_KeyAgreementAlgorithm() {}
1278 
1279  virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0;
1280  virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0;
1281 };
1282 
1283 //! \brief Interface for key derivation algorithms used in DL cryptosystems
1284 template <class T>
1285 class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
1286 {
1287 public:
1288  virtual ~DL_KeyDerivationAlgorithm() {}
1289 
1290  virtual bool ParameterSupported(const char *name) const
1291  {CRYPTOPP_UNUSED(name); return false;}
1292  virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0;
1293 };
1294 
1295 //! \brief Interface for symmetric encryption algorithms used in DL cryptosystems
1296 class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
1297 {
1298 public:
1299  virtual ~DL_SymmetricEncryptionAlgorithm() {}
1300 
1301  virtual bool ParameterSupported(const char *name) const
1302  {CRYPTOPP_UNUSED(name); return false;}
1303  virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0;
1304  virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0;
1305  virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0;
1306  virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const =0;
1307  virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const =0;
1308 };
1309 
1310 //! \brief Discrete Log (DL) base interface
1311 //! \tparam KI public or private key interface
1312 template <class KI>
1313 class CRYPTOPP_NO_VTABLE DL_Base
1314 {
1315 protected:
1316  typedef KI KeyInterface;
1317  typedef typename KI::Element Element;
1318 
1319  virtual ~DL_Base() {}
1320 
1321  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();}
1322  DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();}
1323 
1324  virtual KeyInterface & AccessKeyInterface() =0;
1325  virtual const KeyInterface & GetKeyInterface() const =0;
1326 };
1327 
1328 //! \brief Discrete Log (DL) signature scheme base implementation
1329 //! \tparam INTFACE PK_Signer or PK_Verifier derived class
1330 //! \tparam DL_Base key base used in the scheme
1331 //! \details DL_SignatureSchemeBase provides common functions for signers and verifiers.
1332 //! DL_Base<DL_PrivateKey> is used for signers, and DL_Base<DL_PublicKey> is used for verifiers.
1333 template <class INTFACE, class KEY_INTFACE>
1334 class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTFACE, public DL_Base<KEY_INTFACE>
1335 {
1336 public:
1337  virtual ~DL_SignatureSchemeBase() {}
1338 
1339  //! \brief Provides the signature length
1340  //! \returns signature length, in bytes
1341  //! \details SignatureLength returns the size required for <tt>r+s</tt>.
1342  size_t SignatureLength() const
1343  {
1344  return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
1345  + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
1346  }
1347 
1348  //! \brief Provides the maximum recoverable length
1349  //! \returns maximum recoverable length, in bytes
1350  size_t MaxRecoverableLength() const
1351  {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
1352 
1353  //! \brief Provides the maximum recoverable length
1354  //! \param signatureLength the size fo the signature
1355  //! \returns maximum recoverable length based on signature length, in bytes
1356  //! \details this function is not implemented and always returns 0.
1357  size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
1358  {CRYPTOPP_UNUSED(signatureLength); CRYPTOPP_ASSERT(false); return 0;} // TODO
1359 
1360  //! \brief Determines if the scheme is probabilistic
1361  //! \returns true if the scheme is probabilistic, false otherwise
1362  bool IsProbabilistic() const
1363  {return true;}
1364 
1365  //! \brief Determines if the scheme has non-recoverable part
1366  //! \returns true if the message encoding has a non-recoverable part, false otherwise.
1368  {return GetMessageEncodingInterface().AllowNonrecoverablePart();}
1369 
1370  //! \brief Determines if the scheme allows recoverable part first
1371  //! \returns true if the message encoding allows the recoverable part, false otherwise.
1373  {return GetMessageEncodingInterface().RecoverablePartFirst();}
1374 
1375 protected:
1376  size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
1377  size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
1378 
1379  virtual const DL_ElgamalLikeSignatureAlgorithm<typename KEY_INTFACE::Element> & GetSignatureAlgorithm() const =0;
1380  virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
1381  virtual HashIdentifier GetHashIdentifier() const =0;
1382  virtual size_t GetDigestSize() const =0;
1383 };
1384 
1385 //! \brief Discrete Log (DL) signature scheme signer base implementation
1386 //! \tparam T
1387 template <class T>
1388 class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
1389 {
1390 public:
1391  virtual ~DL_SignerBase() {}
1392 
1393  //! \brief Testing interface
1394  //! \param k Integer
1395  //! \param e Integer
1396  //! \param r Integer
1397  //! \param s Integer
1398  void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
1399  {
1400  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1401  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1402  const DL_PrivateKey<T> &key = this->GetKeyInterface();
1403 
1404  r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1405  alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1406  }
1407 
1408  void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
1409  {
1410  PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1411  ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
1412  this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
1413  recoverableMessage, recoverableMessageLength,
1414  ma.m_presignature, ma.m_presignature.size(),
1415  ma.m_semisignature);
1416  }
1417 
1418  size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
1419  {
1420  this->GetMaterial().DoQuickSanityCheck();
1421 
1422  PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1423  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1424  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1425  const DL_PrivateKey<T> &key = this->GetKeyInterface();
1426 
1427  SecByteBlock representative(this->MessageRepresentativeLength());
1428  this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1429  rng,
1430  ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1431  ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1432  representative, this->MessageRepresentativeBitLength());
1433  ma.m_empty = true;
1434  Integer e(representative, representative.size());
1435 
1436  // hash message digest into random number k to prevent reusing the same k on a different messages
1437  // after virtual machine rollback
1438  if (rng.CanIncorporateEntropy())
1439  rng.IncorporateEntropy(representative, representative.size());
1440  Integer k(rng, 1, params.GetSubgroupOrder()-1);
1441  Integer r, s;
1442  r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1443  alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1444 
1445  /*
1446  Integer r, s;
1447  if (this->MaxRecoverableLength() > 0)
1448  r.Decode(ma.m_semisignature, ma.m_semisignature.size());
1449  else
1450  r.Decode(ma.m_presignature, ma.m_presignature.size());
1451  alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s);
1452  */
1453 
1454  size_t rLen = alg.RLen(params);
1455  r.Encode(signature, rLen);
1456  s.Encode(signature+rLen, alg.SLen(params));
1457 
1458  if (restart)
1459  RestartMessageAccumulator(rng, ma);
1460 
1461  return this->SignatureLength();
1462  }
1463 
1464 protected:
1465  void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
1466  {
1467  // k needs to be generated before hashing for signature schemes with recovery
1468  // but to defend against VM rollbacks we need to generate k after hashing.
1469  // so this code is commented out, since no DL-based signature scheme with recovery
1470  // has been implemented in Crypto++ anyway
1471  /*
1472  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1473  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1474  ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
1475  ma.m_presignature.New(params.GetEncodedElementSize(false));
1476  params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size());
1477  */
1478  CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(ma);
1479  }
1480 };
1481 
1482 //! _
1483 template <class T>
1484 class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
1485 {
1486 public:
1487  virtual ~DL_VerifierBase() {}
1488 
1489  void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
1490  {
1491  CRYPTOPP_UNUSED(signature); CRYPTOPP_UNUSED(signatureLength);
1492  PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1493  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1494  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1495 
1496  size_t rLen = alg.RLen(params);
1497  ma.m_semisignature.Assign(signature, rLen);
1498  ma.m_s.Decode(signature+rLen, alg.SLen(params));
1499 
1500  this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
1501  }
1502 
1503  bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
1504  {
1505  this->GetMaterial().DoQuickSanityCheck();
1506 
1507  PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1508  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1509  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1510  const DL_PublicKey<T> &key = this->GetKeyInterface();
1511 
1512  SecByteBlock representative(this->MessageRepresentativeLength());
1513  this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1514  ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1515  representative, this->MessageRepresentativeBitLength());
1516  ma.m_empty = true;
1517  Integer e(representative, representative.size());
1518 
1519  Integer r(ma.m_semisignature, ma.m_semisignature.size());
1520  return alg.Verify(params, key, e, r, ma.m_s);
1521  }
1522 
1523  DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
1524  {
1525  this->GetMaterial().DoQuickSanityCheck();
1526 
1527  PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1528  const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1529  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1530  const DL_PublicKey<T> &key = this->GetKeyInterface();
1531 
1532  SecByteBlock representative(this->MessageRepresentativeLength());
1533  this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1534  NullRNG(),
1535  ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1536  ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1537  representative, this->MessageRepresentativeBitLength());
1538  ma.m_empty = true;
1539  Integer e(representative, representative.size());
1540 
1541  ma.m_presignature.New(params.GetEncodedElementSize(false));
1542  Integer r(ma.m_semisignature, ma.m_semisignature.size());
1543  alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
1544 
1545  return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
1546  ma.AccessHash(), this->GetHashIdentifier(),
1547  ma.m_presignature, ma.m_presignature.size(),
1548  ma.m_semisignature, ma.m_semisignature.size(),
1549  recoveredMessage);
1550  }
1551 };
1552 
1553 //! \brief Discrete Log (DL) cryptosystem base implementation
1554 //! \tparam PK field element type
1555 //! \tparam KI public or private key interface
1556 template <class PK, class KI>
1557 class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
1558 {
1559 public:
1560  typedef typename DL_Base<KI>::Element Element;
1561 
1562  virtual ~DL_CryptoSystemBase() {}
1563 
1564  size_t MaxPlaintextLength(size_t ciphertextLength) const
1565  {
1566  unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
1567  return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
1568  }
1569 
1570  size_t CiphertextLength(size_t plaintextLength) const
1571  {
1572  size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
1573  return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
1574  }
1575 
1576  bool ParameterSupported(const char *name) const
1577  {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
1578 
1579 protected:
1580  virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
1581  virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
1582  virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
1583 };
1584 
1585 //! \brief Discrete Log (DL) decryptor base implementation
1586 //! \tparam T field element type
1587 template <class T>
1588 class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
1589 {
1590 public:
1591  typedef T Element;
1592 
1593  virtual ~DL_DecryptorBase() {}
1594 
1595  DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
1596  {
1597  try
1598  {
1599  CRYPTOPP_UNUSED(rng);
1600  const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
1601  const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
1602  const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
1603  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1604  const DL_PrivateKey<T> &key = this->GetKeyInterface();
1605 
1606  Element q = params.DecodeElement(ciphertext, true);
1607  size_t elementSize = params.GetEncodedElementSize(true);
1608  ciphertext += elementSize;
1609  ciphertextLength -= elementSize;
1610 
1611  Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
1612 
1613  SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
1614  derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1615 
1616  return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
1617  }
1618  catch (DL_BadElement &)
1619  {
1620  return DecodingResult();
1621  }
1622  }
1623 };
1624 
1625 //! \brief Discrete Log (DL) encryptor base implementation
1626 //! \tparam T field element type
1627 template <class T>
1628 class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
1629 {
1630 public:
1631  typedef T Element;
1632 
1633  virtual ~DL_EncryptorBase() {}
1634 
1635  void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const
1636  {
1637  const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
1638  const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
1639  const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
1640  const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1641  const DL_PublicKey<T> &key = this->GetKeyInterface();
1642 
1643  Integer x(rng, Integer::One(), params.GetMaxExponent());
1644  Element q = params.ExponentiateBase(x);
1645  params.EncodeElement(true, q, ciphertext);
1646  unsigned int elementSize = params.GetEncodedElementSize(true);
1647  ciphertext += elementSize;
1648 
1649  Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
1650 
1651  SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
1652  derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1653 
1654  encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
1655  }
1656 };
1657 
1658 //! \brief Discrete Log (DL) scheme options
1659 //! \tparam T1 algorithm information
1660 //! \tparam T2 group paramters for the scheme
1661 template <class T1, class T2>
1663 {
1664  typedef T1 AlgorithmInfo;
1665  typedef T2 GroupParameters;
1666  typedef typename GroupParameters::Element Element;
1667 };
1668 
1669 //! \brief Discrete Log (DL) key options
1670 //! \tparam T1 algorithm information
1671 //! \tparam T2 keys used in the scheme
1672 template <class T1, class T2>
1673 struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
1674 {
1675  typedef T2 Keys;
1676  typedef typename Keys::PrivateKey PrivateKey;
1677  typedef typename Keys::PublicKey PublicKey;
1678 };
1679 
1680 //! \brief Discrete Log (DL) signature scheme options
1681 //! \tparam T1 algorithm information
1682 //! \tparam T2 keys used in the scheme
1683 //! \tparam T3 signature algorithm
1684 //! \tparam T4 message encoding method
1685 //! \tparam T5 hash function
1686 template <class T1, class T2, class T3, class T4, class T5>
1688 {
1689  typedef T3 SignatureAlgorithm;
1690  typedef T4 MessageEncodingMethod;
1691  typedef T5 HashFunction;
1692 };
1693 
1694 //! \brief Discrete Log (DL) crypto scheme options
1695 //! \tparam T1 algorithm information
1696 //! \tparam T2 keys used in the scheme
1697 //! \tparam T3 key agreement algorithm
1698 //! \tparam T4 key derivation algorithm
1699 //! \tparam T5 symmetric encryption algorithm
1700 template <class T1, class T2, class T3, class T4, class T5>
1702 {
1703  typedef T3 KeyAgreementAlgorithm;
1704  typedef T4 KeyDerivationAlgorithm;
1705  typedef T5 SymmetricEncryptionAlgorithm;
1706 };
1707 
1708 //! \brief Discrete Log (DL) base object implementation
1709 //! \tparam BASE TODO
1710 //! \tparam SCHEME_OPTIONS options for the scheme
1711 //! \tparam KEY key used in the scheme
1712 template <class BASE, class SCHEME_OPTIONS, class KEY>
1713 class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
1714 {
1715 public:
1716  typedef SCHEME_OPTIONS SchemeOptions;
1717  typedef typename KEY::Element Element;
1718 
1719  virtual ~DL_ObjectImplBase() {}
1720 
1721  PrivateKey & AccessPrivateKey() {return m_key;}
1722  PublicKey & AccessPublicKey() {return m_key;}
1723 
1724  // KeyAccessor
1725  const KEY & GetKey() const {return m_key;}
1726  KEY & AccessKey() {return m_key;}
1727 
1728 protected:
1729  typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
1730  const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
1731 
1732  // for signature scheme
1733  HashIdentifier GetHashIdentifier() const
1734  {
1735  typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
1736  return HashLookup::template HashIdentifierLookup2<typename SchemeOptions::HashFunction>::Lookup();
1737  }
1738  size_t GetDigestSize() const
1739  {
1740  typedef typename SchemeOptions::HashFunction H;
1741  return H::DIGESTSIZE;
1742  }
1743 
1744 private:
1745  KEY m_key;
1746 };
1747 
1748 //! \brief Discrete Log (DL) object implementation
1749 //! \tparam BASE TODO
1750 //! \tparam SCHEME_OPTIONS options for the scheme
1751 //! \tparam KEY key used in the scheme
1752 template <class BASE, class SCHEME_OPTIONS, class KEY>
1753 class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
1754 {
1755 public:
1756  typedef typename KEY::Element Element;
1757 
1758  virtual ~DL_ObjectImpl() {}
1759 
1760 protected:
1761  const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
1763  const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
1765  const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
1767  const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
1769  HashIdentifier GetHashIdentifier() const
1770  {return HashIdentifier();}
1771  const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
1773 };
1774 
1775 //! \brief Discrete Log (DL) signer implementation
1776 //! \tparam SCHEME_OPTIONS options for the scheme
1777 template <class SCHEME_OPTIONS>
1778 class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
1779 {
1780 public:
1782  {
1784  this->RestartMessageAccumulator(rng, *p);
1785  return p.release();
1786  }
1787 };
1788 
1789 //! \brief Discrete Log (DL) verifier implementation
1790 //! \tparam SCHEME_OPTIONS options for the scheme
1791 template <class SCHEME_OPTIONS>
1792 class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
1793 {
1794 public:
1796  {
1798  }
1799 };
1800 
1801 //! \brief Discrete Log (DL) encryptor implementation
1802 //! \tparam SCHEME_OPTIONS options for the scheme
1803 template <class SCHEME_OPTIONS>
1804 class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
1805 {
1806 };
1807 
1808 //! \brief Discrete Log (DL) decryptor implementation
1809 //! \tparam SCHEME_OPTIONS options for the scheme
1810 template <class SCHEME_OPTIONS>
1811 class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
1812 {
1813 };
1814 
1815 // ********************************************************
1816 
1817 //! \brief Discrete Log (DL) simple key agreement base implementation
1818 //! \tparam T class or type
1819 template <class T>
1821 {
1822 public:
1823  typedef T Element;
1824 
1825  virtual ~DL_SimpleKeyAgreementDomainBase() {}
1826 
1827  CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
1828  unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
1829  unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
1830  unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
1831 
1832  void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
1833  {
1834  Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
1835  x.Encode(privateKey, PrivateKeyLength());
1836  }
1837 
1838  void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
1839  {
1840  CRYPTOPP_UNUSED(rng);
1841  const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1842  Integer x(privateKey, PrivateKeyLength());
1843  Element y = params.ExponentiateBase(x);
1844  params.EncodeElement(true, y, publicKey);
1845  }
1846 
1847  bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
1848  {
1849  try
1850  {
1851  const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1852  Integer x(privateKey, PrivateKeyLength());
1853  Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
1854 
1855  Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
1856  GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
1857  params.EncodeElement(false, z, agreedValue);
1858  }
1859  catch (DL_BadElement &)
1860  {
1861  return false;
1862  }
1863  return true;
1864  }
1865 
1866  //! \brief Retrieves a reference to the group generator
1867  //! \returns const reference to the group generator
1868  const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
1869 
1870 protected:
1871  virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
1872  virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
1873  const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
1874 };
1875 
1876 //! \brief Methods for avoiding "Small-Subgroup" attacks on Diffie-Hellman Key Agreement
1877 //! \details Additional methods exist and include public key validation and choice of prime p.
1878 //! \sa <A HREF="http://tools.ietf.org/html/rfc2785">Methods for Avoiding the "Small-Subgroup" Attacks on the
1879 //! Diffie-Hellman Key Agreement Method for S/MIME</A>
1881  //! \brief No cofactor multiplication applied
1883  //! \brief Cofactor multiplication compatible with ordinary Diffie-Hellman
1884  //! \details Modifies the computation of ZZ by including j (the cofactor) in the computations and is
1885  //! compatible with ordinary Diffie-Hellman.
1887  //! \brief Cofactor multiplication incompatible with ordinary Diffie-Hellman
1888  //! \details Modifies the computation of ZZ by including j (the cofactor) in the computations but is
1889  //! not compatible with ordinary Diffie-Hellman.
1891 
1895 
1896 //! \brief Diffie-Hellman key agreement algorithm
1897 template <class ELEMENT, class COFACTOR_OPTION>
1899 {
1900 public:
1901  typedef ELEMENT Element;
1902 
1903  CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName()
1904  {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
1905 
1906  virtual ~DL_KeyAgreementAlgorithm_DH() {}
1907 
1908  Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
1909  {
1910  return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
1911  COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
1912  }
1913 
1914  Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
1915  {
1916  if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
1917  {
1918  const Integer &k = params.GetCofactor();
1919  return params.ExponentiateElement(publicElement,
1920  ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
1921  }
1922  else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
1923  return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
1924  else
1925  {
1926  CRYPTOPP_ASSERT(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
1927 
1928  if (!validateOtherPublicKey)
1929  return params.ExponentiateElement(publicElement, privateExponent);
1930 
1931  if (params.FastSubgroupCheckAvailable())
1932  {
1933  if (!params.ValidateElement(2, publicElement, NULL))
1934  throw DL_BadElement();
1935  return params.ExponentiateElement(publicElement, privateExponent);
1936  }
1937  else
1938  {
1939  const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
1940  Element r[2];
1941  params.SimultaneousExponentiate(r, publicElement, e, 2);
1942  if (!params.IsIdentity(r[0]))
1943  throw DL_BadElement();
1944  return r[1];
1945  }
1946  }
1947  }
1948 };
1949 
1950 // ********************************************************
1951 
1952 //! \brief Template implementing constructors for public key algorithm classes
1953 template <class BASE>
1954 class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
1955 {
1956 public:
1957  PK_FinalTemplate() {}
1958 
1959  PK_FinalTemplate(const CryptoMaterial &key)
1960  {this->AccessKey().AssignFrom(key);}
1961 
1963  {this->AccessKey().BERDecode(bt);}
1964 
1965  PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
1966  {this->AccessKey().AssignFrom(algorithm.GetMaterial());}
1967 
1968  PK_FinalTemplate(const Integer &v1)
1969  {this->AccessKey().Initialize(v1);}
1970 
1971  template <class T1, class T2>
1972  PK_FinalTemplate(const T1 &v1, const T2 &v2)
1973  {this->AccessKey().Initialize(v1, v2);}
1974 
1975  template <class T1, class T2, class T3>
1976  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
1977  {this->AccessKey().Initialize(v1, v2, v3);}
1978 
1979  template <class T1, class T2, class T3, class T4>
1980  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
1981  {this->AccessKey().Initialize(v1, v2, v3, v4);}
1982 
1983  template <class T1, class T2, class T3, class T4, class T5>
1984  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
1985  {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
1986 
1987  template <class T1, class T2, class T3, class T4, class T5, class T6>
1988  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
1989  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1990 
1991  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1992  PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
1993  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1994 
1995  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
1996  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)
1997  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1998 
1999  template <class T1, class T2>
2000  PK_FinalTemplate(T1 &v1, const T2 &v2)
2001  {this->AccessKey().Initialize(v1, v2);}
2002 
2003  template <class T1, class T2, class T3>
2004  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
2005  {this->AccessKey().Initialize(v1, v2, v3);}
2006 
2007  template <class T1, class T2, class T3, class T4>
2008  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
2009  {this->AccessKey().Initialize(v1, v2, v3, v4);}
2010 
2011  template <class T1, class T2, class T3, class T4, class T5>
2012  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
2013  {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
2014 
2015  template <class T1, class T2, class T3, class T4, class T5, class T6>
2016  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
2017  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
2018 
2019  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
2020  PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
2021  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
2022 
2023  template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
2024  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)
2025  {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
2026 };
2027 
2028 //! \brief Base class for public key encryption standard classes.
2029 //! \details These classes are used to select from variants of algorithms.
2030 //! Not all standards apply to all algorithms.
2032 
2033 //! \brief Base class for public key signature standard classes.
2034 //! \details These classes are used to select from variants of algorithms.
2035 //! Not all standards apply to all algorithms.
2037 
2038 //! \brief Trapdoor Function (TF) encryption scheme
2039 //! \tparam STANDARD standard
2040 //! \tparam KEYS keys used in the encryption scheme
2041 //! \tparam ALG_INFO algorithm information
2042 template <class KEYS, class STANDARD, class ALG_INFO>
2043 class TF_ES;
2044 
2045 template <class KEYS, class STANDARD, class ALG_INFO = TF_ES<KEYS, STANDARD, int> >
2046 class TF_ES : public KEYS
2047 {
2048  typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
2049 
2050 public:
2051  //! see EncryptionStandard for a list of standards
2052  typedef STANDARD Standard;
2054 
2055  static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
2056 
2057  //! implements PK_Decryptor interface
2059  //! implements PK_Encryptor interface
2061 };
2062 
2063 //! \class TF_SS
2064 //! \brief Trapdoor Function (TF) Signature Scheme
2065 //! \tparam STANDARD standard
2066 //! \tparam H hash function
2067 //! \tparam KEYS keys used in the signature scheme
2068 //! \tparam ALG_INFO algorithm information
2069 template <class KEYS, class STANDARD, class H, class ALG_INFO>
2070 class TF_SS;
2071 
2072 template <class KEYS, class STANDARD, class H, class ALG_INFO = TF_SS<KEYS, STANDARD, H, int> >
2073 class TF_SS : public KEYS
2074 {
2075 public:
2076  //! see SignatureStandard for a list of standards
2077  typedef STANDARD Standard;
2080 
2081  static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
2082 
2083  //! implements PK_Signer interface
2085  //! implements PK_Verifier interface
2087 };
2088 
2089 //! \class DL_SS
2090 //! \brief Discrete Log (DL) signature scheme
2091 //! \tparam KEYS keys used in the signature scheme
2092 //! \tparam SA signature algorithm
2093 //! \tparam MEM message encoding method
2094 //! \tparam H hash function
2095 //! \tparam ALG_INFO algorithm information
2096 template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
2097 class DL_SS;
2098 
2099 template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
2100 class DL_SS : public KEYS
2101 {
2103 
2104 public:
2105  static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
2106 
2107  //! implements PK_Signer interface
2109  //! implements PK_Verifier interface
2111 };
2112 
2113 //! \brief Discrete Log (DL) encryption scheme
2114 //! \tparam KEYS keys used in the encryption scheme
2115 //! \tparam AA key agreement algorithm
2116 //! \tparam DA key derivation algorithm
2117 //! \tparam EA encryption algorithm
2118 //! \tparam ALG_INFO algorithm information
2119 template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
2120 class DL_ES : public KEYS
2121 {
2123 
2124 public:
2125  //! implements PK_Decryptor interface
2127  //! implements PK_Encryptor interface
2129 };
2130 
2131 NAMESPACE_END
2132 
2133 #if CRYPTOPP_MSC_VERSION
2134 # pragma warning(pop)
2135 #endif
2136 
2137 #endif
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: pubkey.h:1159
virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0
Exponentiates a base to multiple exponents.
Standard names for retrieving values by name when working with NameValuePairs.
bool IsProbabilistic() const
Determines if the scheme is probabilistic.
Definition: pubkey.h:1362
Discrete Log (DL) key options.
Definition: pubkey.h:1673
bool GetThisObject(T &object) const
Get a copy of this object or subobject.
Definition: cryptlib.h:315
Applies the trapdoor function, using random data if required.
Definition: pubkey.h:102
PK_FinalTemplate< DL_DecryptorImpl< SchemeOptions > > Decryptor
implements PK_Decryptor interface
Definition: pubkey.h:2126
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:1635
bool SupportsPrecomputation() const
Determines whether the object supports precomputation.
Definition: pubkey.h:1137
Interface for asymmetric algorithms.
Definition: cryptlib.h:2196
Interface for message encoding method for public key signature schemes.
Definition: pubkey.h:422
Trapdoor Function (TF) encryption scheme.
Definition: pubkey.h:2043
virtual const CryptoMaterial & GetMaterial() const =0
Retrieves a reference to CryptoMaterial.
Diffie-Hellman key agreement algorithm.
Definition: pubkey.h:1898
Restricts the instantiation of a class to one static object without locks.
Definition: misc.h:274
Discrete Log (DL) signer implementation.
Definition: pubkey.h:1778
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition: integer.cpp:3369
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: pubkey.h:1124
PK_MessageAccumulator * NewVerificationAccumulator() const
Create a new HashTransformation to accumulate the message to be verified.
Definition: pubkey.h:1795
DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters=g_nullNameValuePairs) const
Decrypt a byte string.
Definition: pubkey.h:1595
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
PK_FinalTemplate< TF_VerifierImpl< SchemeOptions > > Verifier
implements PK_Verifier interface
Definition: pubkey.h:2086
PK_FinalTemplate< TF_EncryptorImpl< SchemeOptions > > Encryptor
implements PK_Encryptor interface
Definition: pubkey.h:2060
static Integer Gcd(const Integer &a, const Integer &n)
greatest common divisor
Definition: integer.cpp:4365
Encodes and decodesprivateKeyInfo.
Definition: asn.h:414
void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: pubkey.h:1157
virtual void SetSubgroupGenerator(const Element &base)
Set the subgroup generator.
Definition: pubkey.h:792
The base for trapdoor based cryptosystems.
Definition: pubkey.h:237
virtual Integer ConvertElementToInteger(const Element &element) const =0
Converts an element to an Integer.
Interface for Discrete Log (DL) group parameters.
Definition: pubkey.h:730
Converts an enumeration to a type suitable for use as a template parameter.
Definition: cryptlib.h:116
Interface for message encoding method for public key signature schemes.
Definition: pubkey.h:322
virtual bool IsRandomized() const
Determines if the decryption algorithm is randomized.
Definition: pubkey.h:174
Abstract base classes that provide a uniform interface to this library.
virtual Integer GetMaxExponent() const =0
Retrieves the maximum exponent for the group.
virtual const DL_GroupPrecomputation< Element > & GetGroupPrecomputation() const =0
Retrieves the group precomputation.
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:524
const Element & GetGenerator() const
Retrieves a reference to the group generator.
Definition: pubkey.h:1868
bool IsRandomized() const
Determines if the encryption algorithm is randomized.
Definition: pubkey.h:142
Message encoding method for public key encryption.
Definition: pubkey.h:214
Interface for key derivation algorithms used in DL cryptosystems.
Definition: pubkey.h:1285
Classes for automatic resource management.
Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
Applies the inverse of the trapdoor function.
Definition: pubkey.h:195
Library configuration file.
Interface for Discrete Log (DL) private keys.
Definition: pubkey.h:1023
bool RecoverablePartFirst() const
Determines if the scheme allows recoverable part first.
Definition: pubkey.h:1372
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: cryptlib.h:1209
Ring of congruence classes modulo n.
Definition: modarith.h:34
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
Sign and restart messageAccumulator.
Definition: pubkey.h:1418
Interface for random number generators.
Definition: cryptlib.h:1188
Discrete Log (DL) base interface.
Definition: pubkey.h:1313
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:647
Trapdoor function cryptosystems decryption base class.
Definition: pubkey.h:293
Discrete Log (DL) scheme options.
Definition: pubkey.h:1662
const DL_GroupParameters< Element > & GetAbstractGroupParameters() const
Retrieves abstract group parameters.
Definition: pubkey.h:1234
Discrete Log (DL) encryption scheme.
Definition: pubkey.h:2120
SecBlock typedef.
Definition: secblock.h:731
Discrete Log (DL) crypto scheme options.
Definition: pubkey.h:1701
Classes for performing mathematics over different fields.
STANDARD Standard
see SignatureStandard for a list of standards
Definition: pubkey.h:2077
Interface for buffered transformations.
Definition: cryptlib.h:1352
_
Definition: emsa2.h:61
Provides range for plaintext and ciphertext lengths.
Definition: pubkey.h:73
Interface for private keys.
Definition: cryptlib.h:2186
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
Recover a message from its signature.
Definition: pubkey.h:1523
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
Definition: pubkey.h:1503
static const Integer & One()
Integer representing 1.
Definition: integer.cpp:3035
Interface for Discrete Log (DL) public keys.
Definition: pubkey.h:986
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate private key in this domain.
Definition: pubkey.h:1832
Base class for public key signature standard classes.
Definition: pubkey.h:2036
virtual const Element & GetSubgroupGenerator() const
Retrieves the subgroup generator.
Definition: pubkey.h:787
virtual const DL_GroupParameters< T > & GetAbstractGroupParameters() const =0
Retrieves abstract group parameters.
const char * PrivateExponent()
Integer.
Definition: argnames.h:35
CryptoParameters & AccessCryptoParameters()
Retrieves a reference to Crypto Parameters.
Definition: pubkey.h:1827
Pointer that overloads operator ->
Definition: smartptr.h:39
void Precompute(unsigned int precomputationStorage=16)
Perform precomputation.
Definition: pubkey.h:1215
Discrete Log (DL) signature scheme.
Definition: pubkey.h:2097
const DL_FixedBasePrecomputation< Element > & GetBasePrecomputation() const
Retrieves the group precomputation.
Definition: pubkey.h:956
unsigned int PublicKeyLength() const
Provides the size of the public key.
Definition: pubkey.h:1830
unsigned int AgreedValueLength() const
Provides the size of the agreed value.
Definition: pubkey.h:1828
virtual Integer MaxPreimage() const
Returns the maximum size of a message before the trapdoor function is applied bound to a public key...
Definition: pubkey.h:89
virtual const DL_FixedBasePrecomputation< Element > & GetBasePrecomputation() const =0
Retrieves the group precomputation.
Base class for a Discrete Log (DL) key.
Definition: pubkey.h:971
Interface for domains of simple key agreement protocols.
Definition: cryptlib.h:2663
bool FIPS_140_2_ComplianceEnabled()
Determines whether the library provides FIPS validated cryptography.
Definition: fips140.cpp:29
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
Applies the inverse of the trapdoor function.
Definition: pubkey.h:183
virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation< Element > *precomp) const =0
Check the element for errors.
Returns a decoding results.
Definition: cryptlib.h:238
Uses encapsulation to hide an object in derived classes.
Definition: misc.h:205
bool IsPositive() const
Determines if the Integer is positive.
Definition: integer.h:336
DL_FixedBasePrecomputation< Element > & AccessBasePrecomputation()
Retrieves the group precomputation.
Definition: pubkey.h:960
PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
Create a new HashTransformation to accumulate the message to be signed.
Definition: pubkey.h:1781
P1363 mask generation function.
Definition: pubkey.h:690
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
Retrieve previously saved precomputation.
Definition: pubkey.h:1142
void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
Testing interface.
Definition: pubkey.h:1398
Cofactor multiplication compatible with ordinary Diffie-Hellman.
Definition: pubkey.h:1886
bool GetThisPointer(T *&ptr) const
Get a pointer to this object.
Definition: cryptlib.h:324
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: pubkey.h:758
PK_FinalTemplate< TF_SignerImpl< SchemeOptions > > Signer
implements PK_Signer interface
Definition: pubkey.h:2084
A method was called which was not implemented.
Definition: cryptlib.h:205
bool SupportsPrecomputation() const
Determines whether the object supports precomputation.
Definition: pubkey.h:766
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: pubkey.h:1119
No cofactor multiplication applied.
Definition: pubkey.h:1882
Interface for Elgamal-like signature algorithms.
Definition: pubkey.h:1251
Discrete Log (DL) signature scheme signer base implementation.
Definition: pubkey.h:1388
Interface for message encoding method for public key signature schemes.
Definition: pubkey.h:398
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Derive agreed value.
Definition: pubkey.h:1847
Interface for message encoding method for public key signature schemes.
Definition: pubkey.h:448
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: pubkey.h:1196
void Assign(const T *ptr, size_type len)
Set contents and size from an array.
Definition: secblock.h:544
Base class for public key encryption standard classes.
Definition: pubkey.h:2031
Discrete Log (DL) object implementation.
Definition: pubkey.h:1753
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
Retrieve previously saved precomputation.
Definition: pubkey.h:1221
Multiple precision integer with arithmetic operations.
Definition: integer.h:43
Discrete Log (DL) verifier implementation.
Definition: pubkey.h:1792
void Precompute(unsigned int precomputationStorage=16)
Perform precomputation.
Definition: pubkey.h:1139
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
Definition: misc.h:847
Discrete Log (DL) signature scheme base implementation.
Definition: pubkey.h:1334
virtual Integer MaxImage() const
Returns the maximum size of a message after the trapdoor function is applied bound to a public key...
Definition: pubkey.h:93
Discrete Log (DL) base object implementation.
Definition: pubkey.h:1713
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Definition: cryptlib.cpp:76
const char * SubgroupGenerator()
Integer, ECP::Point, or EC2N::Point.
Definition: argnames.h:39
Applies the trapdoor function.
Definition: pubkey.h:128
Discrete Log (DL) cryptosystem base implementation.
Definition: pubkey.h:1557
unsigned int PrivateKeyLength() const
Provides the size of the private key.
Definition: pubkey.h:1829
virtual const Integer & GetSubgroupOrder() const =0
Retrieves the subgroup order.
const DL_GroupPrecomputation< Element > & GetGroupPrecomputation() const
Retrieves the group precomputation.
Definition: pubkey.h:952
void Precompute(unsigned int precomputationStorage=16)
Perform precomputation.
Definition: pubkey.h:768
Mask generation function interface.
Definition: pubkey.h:660
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: pubkey.h:1106
PK_FinalTemplate< DL_EncryptorImpl< SchemeOptions > > Encryptor
implements PK_Encryptor interface
Definition: pubkey.h:2128
bool AllowNonrecoverablePart() const
Determines if the scheme has non-recoverable part.
Definition: pubkey.h:1367
Public key trapdoor function default implementation.
Definition: pubkey.h:257
virtual bool IsIdentity(const Element &element) const =0
Determines if an element is an identity.
Exception thrown when an invalid group element is encountered.
Definition: pubkey.h:720
virtual Integer GetCofactor() const
Retrieves the cofactor.
Definition: pubkey.h:842
RandomNumberGenerator & NullRNG()
Random Number Generator that does not produce random numbers.
Definition: cryptlib.cpp:402
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:62
virtual unsigned int PrivateKeyLength() const =0
Provides the size of the private key.
void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask=true) const
Generate and apply mask.
Definition: pubkey.h:694
virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0
Decodes the element.
bool IsRandomized() const
Determines if the decryption algorithm is randomized.
Definition: pubkey.h:201
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Definition: pubkey.h:455
Implementation of BufferedTransformation's attachment interface.
DL_GroupParameters< Element > & AccessAbstractGroupParameters()
Retrieves abstract group parameters.
Definition: pubkey.h:1235
void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
Input a recoverable message to an accumulator.
Definition: pubkey.h:1408
Interface for accumulating messages to be signed or verified.
Definition: cryptlib.h:2509
Interface for key agreement algorithms.
Definition: cryptlib.h:2270
Discrete Log (DL) encryptor base implementation.
Definition: pubkey.h:1628
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: pubkey.h:1203
void DEREncode(BufferedTransformation &bt) const
Encode in DER format.
Definition: integer.cpp:3391
Classes for precomputation in a group.
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: pubkey.h:1208
PK_FinalTemplate< DL_SignerImpl< SchemeOptions > > Signer
implements PK_Signer interface
Definition: pubkey.h:2108
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
Save precomputation for later use.
Definition: pubkey.h:1227
Classes and functions for the FIPS 140-2 validated library.
size_t SignatureLength() const
Provides the signature length.
Definition: pubkey.h:1342
size_t MaxRecoverableLength() const
Provides the maximum recoverable length.
Definition: pubkey.h:1350
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
Definition: pubkey.h:1838
virtual unsigned int GetEncodedElementSize(bool reversible) const =0
Retrieves the encoded element's size.
PK_FinalTemplate< TF_DecryptorImpl< SchemeOptions > > Decryptor
implements PK_Decryptor interface
Definition: pubkey.h:2058
Interface for hash functions and data processing part of MACs.
Definition: cryptlib.h:930
Interface for crypto material, such as public and private keys, and crypto parameters.
Definition: cryptlib.h:2042
CofactorMultiplicationOption
Methods for avoiding "Small-Subgroup" attacks on Diffie-Hellman Key Agreement.
Definition: pubkey.h:1880
const DL_GroupParameters< Element > & GetAbstractGroupParameters() const
Retrieves abstract group parameters.
Definition: pubkey.h:1149
DL_GroupParameters< Element > & AccessAbstractGroupParameters()
Retrieves abstract group parameters.
Definition: pubkey.h:1150
void Decode(const byte *input, size_t inputLen, Signedness sign=UNSIGNED)
Decode from big-endian byte array.
Definition: integer.cpp:3314
Discrete Log (DL) encryptor implementation.
Definition: pubkey.h:1804
Multiple precision integer with arithmetic operations.
Cofactor multiplication incompatible with ordinary Diffie-Hellman.
Definition: pubkey.h:1890
static const Integer & Zero()
Integer representing 0.
Definition: integer.cpp:3027
Interface for crypto prameters.
Definition: cryptlib.h:2191
Discrete Log (DL) decryptor implementation.
Definition: pubkey.h:1811
virtual bool IsRandomized() const
Determines if the encryption algorithm is randomized.
Definition: pubkey.h:119
void BERDecode(const byte *input, size_t inputLen)
Decode from BER format.
Definition: integer.cpp:3398
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
Save precomputation for later use.
Definition: pubkey.h:1145
Class file for performing modular arithmetic.
Interface for public keys.
Definition: cryptlib.h:2181
Crypto++ library namespace.
Applies the inverse of the trapdoor function, using random data if required.
Definition: pubkey.h:158
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: pubkey.h:742
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition: pubkey.h:1296
Base implmentation of Discrete Log (DL) group parameters.
Definition: pubkey.h:941
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: pubkey.h:1129
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
Save precomputation for later use.
Definition: pubkey.h:779
Encodes and decodes subjectPublicKeyInfo.
Definition: asn.h:391
Trapdoor function cryptosystem base class.
Definition: pubkey.h:276
virtual DL_GroupParameters< T > & AccessAbstractGroupParameters()=0
Retrieves abstract group parameters.
Input data was received that did not conform to expected format.
Definition: cryptlib.h:191
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
Retrieve previously saved precomputation.
Definition: pubkey.h:773
virtual Element ExponentiateBase(const Integer &exponent) const
Retrieves the subgroup generator.
Definition: pubkey.h:797
PK_FinalTemplate< DL_VerifierImpl< SchemeOptions > > Verifier
implements PK_Verifier interface
Definition: pubkey.h:2110
Discrete Log (DL) signature scheme options.
Definition: pubkey.h:1687
Object Identifier.
Definition: asn.h:165
Interface for message encoding method for public key signature schemes.
Definition: pubkey.h:410
const char * SubgroupOrder()
Integer.
Definition: argnames.h:37
bool SupportsPrecomputation() const
Determines whether the object supports precomputation.
Definition: pubkey.h:1213
Discrete Log (DL) decryptor base implementation.
Definition: pubkey.h:1588
Interface for message encoding method for public key signature schemes.
Definition: pubkey.h:471
virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
Exponentiates an element.
Definition: pubkey.h:807
const char * PublicElement()
Integer.
Definition: argnames.h:36
Interface for DL key agreement algorithms.
Definition: pubkey.h:1272
Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
Applies the trapdoor function.
Definition: pubkey.h:140
unsigned int ByteCount() const
Determines the number of bytes required to represent the Integer.
Definition: integer.cpp:3296
Discrete Log (DL) simple key agreement base implementation.
Definition: pubkey.h:1820
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
Input signature into a message accumulator.
Definition: pubkey.h:1489
STANDARD Standard
see EncryptionStandard for a list of standards
Definition: pubkey.h:2052
virtual void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: cryptlib.h:1201
Interface for message encoding method for public key signature schemes.
Definition: pubkey.h:435
virtual Integer GetGroupOrder() const
Retrieves the order of the group.
Definition: pubkey.h:837
size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
Provides the maximum recoverable length.
Definition: pubkey.h:1357
Interface for retrieving values given their names.
Definition: cryptlib.h:279
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:1954
Trapdoor Function (TF) Signature Scheme.
Definition: pubkey.h:2070
Base class for identifying alogorithm.
Definition: simple.h:38