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