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