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