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