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