Crypto++ 8.9
Free C++ class library of cryptographic schemes
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 hierarchies 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 /// \return 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 representation after the trapdoor function is applied
82 /// \return the maximum size of a representation 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 /// \return 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 representation after the trapdoor function is applied bound to a public key
90 /// \return the maximum size of a representation 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 /// \return 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 /// \return 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()
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 /// \return 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 /// \return 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 /// \return 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 /// \return 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()
189 /// without the RandomNumberGenerator.
191 {return CalculateInverse(rng, x);}
192
193 /// \brief Determines if the decryption algorithm is randomized
194 /// \return 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 /// \return 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
685/// \sa P1363_KDF2, P1363_MGF1
686/// \since Crypto++ 2.0
687class CRYPTOPP_NO_VTABLE MaskGeneratingFunction
688{
689public:
690 virtual ~MaskGeneratingFunction() {}
691
692 /// \brief Generate and apply mask
693 /// \param hash HashTransformation derived class
694 /// \param output the destination byte array
695 /// \param outputLength the size of the destination byte array
696 /// \param input the message to hash
697 /// \param inputLength the size of the message
698 /// \param mask flag indicating whether to apply the mask
699 virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0;
700};
701
702/// \fn P1363_MGF1KDF2_Common
703/// \brief P1363 mask generation function
704/// \param hash HashTransformation derived class
705/// \param output the destination byte array
706/// \param outputLength the size of the destination byte array
707/// \param input the message to hash
708/// \param inputLength the size of the message
709/// \param derivationParams additional derivation parameters
710/// \param derivationParamsLength the size of the additional derivation parameters
711/// \param mask flag indicating whether to apply the mask
712/// \param counterStart starting counter value used in generation function
713CRYPTOPP_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);
714
715/// \brief P1363 mask generation function
716/// \sa P1363_KDF2, MaskGeneratingFunction
717/// \since Crypto++ 2.0
719{
720public:
721 /// \brief The algorithm name
722 /// \return the algorithm name
723 /// \details StaticAlgorithmName returns the algorithm's name as a static
724 /// member function.
725 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "MGF1";}
726
727 /// \brief P1363 mask generation function
728 /// \param hash HashTransformation derived class
729 /// \param output the destination byte array
730 /// \param outputLength the size of the destination byte array
731 /// \param input the message to hash
732 /// \param inputLength the size of the message
733 /// \param mask flag indicating whether to apply the mask
734 void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const
735 {
736 P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULLPTR, 0, mask, 0);
737 }
738};
739
740// ********************************************************
741
742/// \brief P1363 key derivation function
743/// \tparam H hash function used in the derivation
744/// \sa P1363_MGF1, KeyDerivationFunction, <A
745/// HREF="https://www.cryptopp.com/wiki/P1363_KDF2">P1363_KDF2</A>
746/// on the Crypto++ wiki
747/// \since Crypto++ 2.0
748template <class H>
750{
751public:
752 /// \brief P1363 key derivation function
753 /// \param output the destination byte array
754 /// \param outputLength the size of the destination byte array
755 /// \param input the message to hash
756 /// \param inputLength the size of the message
757 /// \param derivationParams additional derivation parameters
758 /// \param derivationParamsLength the size of the additional derivation parameters
759 /// \details DeriveKey calls P1363_MGF1KDF2_Common
760 static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength)
761 {
762 H h;
763 P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
764 }
765};
766
767// ********************************************************
768
769/// \brief Exception thrown when an invalid group element is encountered
770/// \details Thrown by DecodeElement and AgreeWithStaticPrivateKey
772{
773public:
774 DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {}
775};
776
777/// \brief Interface for Discrete Log (DL) group parameters
778/// \tparam T element in the group
779/// \details The element is usually an Integer, \ref ECP "ECP::Point" or \ref EC2N "EC2N::Point"
780template <class T>
781class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters
782{
784
785public:
786 typedef T Element;
787
788 virtual ~DL_GroupParameters() {}
789
790 DL_GroupParameters() : m_validationLevel(0) {}
791
792 // CryptoMaterial
793 bool Validate(RandomNumberGenerator &rng, unsigned int level) const
794 {
795 if (!GetBasePrecomputation().IsInitialized())
796 return false;
797
798 if (m_validationLevel > level)
799 return true;
800
801 CRYPTOPP_ASSERT(ValidateGroup(rng, level));
802 bool pass = ValidateGroup(rng, level);
803 CRYPTOPP_ASSERT(ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation()));
804 pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
805
806 m_validationLevel = pass ? level+1 : 0;
807
808 return pass;
809 }
810
811 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
812 {
813 return GetValueHelper(this, name, valueType, pValue)
814 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
815 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
816 ;
817 }
818
819 /// \brief Determines whether the object supports precomputation
820 /// \return true if the object supports precomputation, false otherwise
821 /// \sa Precompute()
822 bool SupportsPrecomputation() const {return true;}
823
824 /// \brief Perform precomputation
825 /// \param precomputationStorage the suggested number of objects for the precompute table
826 /// \throw NotImplemented
827 /// \details The exact semantics of Precompute() varies, but it typically means calculate
828 /// a table of n objects that can be used later to speed up computation.
829 /// \details If a derived class does not override Precompute(), then the base class throws
830 /// NotImplemented.
831 /// \sa SupportsPrecomputation(), LoadPrecomputation(), SavePrecomputation()
832 void Precompute(unsigned int precomputationStorage=16)
833 {
834 AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
835 }
836
837 /// \brief Retrieve previously saved precomputation
838 /// \param storedPrecomputation BufferedTransformation with the saved precomputation
839 /// \throw NotImplemented
840 /// \sa SupportsPrecomputation(), Precompute()
841 void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
842 {
843 AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
844 m_validationLevel = 0;
845 }
846
847 /// \brief Save precomputation for later use
848 /// \param storedPrecomputation BufferedTransformation to write the precomputation
849 /// \throw NotImplemented
850 /// \sa SupportsPrecomputation(), Precompute()
851 void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
852 {
853 GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
854 }
855
856 /// \brief Retrieves the subgroup generator
857 /// \return the subgroup generator
858 /// \details The subgroup generator is retrieved from the base precomputation
859 virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
860
861 /// \brief Sets the subgroup generator
862 /// \param base the new subgroup generator
863 /// \details The subgroup generator is set in the base precomputation
864 virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
865
866 /// \brief Exponentiates the base
867 /// \return the element after exponentiation
868 /// \details ExponentiateBase() calls GetBasePrecomputation() and then exponentiates.
869 virtual Element ExponentiateBase(const Integer &exponent) const
870 {
871 return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
872 }
873
874 /// \brief Exponentiates an element
875 /// \param base the base element
876 /// \param exponent the exponent to raise the base
877 /// \return the result of the exponentiation
878 /// \details Internally, ExponentiateElement() calls SimultaneousExponentiate().
879 virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
880 {
881 Element result;
882 SimultaneousExponentiate(&result, base, &exponent, 1);
883 return result;
884 }
885
886 /// \brief Retrieves the group precomputation
887 /// \return a const reference to the group precomputation
889
890 /// \brief Retrieves the group precomputation
891 /// \return a const reference to the group precomputation using a fixed base
893
894 /// \brief Retrieves the group precomputation
895 /// \return a non-const reference to the group precomputation using a fixed base
897
898 /// \brief Retrieves the subgroup order
899 /// \return the order of subgroup generated by the base element
900 virtual const Integer & GetSubgroupOrder() const =0;
901
902 /// \brief Retrieves the maximum exponent for the group
903 /// \return the maximum exponent for the group
904 virtual Integer GetMaxExponent() const =0;
905
906 /// \brief Retrieves the order of the group
907 /// \return the order of the group
908 /// \details Either GetGroupOrder() or GetCofactor() must be overridden in a derived class.
909 virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();}
910
911 /// \brief Retrieves the cofactor
912 /// \return the cofactor
913 /// \details Either GetGroupOrder() or GetCofactor() must be overridden in a derived class.
914 virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();}
915
916 /// \brief Retrieves the encoded element's size
917 /// \param reversible flag indicating the encoding format
918 /// \return encoded element's size, in bytes
919 /// \details The format of the encoded element varies by the underlying type of the element and the
920 /// reversible flag. GetEncodedElementSize() must be implemented in a derived class.
921 /// \sa GetEncodedElementSize(), EncodeElement(), DecodeElement()
922 virtual unsigned int GetEncodedElementSize(bool reversible) const =0;
923
924 /// \brief Encodes the element
925 /// \param reversible flag indicating the encoding format
926 /// \param element reference to the element to encode
927 /// \param encoded destination byte array for the encoded element
928 /// \details EncodeElement() must be implemented in a derived class.
929 /// \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
930 virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0;
931
932 /// \brief Decodes the element
933 /// \param encoded byte array with the encoded element
934 /// \param checkForGroupMembership flag indicating if the element should be validated
935 /// \return Element after decoding
936 /// \details DecodeElement() must be implemented in a derived class.
937 /// \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
938 virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0;
939
940 /// \brief Converts an element to an Integer
941 /// \param element the element to convert to an Integer
942 /// \return Element after converting to an Integer
943 /// \details ConvertElementToInteger() must be implemented in a derived class.
944 virtual Integer ConvertElementToInteger(const Element &element) const =0;
945
946 /// \brief Check the group for errors
947 /// \param rng RandomNumberGenerator for objects which use randomized testing
948 /// \param level level of thoroughness
949 /// \return true if the tests succeed, false otherwise
950 /// \details There are four levels of thoroughness:
951 /// <ul>
952 /// <li>0 - using this object won't cause a crash or exception
953 /// <li>1 - this object will probably function, and encrypt, sign, other operations correctly
954 /// <li>2 - ensure this object will function correctly, and perform reasonable security checks
955 /// <li>3 - perform reasonable security checks, and do checks that may take a long time
956 /// </ul>
957 /// \details Level 0 does not require a RandomNumberGenerator. A NullRNG() can be used for level 0.
958 /// Level 1 may not check for weak keys and such. Levels 2 and 3 are recommended.
959 /// \details ValidateGroup() must be implemented in a derived class.
960 virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0;
961
962 /// \brief Check the element for errors
963 /// \param level level of thoroughness
964 /// \param element element to check
965 /// \param precomp optional pointer to DL_FixedBasePrecomputation
966 /// \return true if the tests succeed, false otherwise
967 /// \details There are four levels of thoroughness:
968 /// <ul>
969 /// <li>0 - using this object won't cause a crash or exception
970 /// <li>1 - this object will probably function, and encrypt, sign, other operations correctly
971 /// <li>2 - ensure this object will function correctly, and perform reasonable security checks
972 /// <li>3 - perform reasonable security checks, and do checks that may take a long time
973 /// </ul>
974 /// \details Level 0 performs group membership checks. Level 1 may not check for weak keys and such.
975 /// Levels 2 and 3 are recommended.
976 /// \details ValidateElement() must be implemented in a derived class.
977 virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0;
978
979 virtual bool FastSubgroupCheckAvailable() const =0;
980
981 /// \brief Determines if an element is an identity
982 /// \param element element to check
983 /// \return true if the element is an identity, false otherwise
984 /// \details The identity element or or neutral element is a special element in a group that leaves
985 /// other elements unchanged when combined with it.
986 /// \details IsIdentity() must be implemented in a derived class.
987 virtual bool IsIdentity(const Element &element) const =0;
988
989 /// \brief Exponentiates a base to multiple exponents
990 /// \param results an array of Elements
991 /// \param base the base to raise to the exponents
992 /// \param exponents an array of exponents
993 /// \param exponentsCount the number of exponents in the array
994 /// \details SimultaneousExponentiate() raises the base to each exponent in the exponents array and stores the
995 /// result at the respective position in the results array.
996 /// \details SimultaneousExponentiate() must be implemented in a derived class.
997 /// \pre <tt>COUNTOF(results) == exponentsCount</tt>
998 /// \pre <tt>COUNTOF(exponents) == exponentsCount</tt>
999 virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0;
1000
1001protected:
1002 void ParametersChanged() {m_validationLevel = 0;}
1003
1004private:
1005 mutable unsigned int m_validationLevel;
1006};
1007
1008/// \brief Base implementation of Discrete Log (DL) group parameters
1009/// \tparam GROUP_PRECOMP group precomputation class
1010/// \tparam BASE_PRECOMP fixed base precomputation class
1011/// \tparam BASE class or type of an element
1012template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<typename GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<typename GROUP_PRECOMP::Element> >
1013class DL_GroupParametersImpl : public BASE
1014{
1015public:
1016 typedef GROUP_PRECOMP GroupPrecomputation;
1017 typedef typename GROUP_PRECOMP::Element Element;
1018 typedef BASE_PRECOMP BasePrecomputation;
1019
1020 virtual ~DL_GroupParametersImpl() {}
1021
1022 /// \brief Retrieves the group precomputation
1023 /// \return a const reference to the group precomputation
1024 const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;}
1025
1026 /// \brief Retrieves the group precomputation
1027 /// \return a const reference to the group precomputation using a fixed base
1029
1030 /// \brief Retrieves the group precomputation
1031 /// \return a non-const reference to the group precomputation using a fixed base
1033
1034protected:
1035 GROUP_PRECOMP m_groupPrecomputation;
1036 BASE_PRECOMP m_gpc;
1037};
1038
1039/// \brief Base class for a Discrete Log (DL) key
1040/// \tparam T class or type of an element
1041/// \details The element is usually an Integer, \ref ECP "ECP::Point" or \ref EC2N "EC2N::Point"
1042template <class T>
1043class CRYPTOPP_NO_VTABLE DL_Key
1044{
1045public:
1046 virtual ~DL_Key() {}
1047
1048 /// \brief Retrieves abstract group parameters
1049 /// \return a const reference to the group parameters
1051 /// \brief Retrieves abstract group parameters
1052 /// \return a non-const reference to the group parameters
1054};
1055
1056/// \brief Interface for Discrete Log (DL) public keys
1057template <class T>
1058class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T>
1059{
1060 typedef DL_PublicKey<T> ThisClass;
1061
1062public:
1063 typedef T Element;
1064
1065 virtual ~DL_PublicKey();
1066
1067 /// \brief Get a named value
1068 /// \param name the name of the object or value to retrieve
1069 /// \param valueType reference to a variable that receives the value
1070 /// \param pValue void pointer to a variable that receives the value
1071 /// \return true if the value was retrieved, false otherwise
1072 /// \details GetVoidValue() retrieves the value of name if it exists.
1073 /// \note GetVoidValue() is an internal function and should be implemented
1074 /// by derived classes. Users should use one of the other functions instead.
1075 /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
1076 /// GetRequiredParameter() and GetRequiredIntParameter()
1077 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1078 {
1079 return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
1080 CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
1081 }
1082
1083 /// \brief Initialize or reinitialize this key
1084 /// \param source NameValuePairs to assign
1085 void AssignFrom(const NameValuePairs &source);
1086
1087 /// \brief Retrieves the public element
1088 /// \return the public element
1089 virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
1090
1091 /// \brief Sets the public element
1092 /// \param y the public element
1093 virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
1094
1095 /// \brief Exponentiates this element
1096 /// \param exponent the exponent to raise the base
1097 /// \return the public element raised to the exponent
1098 virtual Element ExponentiatePublicElement(const Integer &exponent) const
1099 {
1100 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1101 return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
1102 }
1103
1104 /// \brief Exponentiates an element
1105 /// \param baseExp the first exponent
1106 /// \param publicExp the second exponent
1107 /// \return the public element raised to the exponent
1108 /// \details CascadeExponentiateBaseAndPublicElement raises the public element to
1109 /// the base element and precomputation.
1110 virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
1111 {
1112 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1113 return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
1114 }
1115
1116 /// \brief Accesses the public precomputation
1117 /// \details GetPublicPrecomputation returns a const reference, while
1118 /// AccessPublicPrecomputation returns a non-const reference. Must be
1119 /// overridden in derived classes.
1121
1122 /// \brief Accesses the public precomputation
1123 /// \details GetPublicPrecomputation returns a const reference, while
1124 /// AccessPublicPrecomputation returns a non-const reference. Must be
1125 /// overridden in derived classes.
1127};
1128
1129// Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499
1130template<class T>
1132
1133/// \brief Interface for Discrete Log (DL) private keys
1134template <class T>
1135class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T>
1136{
1138
1139public:
1140 typedef T Element;
1141
1142 virtual ~DL_PrivateKey();
1143
1144 /// \brief Initializes a public key from this key
1145 /// \param pub reference to a public key
1147 {
1148 pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters());
1149 pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
1150 }
1151
1152 /// \brief Get a named value
1153 /// \param name the name of the object or value to retrieve
1154 /// \param valueType reference to a variable that receives the value
1155 /// \param pValue void pointer to a variable that receives the value
1156 /// \return true if the value was retrieved, false otherwise
1157 /// \details GetVoidValue() retrieves the value of name if it exists.
1158 /// \note GetVoidValue() is an internal function and should be implemented
1159 /// by derived classes. Users should use one of the other functions instead.
1160 /// \sa GetValue(), GetValueWithDefault(), GetIntValue(), GetIntValueWithDefault(),
1161 /// GetRequiredParameter() and GetRequiredIntParameter()
1162 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1163 {
1164 return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
1165 CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
1166 }
1167
1168 /// \brief Initialize or reinitialize this key
1169 /// \param source NameValuePairs to assign
1170 void AssignFrom(const NameValuePairs &source)
1171 {
1172 this->AccessAbstractGroupParameters().AssignFrom(source);
1173 AssignFromHelper(this, source)
1174 CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
1175 }
1176
1177 /// \brief Retrieves the private exponent
1178 /// \return the private exponent
1179 /// \details Must be overridden in derived classes.
1180 virtual const Integer & GetPrivateExponent() const =0;
1181 /// \brief Sets the private exponent
1182 /// \param x the private exponent
1183 /// \details Must be overridden in derived classes.
1184 virtual void SetPrivateExponent(const Integer &x) =0;
1185};
1186
1187// Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499
1188template<class T>
1190
1191template <class T>
1193{
1194 DL_PrivateKey<T> *pPrivateKey = NULLPTR;
1195 if (source.GetThisPointer(pPrivateKey))
1196 pPrivateKey->MakePublicKey(*this);
1197 else
1198 {
1199 this->AccessAbstractGroupParameters().AssignFrom(source);
1200 AssignFromHelper(this, source)
1201 CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
1202 }
1203}
1204
1205class OID;
1206
1207/// \brief Discrete Log (DL) key base implementation
1208/// \tparam PK Key class
1209/// \tparam GP GroupParameters class
1210/// \tparam O OID class
1211template <class PK, class GP, class O = OID>
1212class DL_KeyImpl : public PK
1213{
1214public:
1215 typedef GP GroupParameters;
1216
1217 virtual ~DL_KeyImpl() {}
1218
1219 O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();}
1220 bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
1221 {AccessGroupParameters().BERDecode(bt); return true;}
1222 bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
1223 {GetGroupParameters().DEREncode(bt); return true;}
1224
1225 const GP & GetGroupParameters() const {return m_groupParameters;}
1226 GP & AccessGroupParameters() {return m_groupParameters;}
1227
1228private:
1229 GP m_groupParameters;
1230};
1231
1232class X509PublicKey;
1233class PKCS8PrivateKey;
1234
1235/// \brief Discrete Log (DL) private key base implementation
1236/// \tparam GP GroupParameters class
1237template <class GP>
1238class DL_PrivateKeyImpl : public DL_PrivateKey<typename GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP>
1239{
1240public:
1241 typedef typename GP::Element Element;
1242
1243 virtual ~DL_PrivateKeyImpl() {}
1244
1245 // GeneratableCryptoMaterial
1246 bool Validate(RandomNumberGenerator &rng, unsigned int level) const
1247 {
1249 bool pass = GetAbstractGroupParameters().Validate(rng, level);
1250
1251 const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
1252 const Integer &x = GetPrivateExponent();
1253
1254 CRYPTOPP_ASSERT(x.IsPositive());
1255 CRYPTOPP_ASSERT(x < q);
1256 pass = pass && x.IsPositive() && x < q;
1257
1258 if (level >= 1)
1259 {
1261 pass = pass && Integer::Gcd(x, q) == Integer::One();
1262 }
1263 return pass;
1264 }
1265
1266 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1267 {
1268 return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable();
1269 }
1270
1271 void AssignFrom(const NameValuePairs &source)
1272 {
1273 AssignFromHelper<DL_PrivateKey<Element> >(this, source);
1274 }
1275
1277 {
1278 if (!params.GetThisObject(this->AccessGroupParameters()))
1279 this->AccessGroupParameters().GenerateRandom(rng, params);
1280 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
1282 }
1283
1284 bool SupportsPrecomputation() const {return true;}
1285
1286 void Precompute(unsigned int precomputationStorage=16)
1287 {AccessAbstractGroupParameters().Precompute(precomputationStorage);}
1288
1289 void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
1290 {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
1291
1292 void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
1293 {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
1294
1295 // DL_Key
1296 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
1297 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
1298
1299 // DL_PrivateKey
1300 const Integer & GetPrivateExponent() const {return m_x;}
1301 void SetPrivateExponent(const Integer &x) {m_x = x;}
1302
1303 // PKCS8PrivateKey
1305 {m_x.BERDecode(bt);}
1308
1309private:
1310 Integer m_x;
1311};
1312
1313template <class BASE, class SIGNATURE_SCHEME>
1315{
1316public:
1318
1319 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
1320 {
1321 BASE::GenerateRandom(rng, params);
1322
1324 {
1325 typename SIGNATURE_SCHEME::Signer signer(*this);
1326 typename SIGNATURE_SCHEME::Verifier verifier(signer);
1327 SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
1328 }
1329 }
1330};
1331
1332/// \brief Discrete Log (DL) public key base implementation
1333/// \tparam GP GroupParameters class
1334template <class GP>
1335class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP>
1336{
1337public:
1338 typedef typename GP::Element Element;
1339
1340 virtual ~DL_PublicKeyImpl();
1341
1342 // CryptoMaterial
1343 bool Validate(RandomNumberGenerator &rng, unsigned int level) const
1344 {
1346 bool pass = GetAbstractGroupParameters().Validate(rng, level);
1348 pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
1349 return pass;
1350 }
1351
1352 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
1353 {
1354 return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable();
1355 }
1356
1357 void AssignFrom(const NameValuePairs &source)
1358 {
1359 AssignFromHelper<DL_PublicKey<Element> >(this, source);
1360 }
1361
1362 bool SupportsPrecomputation() const {return true;}
1363
1364 void Precompute(unsigned int precomputationStorage=16)
1365 {
1366 AccessAbstractGroupParameters().Precompute(precomputationStorage);
1367 AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
1368 }
1369
1370 void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
1371 {
1372 AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
1373 AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
1374 }
1375
1376 void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
1377 {
1378 GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
1379 GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
1380 }
1381
1382 // DL_Key
1383 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
1384 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
1385
1386 // DL_PublicKey
1389
1390 // non-inherited
1391 bool operator==(const DL_PublicKeyImpl<GP> &rhs) const
1392 {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
1393
1394private:
1395 typename GP::BasePrecomputation m_ypc;
1396};
1397
1398// Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499
1399template<class GP>
1401
1402/// \brief Interface for Elgamal-like signature algorithms
1403/// \tparam T Field element type or class
1404/// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
1405template <class T>
1406class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm
1407{
1408public:
1410
1411 /// \brief Sign a message using a private key
1412 /// \param params GroupParameters
1413 /// \param privateKey private key
1414 /// \param k signing exponent
1415 /// \param e encoded message
1416 /// \param r r part of signature
1417 /// \param s s part of signature
1418 virtual void Sign(const DL_GroupParameters<T> &params, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
1419
1420 /// \brief Verify a message using a public key
1421 /// \param params GroupParameters
1422 /// \param publicKey public key
1423 /// \param e encoded message
1424 /// \param r r part of signature
1425 /// \param s s part of signature
1426 virtual bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
1427
1428 /// \brief Recover a Presignature
1429 /// \param params GroupParameters
1430 /// \param publicKey public key
1431 /// \param r r part of signature
1432 /// \param s s part of signature
1433 virtual Integer RecoverPresignature(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
1434 {
1435 CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(publicKey); CRYPTOPP_UNUSED(r); CRYPTOPP_UNUSED(s);
1436 throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");
1437 MAYBE_RETURN(Integer::Zero());
1438 }
1439
1440 /// \brief Retrieve R length
1441 /// \param params GroupParameters
1442 virtual size_t RLen(const DL_GroupParameters<T> &params) const
1443 {return params.GetSubgroupOrder().ByteCount();}
1444
1445 /// \brief Retrieve S length
1446 /// \param params GroupParameters
1447 virtual size_t SLen(const DL_GroupParameters<T> &params) const
1448 {return params.GetSubgroupOrder().ByteCount();}
1449
1450 /// \brief Signature scheme flag
1451 /// \return true if the signature scheme is deterministic, false otherwise
1452 /// \details IsDeterministic() is provided for DL signers. It is used by RFC 6979 signature schemes.
1453 virtual bool IsDeterministic() const
1454 {return false;}
1455};
1456
1457/// \brief Interface for deterministic signers
1458/// \details RFC 6979 signers which generate k based on the encoded message and private key
1459class CRYPTOPP_NO_VTABLE DeterministicSignatureAlgorithm
1460{
1461public:
1463
1464 /// \brief Generate k
1465 /// \param x private key
1466 /// \param q subgroup generator
1467 /// \param e encoded message
1468 virtual Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const =0;
1469};
1470
1471/// \brief Interface for DL key agreement algorithms
1472/// \tparam T Field element type or class
1473/// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
1474/// \sa DLIES, ECIES, ECIES_P1363
1475template <class T>
1476class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm
1477{
1478public:
1479 typedef T Element;
1480
1481 virtual ~DL_KeyAgreementAlgorithm() {}
1482
1483 virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0;
1484 virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0;
1485};
1486
1487/// \brief Interface for key derivation algorithms used in DL cryptosystems
1488/// \tparam T Field element type or class
1489/// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
1490/// \sa DLIES, ECIES, ECIES_P1363
1491template <class T>
1492class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
1493{
1494public:
1495 virtual ~DL_KeyDerivationAlgorithm() {}
1496
1497 virtual bool ParameterSupported(const char *name) const
1498 {CRYPTOPP_UNUSED(name); return false;}
1499 virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0;
1500};
1501
1502/// \brief Interface for symmetric encryption algorithms used in DL cryptosystems
1503/// \sa DLIES, ECIES, ECIES_P1363
1504class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
1505{
1506public:
1508
1509 virtual bool ParameterSupported(const char *name) const
1510 {CRYPTOPP_UNUSED(name); return false;}
1511 virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0;
1512 virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0;
1513 virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0;
1514 virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const =0;
1515 virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const =0;
1516};
1517
1518/// \brief Discrete Log (DL) base interface
1519/// \tparam KI public or private key interface
1520template <class KI>
1521class CRYPTOPP_NO_VTABLE DL_Base
1522{
1523protected:
1524 typedef KI KeyInterface;
1525 typedef typename KI::Element Element;
1526
1527 virtual ~DL_Base() {}
1528
1529 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();}
1530 DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();}
1531
1532 virtual KeyInterface & AccessKeyInterface() =0;
1533 virtual const KeyInterface & GetKeyInterface() const =0;
1534};
1535
1536/// \brief Discrete Log (DL) signature scheme base implementation
1537/// \tparam INTFACE PK_Signer or PK_Verifier derived class
1538/// \tparam KEY_INTFACE DL_Base key base used in the scheme
1539/// \details DL_SignatureSchemeBase provides common functions for signers and verifiers.
1540/// DL_Base<DL_PrivateKey> is used for signers, and DL_Base<DL_PublicKey> is used for verifiers.
1541template <class INTFACE, class KEY_INTFACE>
1542class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTFACE, public DL_Base<KEY_INTFACE>
1543{
1544public:
1545 virtual ~DL_SignatureSchemeBase() {}
1546
1547 /// \brief Provides the signature length
1548 /// \return signature length, in bytes
1549 /// \details SignatureLength returns the size required for <tt>r+s</tt>.
1550 size_t SignatureLength() const
1551 {
1552 return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
1553 + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
1554 }
1555
1556 /// \brief Provides the maximum recoverable length
1557 /// \return maximum recoverable length, in bytes
1559 {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
1560
1561 /// \brief Provides the maximum recoverable length
1562 /// \param signatureLength the size of the signature
1563 /// \return maximum recoverable length based on signature length, in bytes
1564 /// \details this function is not implemented and always returns 0.
1565 size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
1566 {CRYPTOPP_UNUSED(signatureLength); CRYPTOPP_ASSERT(false); return 0;} // TODO
1567
1568 /// \brief Determines if the scheme is probabilistic
1569 /// \return true if the scheme is probabilistic, false otherwise
1570 bool IsProbabilistic() const
1571 {return true;}
1572
1573 /// \brief Determines if the scheme has non-recoverable part
1574 /// \return true if the message encoding has a non-recoverable part, false otherwise.
1576 {return GetMessageEncodingInterface().AllowNonrecoverablePart();}
1577
1578 /// \brief Determines if the scheme allows recoverable part first
1579 /// \return true if the message encoding allows the recoverable part, false otherwise.
1581 {return GetMessageEncodingInterface().RecoverablePartFirst();}
1582
1583protected:
1584 size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
1585 size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
1586
1587 // true if the scheme conforms to RFC 6979
1588 virtual bool IsDeterministic() const {return false;}
1589
1590 virtual const DL_ElgamalLikeSignatureAlgorithm<typename KEY_INTFACE::Element> & GetSignatureAlgorithm() const =0;
1591 virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
1592 virtual HashIdentifier GetHashIdentifier() const =0;
1593 virtual size_t GetDigestSize() const =0;
1594};
1595
1596/// \brief Discrete Log (DL) signature scheme signer base implementation
1597/// \tparam T Field element type or class
1598/// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
1599template <class T>
1600class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
1601{
1602public:
1603 virtual ~DL_SignerBase() {}
1604
1605 /// \brief Testing interface
1606 /// \param k Integer
1607 /// \param e Integer
1608 /// \param r Integer
1609 /// \param s Integer
1610 void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
1611 {
1612 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1613 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1614 const DL_PrivateKey<T> &key = this->GetKeyInterface();
1615
1616 r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1617 alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1618 }
1619
1620 void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
1621 {
1622 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1623 ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
1624 this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
1625 recoverableMessage, recoverableMessageLength,
1626 ma.m_presignature, ma.m_presignature.size(),
1627 ma.m_semisignature);
1628 }
1629
1630 size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
1631 {
1632 this->GetMaterial().DoQuickSanityCheck();
1633
1634 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1635 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1636 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1637 const DL_PrivateKey<T> &key = this->GetKeyInterface();
1638
1639 SecByteBlock representative(this->MessageRepresentativeLength());
1640 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1641 rng,
1642 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1643 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1644 representative, this->MessageRepresentativeBitLength());
1645 ma.m_empty = true;
1646 Integer e(representative, representative.size());
1647
1648 // hash message digest into random number k to prevent reusing the same k on
1649 // different messages after virtual machine rollback
1650 if (rng.CanIncorporateEntropy())
1651 rng.IncorporateEntropy(representative, representative.size());
1652
1653 Integer k, ks;
1654 const Integer& q = params.GetSubgroupOrder();
1655 if (alg.IsDeterministic())
1656 {
1657 const Integer& x = key.GetPrivateExponent();
1658 const DeterministicSignatureAlgorithm& det = dynamic_cast<const DeterministicSignatureAlgorithm&>(alg);
1659 k = det.GenerateRandom(x, q, e);
1660 }
1661 else
1662 {
1663 k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
1664 }
1665
1666 // Due to timing attack on nonce length by Jancar
1667 // https://github.com/weidai11/cryptopp/issues/869
1668 ks = k + q;
1669 if (ks.BitCount() == q.BitCount()) {
1670 ks += q;
1671 }
1672
1673 Integer r, s;
1674 r = params.ConvertElementToInteger(params.ExponentiateBase(ks));
1675 alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1676
1677 /*
1678 Integer r, s;
1679 if (this->MaxRecoverableLength() > 0)
1680 r.Decode(ma.m_semisignature, ma.m_semisignature.size());
1681 else
1682 r.Decode(ma.m_presignature, ma.m_presignature.size());
1683 alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s);
1684 */
1685
1686 const size_t rLen = alg.RLen(params);
1687 r.Encode(signature, rLen);
1688 s.Encode(signature+rLen, alg.SLen(params));
1689
1690 if (restart)
1691 RestartMessageAccumulator(rng, ma);
1692
1693 return this->SignatureLength();
1694 }
1695
1696protected:
1697 void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
1698 {
1699 // k needs to be generated before hashing for signature schemes with recovery
1700 // but to defend against VM rollbacks we need to generate k after hashing.
1701 // so this code is commented out, since no DL-based signature scheme with recovery
1702 // has been implemented in Crypto++ anyway
1703 /*
1704 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1705 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1706 ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
1707 ma.m_presignature.New(params.GetEncodedElementSize(false));
1708 params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size());
1709 */
1710 CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(ma);
1711 }
1712};
1713
1714/// \brief Discret Log (DL) Verifier base class
1715/// \tparam T Field element type or class
1716/// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
1717template <class T>
1718class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
1719{
1720public:
1721 virtual ~DL_VerifierBase() {}
1722
1723 void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
1724 {
1725 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1726 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1727 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1728
1729 // Validation due to https://github.com/weidai11/cryptopp/issues/981
1730 // We allow a caller to provide R and S in oversized buffer. R and S
1731 // are read based on the field element size, and not the buffer size.
1732 const size_t rLen = alg.RLen(params);
1733 const size_t sLen = alg.SLen(params);
1734 CRYPTOPP_ASSERT(signatureLength >= rLen + sLen);
1735 if (signatureLength < rLen + sLen)
1736 throw InvalidDataFormat("DL_VerifierBase: signature length is not valid.");
1737
1738 ma.m_semisignature.Assign(signature, rLen);
1739 ma.m_s.Decode(signature+rLen, sLen);
1740
1741 this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
1742 }
1743
1744 bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
1745 {
1746 this->GetMaterial().DoQuickSanityCheck();
1747
1748 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1749 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1750 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1751 const DL_PublicKey<T> &key = this->GetKeyInterface();
1752
1753 SecByteBlock representative(this->MessageRepresentativeLength());
1754 this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1755 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1756 representative, this->MessageRepresentativeBitLength());
1757 ma.m_empty = true;
1758 Integer e(representative, representative.size());
1759
1760 Integer r(ma.m_semisignature, ma.m_semisignature.size());
1761 return alg.Verify(params, key, e, r, ma.m_s);
1762 }
1763
1764 DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
1765 {
1766 this->GetMaterial().DoQuickSanityCheck();
1767
1768 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1769 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
1770 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1771 const DL_PublicKey<T> &key = this->GetKeyInterface();
1772
1773 SecByteBlock representative(this->MessageRepresentativeLength());
1774 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
1775 NullRNG(),
1776 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1777 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
1778 representative, this->MessageRepresentativeBitLength());
1779 ma.m_empty = true;
1780 Integer e(representative, representative.size());
1781
1782 ma.m_presignature.New(params.GetEncodedElementSize(false));
1783 Integer r(ma.m_semisignature, ma.m_semisignature.size());
1784 alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
1785
1786 return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
1787 ma.AccessHash(), this->GetHashIdentifier(),
1788 ma.m_presignature, ma.m_presignature.size(),
1789 ma.m_semisignature, ma.m_semisignature.size(),
1790 recoveredMessage);
1791 }
1792};
1793
1794/// \brief Discrete Log (DL) cryptosystem base implementation
1795/// \tparam PK field element type
1796/// \tparam KI public or private key interface
1797template <class PK, class KI>
1798class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
1799{
1800public:
1801 typedef typename DL_Base<KI>::Element Element;
1802
1803 virtual ~DL_CryptoSystemBase() {}
1804
1805 size_t MaxPlaintextLength(size_t ciphertextLength) const
1806 {
1807 unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
1808 return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
1809 }
1810
1811 size_t CiphertextLength(size_t plaintextLength) const
1812 {
1813 size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
1814 return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
1815 }
1816
1817 bool ParameterSupported(const char *name) const
1818 {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
1819
1820protected:
1821 virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
1822 virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
1823 virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
1824};
1825
1826/// \brief Discrete Log (DL) decryptor base implementation
1827/// \tparam T Field element type or class
1828/// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
1829template <class T>
1830class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
1831{
1832public:
1833 typedef T Element;
1834
1835 virtual ~DL_DecryptorBase() {}
1836
1837 DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
1838 {
1839 try
1840 {
1841 CRYPTOPP_UNUSED(rng);
1842 const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
1843 const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
1844 const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
1845 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1846 const DL_PrivateKey<T> &key = this->GetKeyInterface();
1847
1848 Element q = params.DecodeElement(ciphertext, true);
1849 size_t elementSize = params.GetEncodedElementSize(true);
1850 ciphertext += elementSize;
1851 ciphertextLength -= elementSize;
1852
1853 Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
1854
1855 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
1856 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1857
1858 return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
1859 }
1860 catch (DL_BadElement &)
1861 {
1862 return DecodingResult();
1863 }
1864 }
1865};
1866
1867/// \brief Discrete Log (DL) encryptor base implementation
1868/// \tparam T Field element type or class
1869/// \details Field element <tt>T</tt> can be Integer, ECP or EC2N.
1870template <class T>
1871class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
1872{
1873public:
1874 typedef T Element;
1875
1876 virtual ~DL_EncryptorBase() {}
1877
1878 void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const
1879 {
1880 const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
1881 const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
1882 const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
1883 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
1884 const DL_PublicKey<T> &key = this->GetKeyInterface();
1885
1886 Integer x(rng, Integer::One(), params.GetMaxExponent());
1887 Element q = params.ExponentiateBase(x);
1888 params.EncodeElement(true, q, ciphertext);
1889 unsigned int elementSize = params.GetEncodedElementSize(true);
1890 ciphertext += elementSize;
1891
1892 Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
1893
1894 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
1895 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
1896
1897 encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
1898 }
1899};
1900
1901/// \brief Discrete Log (DL) scheme options
1902/// \tparam T1 algorithm information
1903/// \tparam T2 group parameters for the scheme
1904template <class T1, class T2>
1906{
1907 typedef T1 AlgorithmInfo;
1908 typedef T2 GroupParameters;
1909 typedef typename GroupParameters::Element Element;
1910};
1911
1912/// \brief Discrete Log (DL) key options
1913/// \tparam T1 algorithm information
1914/// \tparam T2 keys used in the scheme
1915template <class T1, class T2>
1916struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
1917{
1918 typedef T2 Keys;
1919 typedef typename Keys::PrivateKey PrivateKey;
1920 typedef typename Keys::PublicKey PublicKey;
1921};
1922
1923/// \brief Discrete Log (DL) signature scheme options
1924/// \tparam T1 algorithm information
1925/// \tparam T2 keys used in the scheme
1926/// \tparam T3 signature algorithm
1927/// \tparam T4 message encoding method
1928/// \tparam T5 hash function
1929template <class T1, class T2, class T3, class T4, class T5>
1931{
1932 typedef T3 SignatureAlgorithm;
1933 typedef T4 MessageEncodingMethod;
1934 typedef T5 HashFunction;
1935};
1936
1937/// \brief Discrete Log (DL) crypto scheme options
1938/// \tparam T1 algorithm information
1939/// \tparam T2 keys used in the scheme
1940/// \tparam T3 key agreement algorithm
1941/// \tparam T4 key derivation algorithm
1942/// \tparam T5 symmetric encryption algorithm
1943template <class T1, class T2, class T3, class T4, class T5>
1945{
1946 typedef T3 KeyAgreementAlgorithm;
1947 typedef T4 KeyDerivationAlgorithm;
1948 typedef T5 SymmetricEncryptionAlgorithm;
1949};
1950
1951/// \brief Discrete Log (DL) base object implementation
1952/// \tparam BASE TODO
1953/// \tparam SCHEME_OPTIONS options for the scheme
1954/// \tparam KEY key used in the scheme
1955template <class BASE, class SCHEME_OPTIONS, class KEY>
1956class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
1957{
1958public:
1959 typedef SCHEME_OPTIONS SchemeOptions;
1960 typedef typename KEY::Element Element;
1961
1962 virtual ~DL_ObjectImplBase() {}
1963
1964 PrivateKey & AccessPrivateKey() {return m_key;}
1965 PublicKey & AccessPublicKey() {return m_key;}
1966
1967 // KeyAccessor
1968 const KEY & GetKey() const {return m_key;}
1969 KEY & AccessKey() {return m_key;}
1970
1971protected:
1972 typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
1973 const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
1974
1975 // for signature scheme
1976 HashIdentifier GetHashIdentifier() const
1977 {
1978 typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
1979 return HashLookup::template HashIdentifierLookup2<typename SchemeOptions::HashFunction>::Lookup();
1980 }
1981 size_t GetDigestSize() const
1982 {
1983 typedef typename SchemeOptions::HashFunction H;
1984 return H::DIGESTSIZE;
1985 }
1986
1987private:
1988 KEY m_key;
1989};
1990
1991/// \brief Discrete Log (DL) object implementation
1992/// \tparam BASE TODO
1993/// \tparam SCHEME_OPTIONS options for the scheme
1994/// \tparam KEY key used in the scheme
1995template <class BASE, class SCHEME_OPTIONS, class KEY>
1996class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
1997{
1998public:
1999 typedef typename KEY::Element Element;
2000
2001 virtual ~DL_ObjectImpl() {}
2002
2003protected:
2004 const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
2006 const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
2008 const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
2010 const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
2012 HashIdentifier GetHashIdentifier() const
2013 {return HashIdentifier();}
2014 const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
2016};
2017
2018/// \brief Discrete Log (DL) signer implementation
2019/// \tparam SCHEME_OPTIONS options for the scheme
2020template <class SCHEME_OPTIONS>
2021class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
2022{
2023public:
2024 PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
2025 {
2027 this->RestartMessageAccumulator(rng, *p);
2028 return p.release();
2029 }
2030};
2031
2032/// \brief Discrete Log (DL) verifier implementation
2033/// \tparam SCHEME_OPTIONS options for the scheme
2034template <class SCHEME_OPTIONS>
2035class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
2036{
2037public:
2038 PK_MessageAccumulator * NewVerificationAccumulator() const
2039 {
2041 }
2042};
2043
2044/// \brief Discrete Log (DL) encryptor implementation
2045/// \tparam SCHEME_OPTIONS options for the scheme
2046template <class SCHEME_OPTIONS>
2047class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
2048{
2049};
2050
2051/// \brief Discrete Log (DL) decryptor implementation
2052/// \tparam SCHEME_OPTIONS options for the scheme
2053template <class SCHEME_OPTIONS>
2054class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
2055{
2056};
2057
2058// ********************************************************
2059
2060/// \brief Discrete Log (DL) simple key agreement base implementation
2061/// \tparam T class or type
2062template <class T>
2064{
2065public:
2066 typedef T Element;
2067
2069
2070 CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
2071 unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
2072 unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
2073 unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
2074
2075 void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
2076 {
2077 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
2078 x.Encode(privateKey, PrivateKeyLength());
2079 }
2080
2081 void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
2082 {
2083 CRYPTOPP_UNUSED(rng);
2084 const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
2085 Integer x(privateKey, PrivateKeyLength());
2086 Element y = params.ExponentiateBase(x);
2087 params.EncodeElement(true, y, publicKey);
2088 }
2089
2090 bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
2091 {
2092 try
2093 {
2094 const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
2095 Integer x(privateKey, PrivateKeyLength());
2096 Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
2097
2098 Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
2099 GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
2100 params.EncodeElement(false, z, agreedValue);
2101 }
2102 catch (DL_BadElement &)
2103 {
2104 return false;
2105 }
2106 return true;
2107 }
2108
2109 /// \brief Retrieves a reference to the group generator
2110 /// \return const reference to the group generator
2111 const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
2112
2113protected:
2114 virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
2115 virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
2116 const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
2117};
2118
2119/// \brief Methods for avoiding "Small-Subgroup" attacks on Diffie-Hellman Key Agreement
2120/// \details Additional methods exist and include public key validation and choice of prime p.
2121/// \sa <A HREF="http://tools.ietf.org/html/rfc2785">Methods for Avoiding the "Small-Subgroup" Attacks on the
2122/// Diffie-Hellman Key Agreement Method for S/MIME</A>
2124 /// \brief No cofactor multiplication applied
2126 /// \brief Cofactor multiplication compatible with ordinary Diffie-Hellman
2127 /// \details Modifies the computation of ZZ by including j (the cofactor) in the computations and is
2128 /// compatible with ordinary Diffie-Hellman.
2130 /// \brief Cofactor multiplication incompatible with ordinary Diffie-Hellman
2131 /// \details Modifies the computation of ZZ by including j (the cofactor) in the computations but is
2132 /// not compatible with ordinary Diffie-Hellman.
2134
2138
2139/// \brief Diffie-Hellman key agreement algorithm
2140template <class ELEMENT, class COFACTOR_OPTION>
2142{
2143public:
2144 typedef ELEMENT Element;
2145
2146 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName()
2147 {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
2148
2149 virtual ~DL_KeyAgreementAlgorithm_DH() {}
2150
2151 Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
2152 {
2153 return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
2154 COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
2155 }
2156
2157 Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
2158 {
2159 if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
2160 {
2161 const Integer &k = params.GetCofactor();
2162 return params.ExponentiateElement(publicElement,
2163 ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
2164 }
2165 else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
2166 return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
2167 else
2168 {
2169 CRYPTOPP_ASSERT(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
2170
2171 if (!validateOtherPublicKey)
2172 return params.ExponentiateElement(publicElement, privateExponent);
2173
2174 if (params.FastSubgroupCheckAvailable())
2175 {
2176 if (!params.ValidateElement(2, publicElement, NULLPTR))
2177 throw DL_BadElement();
2178 return params.ExponentiateElement(publicElement, privateExponent);
2179 }
2180 else
2181 {
2182 const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
2183 Element r[2];
2184 params.SimultaneousExponentiate(r, publicElement, e, 2);
2185 if (!params.IsIdentity(r[0]))
2186 throw DL_BadElement();
2187 return r[1];
2188 }
2189 }
2190 }
2191};
2192
2193// ********************************************************
2194
2195/// \brief Template implementing constructors for public key algorithm classes
2196template <class BASE>
2197class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
2198{
2199public:
2200 PK_FinalTemplate() {}
2201
2203 {this->AccessKey().AssignFrom(key);}
2204
2206 {this->AccessKey().BERDecode(bt);}
2207
2208 PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
2209 {this->AccessKey().AssignFrom(algorithm.GetMaterial());}
2210
2211 PK_FinalTemplate(const Integer &v1)
2212 {this->AccessKey().Initialize(v1);}
2213
2214 template <class T1, class T2>
2215 PK_FinalTemplate(const T1 &v1, const T2 &v2)
2216 {this->AccessKey().Initialize(v1, v2);}
2217
2218 template <class T1, class T2, class T3>
2219 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
2220 {this->AccessKey().Initialize(v1, v2, v3);}
2221
2222 template <class T1, class T2, class T3, class T4>
2223 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
2224 {this->AccessKey().Initialize(v1, v2, v3, v4);}
2225
2226 template <class T1, class T2, class T3, class T4, class T5>
2227 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
2228 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
2229
2230 template <class T1, class T2, class T3, class T4, class T5, class T6>
2231 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
2232 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
2233
2234 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
2235 PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
2236 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
2237
2238 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
2239 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)
2240 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
2241
2242 template <class T1, class T2>
2243 PK_FinalTemplate(T1 &v1, const T2 &v2)
2244 {this->AccessKey().Initialize(v1, v2);}
2245
2246 template <class T1, class T2, class T3>
2247 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
2248 {this->AccessKey().Initialize(v1, v2, v3);}
2249
2250 template <class T1, class T2, class T3, class T4>
2251 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
2252 {this->AccessKey().Initialize(v1, v2, v3, v4);}
2253
2254 template <class T1, class T2, class T3, class T4, class T5>
2255 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
2256 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
2257
2258 template <class T1, class T2, class T3, class T4, class T5, class T6>
2259 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
2260 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
2261
2262 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
2263 PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
2264 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
2265
2266 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
2267 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)
2268 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
2269};
2270
2271/// \brief Base class for public key encryption standard classes.
2272/// \details These classes are used to select from variants of algorithms.
2273/// Not all standards apply to all algorithms.
2275
2276/// \brief Base class for public key signature standard classes.
2277/// \details These classes are used to select from variants of algorithms.
2278/// Not all standards apply to all algorithms.
2280
2281/// \brief Trapdoor Function (TF) encryption scheme
2282/// \tparam STANDARD standard
2283/// \tparam KEYS keys used in the encryption scheme
2284/// \tparam ALG_INFO algorithm information
2285template <class KEYS, class STANDARD, class ALG_INFO>
2286class TF_ES;
2287
2288template <class KEYS, class STANDARD, class ALG_INFO = TF_ES<KEYS, STANDARD, int> >
2289class TF_ES : public KEYS
2290{
2291 typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
2292
2293public:
2294 /// see EncryptionStandard for a list of standards
2295 typedef STANDARD Standard;
2297
2298 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
2299
2300 /// implements PK_Decryptor interface
2302 /// implements PK_Encryptor interface
2304};
2305
2306/// \brief Trapdoor Function (TF) Signature Scheme
2307/// \tparam STANDARD standard
2308/// \tparam H hash function
2309/// \tparam KEYS keys used in the signature scheme
2310/// \tparam ALG_INFO algorithm information
2311template <class KEYS, class STANDARD, class H, class ALG_INFO>
2312class TF_SS;
2313
2314template <class KEYS, class STANDARD, class H, class ALG_INFO = TF_SS<KEYS, STANDARD, H, int> >
2315class TF_SS : public KEYS
2316{
2317public:
2318 /// see SignatureStandard for a list of standards
2319 typedef STANDARD Standard;
2320 typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
2322
2323 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
2324
2325 /// implements PK_Signer interface
2327 /// implements PK_Verifier interface
2329};
2330
2331/// \brief Discrete Log (DL) signature scheme
2332/// \tparam KEYS keys used in the signature scheme
2333/// \tparam SA signature algorithm
2334/// \tparam MEM message encoding method
2335/// \tparam H hash function
2336/// \tparam ALG_INFO algorithm information
2337template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
2338class DL_SS;
2339
2340template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
2341class DL_SS : public KEYS
2342{
2344
2345public:
2346 static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
2347
2348 /// implements PK_Signer interface
2350 /// implements PK_Verifier interface
2352};
2353
2354/// \brief Discrete Log (DL) encryption scheme
2355/// \tparam KEYS keys used in the encryption scheme
2356/// \tparam AA key agreement algorithm
2357/// \tparam DA key derivation algorithm
2358/// \tparam EA encryption algorithm
2359/// \tparam ALG_INFO algorithm information
2360template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
2361class DL_ES : public KEYS
2362{
2364
2365public:
2366 /// implements PK_Decryptor interface
2368 /// implements PK_Encryptor interface
2370};
2371
2372NAMESPACE_END
2373
2374#if CRYPTOPP_MSC_VERSION
2375# pragma warning(pop)
2376#endif
2377
2378#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:40
Interface for asymmetric algorithms.
Definition cryptlib.h:2565
Interface for buffered transformations.
Definition cryptlib.h:1657
Interface for crypto material.
Definition cryptlib.h:2395
Interface for crypto parameters.
Definition cryptlib.h:2551
Exception thrown when an invalid group element is encountered.
Definition pubkey.h:772
Discrete Log (DL) base interface.
Definition pubkey.h:1522
Discrete Log (DL) cryptosystem base implementation.
Definition pubkey.h:1799
Discrete Log (DL) decryptor base implementation.
Definition pubkey.h:1831
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:1837
Discrete Log (DL) decryptor implementation.
Definition pubkey.h:2055
Discrete Log (DL) encryption scheme.
Definition pubkey.h:2362
PK_FinalTemplate< DL_DecryptorImpl< SchemeOptions > > Decryptor
implements PK_Decryptor interface
Definition pubkey.h:2367
PK_FinalTemplate< DL_EncryptorImpl< SchemeOptions > > Encryptor
implements PK_Encryptor interface
Definition pubkey.h:2369
Interface for Elgamal-like signature algorithms.
Definition pubkey.h:1407
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:1453
virtual size_t SLen(const DL_GroupParameters< T > &params) const
Retrieve S length.
Definition pubkey.h:1447
virtual size_t RLen(const DL_GroupParameters< T > &params) const
Retrieve R length.
Definition pubkey.h:1442
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:1433
Discrete Log (DL) encryptor base implementation.
Definition pubkey.h:1872
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:1878
Discrete Log (DL) encryptor implementation.
Definition pubkey.h:2048
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:782
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
Save precomputation for later use.
Definition pubkey.h:851
virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
Exponentiates an element.
Definition pubkey.h:879
bool SupportsPrecomputation() const
Determines whether the object supports precomputation.
Definition pubkey.h:822
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition pubkey.h:811
virtual void SetSubgroupGenerator(const Element &base)
Sets the subgroup generator.
Definition pubkey.h:864
virtual Integer GetCofactor() const
Retrieves the cofactor.
Definition pubkey.h:914
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:793
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:859
virtual Integer GetGroupOrder() const
Retrieves the order of the group.
Definition pubkey.h:909
void Precompute(unsigned int precomputationStorage=16)
Perform precomputation.
Definition pubkey.h:832
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:841
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:869
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:1014
DL_FixedBasePrecomputation< Element > & AccessBasePrecomputation()
Retrieves the group precomputation.
Definition pubkey.h:1032
const DL_FixedBasePrecomputation< Element > & GetBasePrecomputation() const
Retrieves the group precomputation.
Definition pubkey.h:1028
const DL_GroupPrecomputation< Element > & GetGroupPrecomputation() const
Retrieves the group precomputation.
Definition pubkey.h:1024
DL_GroupPrecomputation interface.
Definition eprecomp.h:20
Diffie-Hellman key agreement algorithm.
Definition pubkey.h:2142
Interface for DL key agreement algorithms.
Definition pubkey.h:1477
Interface for key derivation algorithms used in DL cryptosystems.
Definition pubkey.h:1493
Base class for a Discrete Log (DL) key.
Definition pubkey.h:1044
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:1213
Discrete Log (DL) base object implementation.
Definition pubkey.h:1957
Discrete Log (DL) object implementation.
Definition pubkey.h:1997
Interface for Discrete Log (DL) private keys.
Definition pubkey.h:1136
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:1162
void MakePublicKey(DL_PublicKey< T > &pub) const
Initializes a public key from this key.
Definition pubkey.h:1146
virtual void SetPrivateExponent(const Integer &x)=0
Sets the private exponent.
void AssignFrom(const NameValuePairs &source)
Initialize or reinitialize this key.
Definition pubkey.h:1170
Discrete Log (DL) private key base implementation.
Definition pubkey.h:1239
void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t)
Decode privateKey part of privateKeyInfo.
Definition pubkey.h:1304
const DL_GroupParameters< Element > & GetAbstractGroupParameters() const
Retrieves abstract group parameters.
Definition pubkey.h:1296
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition pubkey.h:1271
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition pubkey.h:1266
DL_GroupParameters< Element > & AccessAbstractGroupParameters()
Retrieves abstract group parameters.
Definition pubkey.h:1297
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition pubkey.h:1246
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
Save precomputation for later use.
Definition pubkey.h:1292
bool SupportsPrecomputation() const
Determines whether the object supports precomputation.
Definition pubkey.h:1284
const Integer & GetPrivateExponent() const
Retrieves the private exponent.
Definition pubkey.h:1300
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition pubkey.h:1276
void Precompute(unsigned int precomputationStorage=16)
Perform precomputation.
Definition pubkey.h:1286
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
Definition pubkey.h:1306
void SetPrivateExponent(const Integer &x)
Sets the private exponent.
Definition pubkey.h:1301
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
Retrieve previously saved precomputation.
Definition pubkey.h:1289
Interface for Discrete Log (DL) public keys.
Definition pubkey.h:1059
virtual DL_FixedBasePrecomputation< T > & AccessPublicPrecomputation()=0
Accesses the public precomputation.
virtual const Element & GetPublicElement() const
Retrieves the public element.
Definition pubkey.h:1089
virtual Element ExponentiatePublicElement(const Integer &exponent) const
Exponentiates this element.
Definition pubkey.h:1098
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:1192
virtual void SetPublicElement(const Element &y)
Sets the public element.
Definition pubkey.h:1093
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition pubkey.h:1077
virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
Exponentiates an element.
Definition pubkey.h:1110
Discrete Log (DL) public key base implementation.
Definition pubkey.h:1336
bool SupportsPrecomputation() const
Determines whether the object supports precomputation.
Definition pubkey.h:1362
DL_FixedBasePrecomputation< Element > & AccessPublicPrecomputation()
Accesses the public precomputation.
Definition pubkey.h:1388
const DL_GroupParameters< Element > & GetAbstractGroupParameters() const
Retrieves abstract group parameters.
Definition pubkey.h:1383
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition pubkey.h:1352
void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
Retrieve previously saved precomputation.
Definition pubkey.h:1370
void Precompute(unsigned int precomputationStorage=16)
Perform precomputation.
Definition pubkey.h:1364
const DL_FixedBasePrecomputation< Element > & GetPublicPrecomputation() const
Accesses the public precomputation.
Definition pubkey.h:1387
DL_GroupParameters< Element > & AccessAbstractGroupParameters()
Retrieves abstract group parameters.
Definition pubkey.h:1384
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition pubkey.h:1343
void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
Save precomputation for later use.
Definition pubkey.h:1376
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition pubkey.h:1357
Discrete Log (DL) signature scheme.
Definition pubkey.h:2342
PK_FinalTemplate< DL_SignerImpl< SchemeOptions > > Signer
implements PK_Signer interface
Definition pubkey.h:2349
PK_FinalTemplate< DL_VerifierImpl< SchemeOptions > > Verifier
implements PK_Verifier interface
Definition pubkey.h:2351
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:1543
size_t MaxRecoverableLength() const
Provides the maximum recoverable length.
Definition pubkey.h:1558
bool RecoverablePartFirst() const
Determines if the scheme allows recoverable part first.
Definition pubkey.h:1580
bool AllowNonrecoverablePart() const
Determines if the scheme has non-recoverable part.
Definition pubkey.h:1575
size_t SignatureLength() const
Provides the signature length.
Definition pubkey.h:1550
size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
Provides the maximum recoverable length.
Definition pubkey.h:1565
bool IsProbabilistic() const
Determines if the scheme is probabilistic.
Definition pubkey.h:1570
Discrete Log (DL) signature scheme signer base implementation.
Definition pubkey.h:1601
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
Sign and restart messageAccumulator.
Definition pubkey.h:1630
void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
Testing interface.
Definition pubkey.h:1610
void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
Input a recoverable message to an accumulator.
Definition pubkey.h:1620
Discrete Log (DL) signer implementation.
Definition pubkey.h:2022
Discrete Log (DL) simple key agreement base implementation.
Definition pubkey.h:2064
unsigned int AgreedValueLength() const
Provides the size of the agreed value.
Definition pubkey.h:2071
CryptoParameters & AccessCryptoParameters()
Retrieves a reference to Crypto Parameters.
Definition pubkey.h:2070
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Derive agreed value.
Definition pubkey.h:2090
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate private key in this domain.
Definition pubkey.h:2075
const Element & GetGenerator() const
Retrieves a reference to the group generator.
Definition pubkey.h:2111
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
Definition pubkey.h:2081
unsigned int PrivateKeyLength() const
Provides the size of the private key.
Definition pubkey.h:2072
unsigned int PublicKeyLength() const
Provides the size of the public key.
Definition pubkey.h:2073
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition pubkey.h:1505
Discret Log (DL) Verifier base class.
Definition pubkey.h:1719
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
Recover a message from its signature.
Definition pubkey.h:1764
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
Input signature into a message accumulator.
Definition pubkey.h:1723
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
Definition pubkey.h:1744
Discrete Log (DL) verifier implementation.
Definition pubkey.h:2036
Interface for deterministic signers.
Definition pubkey.h:1460
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:1118
Multiple precision integer with arithmetic operations.
Definition integer.h:50
void DEREncode(BufferedTransformation &bt) const
Encode in DER format.
static const Integer & Zero()
Integer representing 0.
void Randomize(RandomNumberGenerator &rng, size_t bitCount)
Set this Integer to random integer.
void BERDecode(const byte *input, size_t inputLen)
Decode from BER format.
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
void Decode(const byte *input, size_t inputLen, Signedness sign=UNSIGNED)
Decode from big-endian byte array.
static Integer Gcd(const Integer &a, const Integer &n)
Calculate greatest common divisor.
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
static const Integer & One()
Integer representing 1.
Input data was received that did not conform to expected format.
Definition cryptlib.h:218
InvalidDataFormat(const std::string &s)
Construct an InvalidDataFormat.
Definition cryptlib.h:223
Interface for key agreement algorithms.
Definition cryptlib.h:2643
Mask generation function interface.
Definition pubkey.h:688
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:44
const Integer & Divide(const Integer &a, const Integer &b) const
Divides elements in the ring.
Definition modarith.h:218
Interface for retrieving values given their names.
Definition cryptlib.h:327
bool GetThisObject(T &object) const
Get a copy of this object or subobject.
Definition cryptlib.h:362
bool GetThisPointer(T *&ptr) const
Get a pointer to this object.
Definition cryptlib.h:371
A method was called which was not implemented.
Definition cryptlib.h:238
Object Identifier.
Definition asn.h:265
Uses encapsulation to hide an object in derived classes.
Definition misc.h:230
P1363 key derivation function.
Definition pubkey.h:750
static void DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength)
P1363 key derivation function.
Definition pubkey.h:760
P1363 mask generation function.
Definition pubkey.h:719
void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask=true) const
P1363 mask generation function.
Definition pubkey.h:734
static const char * StaticAlgorithmName()
The algorithm name.
Definition pubkey.h:725
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:2198
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:2866
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:749
Interface for private keys.
Definition cryptlib.h:2546
Interface for public keys.
Definition cryptlib.h:2541
Interface for random number generators.
Definition cryptlib.h:1440
virtual void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition cryptlib.h:1452
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition cryptlib.h:1460
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:1126
void Assign(const T *ptr, size_type len)
Set contents and size from an array.
Definition secblock.h:898
size_type size() const
Provides the count of elements in the SecBlock.
Definition secblock.h:867
SecBlock typedef.
Definition secblock.h:1226
Interface for domains of simple key agreement protocols.
Definition cryptlib.h:3018
Restricts the instantiation of a class to one static object without locks.
Definition misc.h:309
const T & Ref(...) const
Return a reference to the inner Singleton object.
Definition misc.h:329
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:2290
PK_FinalTemplate< TF_EncryptorImpl< SchemeOptions > > Encryptor
implements PK_Encryptor interface
Definition pubkey.h:2303
PK_FinalTemplate< TF_DecryptorImpl< SchemeOptions > > Decryptor
implements PK_Decryptor interface
Definition pubkey.h:2301
STANDARD Standard
see EncryptionStandard for a list of standards
Definition pubkey.h:2295
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:2316
PK_FinalTemplate< TF_SignerImpl< SchemeOptions > > Signer
implements PK_Signer interface
Definition pubkey.h:2326
STANDARD Standard
see SignatureStandard for a list of standards
Definition pubkey.h:2319
PK_FinalTemplate< TF_VerifierImpl< SchemeOptions > > Verifier
implements PK_Verifier interface
Definition pubkey.h:2328
Trapdoor Function (TF) Signature Scheme base class.
Definition pubkey.h:484
Trapdoor Function (TF) Signer base class.
Definition pubkey.h:512
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const
Sign and restart messageAccumulator.
void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
Input a recoverable message to an accumulator.
Trapdoor Function (TF) encryptor options.
Definition pubkey.h:672
Trapdoor Function (TF) Verifier base class.
Definition pubkey.h:522
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
Input signature into a message accumulator.
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const
Recover a message from its signature.
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 representation after the trapdoor function is applied.
virtual Integer MaxImage() const
Returns the maximum size of a representation after the trapdoor function is applied bound to a public...
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:703
Pointer that overloads operator ->
Definition smartptr.h:38
Library configuration file.
#define CRYPTOPP_API
Win32 calling convention.
Definition config_dll.h:119
Abstract base classes that provide a uniform interface to this library.
CRYPTOPP_DLL RandomNumberGenerator & NullRNG()
Random Number Generator that does not produce random numbers.
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Definition cryptlib.h:534
Classes for precomputation in a group.
Implementation of BufferedTransformation's attachment interface.
Classes and functions for the FIPS 140-2 validated library.
CRYPTOPP_DLL bool FIPS_140_2_ComplianceEnabled()
Determines whether the library provides FIPS validated cryptography.
Multiple precision integer with arithmetic operations.
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
Definition misc.h:1302
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:1143
Class file for performing modular arithmetic.
Crypto++ library namespace.
CofactorMultiplicationOption
Methods for avoiding "Small-Subgroup" attacks on Diffie-Hellman Key Agreement.
Definition pubkey.h:2123
@ INCOMPATIBLE_COFACTOR_MULTIPLICTION
Cofactor multiplication incompatible with ordinary Diffie-Hellman.
Definition pubkey.h:2133
@ NO_COFACTOR_MULTIPLICTION
No cofactor multiplication applied.
Definition pubkey.h:2125
@ COMPATIBLE_COFACTOR_MULTIPLICTION
Cofactor multiplication compatible with ordinary Diffie-Hellman.
Definition pubkey.h:2129
Classes for automatic resource management.
Common C++ header files.
Discrete Log (DL) crypto scheme options.
Definition pubkey.h:1945
Discrete Log (DL) key options.
Definition pubkey.h:1917
Discrete Log (DL) scheme options.
Definition pubkey.h:1906
Discrete Log (DL) signature scheme options.
Definition pubkey.h:1931
Returns a decoding results.
Definition cryptlib.h:283
Base class for public key encryption standard classes.
Definition pubkey.h:2274
Converts an enumeration to a type suitable for use as a template parameter.
Definition cryptlib.h:141
Base class for public key signature standard classes.
Definition pubkey.h:2279
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:68