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