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