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