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