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