Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1968 lines
77 KiB

  1. // pubkey.h - written and placed in the public domain by Wei Dai
  2. #ifndef CRYPTOPP_PUBKEY_H
  3. #define CRYPTOPP_PUBKEY_H
  4. //! \file
  5. //! \brief This file contains helper classes/functions for implementing public key algorithms.
  6. //! \details the class hierachies in this header file tend to look like this:
  7. //!
  8. //! <pre>
  9. //! x1
  10. //! +--+
  11. //! | |
  12. //! y1 z1
  13. //! | |
  14. //! x2<y1> x2<z1>
  15. //! | |
  16. //! y2 z2
  17. //! | |
  18. //! x3<y2> x3<z2>
  19. //! | |
  20. //! y3 z3
  21. //! </pre>
  22. //!
  23. //! <ul>
  24. //! <li>x1, y1, z1 are abstract interface classes defined in cryptlib.h
  25. //! <li>x2, y2, z2 are implementations of the interfaces using "abstract policies", which
  26. //! are pure virtual functions that should return interfaces to interchangeable algorithms.
  27. //! These classes have \p Base suffixes.
  28. //! <li>x3, y3, z3 hold actual algorithms and implement those virtual functions.
  29. //! These classes have \p Impl suffixes.
  30. //! </ul>
  31. //!
  32. //! \details The \p TF_ prefix means an implementation using trapdoor functions on integers.
  33. //! \details The \p DL_ prefix means an implementation using group operations (in groups where discrete log is hard).
  34. #include "config.h"
  35. #if CRYPTOPP_MSC_VERSION
  36. # pragma warning(push)
  37. # pragma warning(disable: 4702)
  38. #endif
  39. #include "cryptlib.h"
  40. #include "integer.h"
  41. #include "modarith.h"
  42. #include "filters.h"
  43. #include "eprecomp.h"
  44. #include "fips140.h"
  45. #include "argnames.h"
  46. #include "smartptr.h"
  47. #include "stdcpp.h"
  48. // VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file
  49. #undef INTERFACE
  50. NAMESPACE_BEGIN(CryptoPP)
  51. //! \class TrapdoorFunctionBounds
  52. //! \brief Provides range for plaintext and ciphertext lengths
  53. //! \details A trapdoor function is a function that is easy to compute in one direction,
  54. //! but difficult to compute in the opposite direction without special knowledge.
  55. //! The special knowledge is usually the private key.
  56. //! \details Trapdoor functions only handle messages of a limited length or size.
  57. //! \p MaxPreimage is the plaintext's maximum length, and \p MaxImage is the
  58. //! ciphertext's maximum length.
  59. //! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
  60. //! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
  61. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
  62. {
  63. public:
  64. virtual ~TrapdoorFunctionBounds() {}
  65. //! \brief Returns the maximum size of a message before the trapdoor function is applied
  66. //! \returns the maximum size of a message before the trapdoor function is applied
  67. //! \details Derived classes must implement \p PreimageBound().
  68. virtual Integer PreimageBound() const =0;
  69. //! \brief Returns the maximum size of a message after the trapdoor function is applied
  70. //! \returns the maximum size of a message after the trapdoor function is applied
  71. //! \details Derived classes must implement \p ImageBound().
  72. virtual Integer ImageBound() const =0;
  73. //! \brief Returns the maximum size of a message before the trapdoor function is applied bound to a public key
  74. //! \returns the maximum size of a message before the trapdoor function is applied bound to a public key
  75. //! \details The default implementation returns <tt>PreimageBound() - 1</tt>.
  76. virtual Integer MaxPreimage() const {return --PreimageBound();}
  77. //! \brief Returns the maximum size of a message after the trapdoor function is applied bound to a public key
  78. //! \returns the the maximum size of a message after the trapdoor function is applied bound to a public key
  79. //! \details The default implementation returns <tt>ImageBound() - 1</tt>.
  80. virtual Integer MaxImage() const {return --ImageBound();}
  81. };
  82. //! \class RandomizedTrapdoorFunction
  83. //! \brief Applies the trapdoor function, using random data if required
  84. //! \details \p ApplyFunction() is the foundation for encrypting a message under a public key.
  85. //! Derived classes will override it at some point.
  86. //! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
  87. //! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
  88. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
  89. {
  90. public:
  91. //! \brief Applies the trapdoor function, using random data if required
  92. //! \param rng a \p RandomNumberGenerator derived class
  93. //! \param x the message on which the encryption function is applied
  94. //! \returns the message \p x encrypted under the public key
  95. //! \details \p ApplyRandomizedFunction is a generalization of encryption under a public key
  96. //! cryptosystem. The \p RandomNumberGenerator may (or may not) be required.
  97. //! Derived classes must implement it.
  98. virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
  99. //! \brief Determines if the encryption algorithm is randomized
  100. //! \returns \p true if the encryption algorithm is randomized, \p false otherwise
  101. //! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
  102. virtual bool IsRandomized() const {return true;}
  103. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  104. virtual ~RandomizedTrapdoorFunction() { }
  105. #endif
  106. };
  107. //! \class TrapdoorFunction
  108. //! \brief Applies the trapdoor function
  109. //! \details \p ApplyFunction() is the foundation for encrypting a message under a public key.
  110. //! Derived classes will override it at some point.
  111. //! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
  112. //! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
  113. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
  114. {
  115. public:
  116. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  117. virtual ~TrapdoorFunction() { }
  118. #endif
  119. //! \brief Applies the trapdoor function
  120. //! \param rng a \p RandomNumberGenerator derived class
  121. //! \param x the message on which the encryption function is applied
  122. //! \details \p ApplyRandomizedFunction is a generalization of encryption under a public key
  123. //! cryptosystem. The \p RandomNumberGenerator may (or may not) be required.
  124. //! \details Internally, \p ApplyRandomizedFunction() calls \p ApplyFunction() \a
  125. //! without the \p RandomNumberGenerator.
  126. Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
  127. {CRYPTOPP_UNUSED(rng); return ApplyFunction(x);}
  128. bool IsRandomized() const {return false;}
  129. //! \brief Applies the trapdoor
  130. //! \param x the message on which the encryption function is applied
  131. //! \returns the message \p x encrypted under the public key
  132. //! \details \p ApplyFunction is a generalization of encryption under a public key
  133. //! cryptosystem. Derived classes must implement it.
  134. virtual Integer ApplyFunction(const Integer &x) const =0;
  135. };
  136. //! \class RandomizedTrapdoorFunctionInverse
  137. //! \brief Applies the inverse of the trapdoor function, using random data if required
  138. //! \details \p CalculateInverse() is the foundation for decrypting a message under a private key
  139. //! in a public key cryptosystem. Derived classes will override it at some point.
  140. //! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
  141. //! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
  142. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
  143. {
  144. public:
  145. virtual ~RandomizedTrapdoorFunctionInverse() {}
  146. //! \brief Applies the inverse of the trapdoor function, using random data if required
  147. //! \param rng a \p RandomNumberGenerator derived class
  148. //! \param x the message on which the decryption function is applied
  149. //! \returns the message \p x decrypted under the private key
  150. //! \details \p CalculateRandomizedInverse is a generalization of decryption using the private key
  151. //! The \p RandomNumberGenerator may (or may not) be required. Derived classes must implement it.
  152. virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
  153. //! \brief Determines if the decryption algorithm is randomized
  154. //! \returns \p true if the decryption algorithm is randomized, \p false otherwise
  155. //! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
  156. virtual bool IsRandomized() const {return true;}
  157. };
  158. //! \class TrapdoorFunctionInverse
  159. //! \brief Applies the inverse of the trapdoor function
  160. //! \details \p CalculateInverse() is the foundation for decrypting a message under a private key
  161. //! in a public key cryptosystem. Derived classes will override it at some point.
  162. //! \sa TrapdoorFunctionBounds(), RandomizedTrapdoorFunction(), TrapdoorFunction(),
  163. //! RandomizedTrapdoorFunctionInverse() and TrapdoorFunctionInverse()
  164. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
  165. {
  166. public:
  167. virtual ~TrapdoorFunctionInverse() {}
  168. //! \brief Applies the inverse of the trapdoor function
  169. //! \param rng a \p RandomNumberGenerator derived class
  170. //! \param x the message on which the decryption function is applied
  171. //! \returns the message \p x decrypted under the private key
  172. //! \details \p CalculateRandomizedInverse is a generalization of decryption using the private key
  173. //! \details Internally, \p CalculateRandomizedInverse() calls \p CalculateInverse() \a
  174. //! without the \p RandomNumberGenerator.
  175. Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
  176. {return CalculateInverse(rng, x);}
  177. //! \brief Determines if the decryption algorithm is randomized
  178. //! \returns \p true if the decryption algorithm is randomized, \p false otherwise
  179. //! \details If \p IsRandomized() returns \p false, then \p NullRNG() can be used.
  180. bool IsRandomized() const {return false;}
  181. virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
  182. };
  183. // ********************************************************
  184. //! \class PK_EncryptionMessageEncodingMethod
  185. //! \brief Message encoding method for public key encryption
  186. class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
  187. {
  188. public:
  189. virtual ~PK_EncryptionMessageEncodingMethod() {}
  190. virtual bool ParameterSupported(const char *name) const
  191. {CRYPTOPP_UNUSED(name); return false;}
  192. //! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
  193. virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0;
  194. virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs &parameters) const =0;
  195. virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs &parameters) const =0;
  196. };
  197. // ********************************************************
  198. //! \class TF_Base
  199. //! \brief The base for trapdoor based cryptosystems
  200. //! \tparam TFI trapdoor function interface derived class
  201. //! \tparam MEI message encoding interface derived class
  202. template <class TFI, class MEI>
  203. class CRYPTOPP_NO_VTABLE TF_Base
  204. {
  205. protected:
  206. virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
  207. typedef TFI TrapdoorFunctionInterface;
  208. virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
  209. typedef MEI MessageEncodingInterface;
  210. virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
  211. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  212. virtual ~TF_Base() { }
  213. #endif
  214. };
  215. // ********************************************************
  216. //! \class PK_FixedLengthCryptoSystemImpl
  217. //! \brief Public key trapdoor function base class
  218. //! \tparam BASE public key cryptosystem with a fixed length
  219. template <class BASE>
  220. class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
  221. {
  222. public:
  223. size_t MaxPlaintextLength(size_t ciphertextLength) const
  224. {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
  225. size_t CiphertextLength(size_t plaintextLength) const
  226. {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
  227. virtual size_t FixedMaxPlaintextLength() const =0;
  228. virtual size_t FixedCiphertextLength() const =0;
  229. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  230. virtual ~PK_FixedLengthCryptoSystemImpl() { }
  231. #endif
  232. };
  233. //! \class TF_CryptoSystemBase
  234. //! \brief Trapdoor function cryptosystem base class
  235. //! \tparam INTERFACE public key cryptosystem base interface
  236. //! \tparam BASE public key cryptosystem implementation base
  237. template <class INTERFACE, class BASE>
  238. class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE
  239. {
  240. public:
  241. bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);}
  242. size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
  243. size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
  244. protected:
  245. size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
  246. // Coverity finding on potential overflow/underflow.
  247. size_t PaddedBlockBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().PreimageBound().BitCount(),1U);}
  248. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  249. virtual ~TF_CryptoSystemBase() { }
  250. #endif
  251. };
  252. //! \class TF_DecryptorBase
  253. //! \brief Trapdoor function cryptosystems decryption base class
  254. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
  255. {
  256. public:
  257. DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
  258. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  259. virtual ~TF_DecryptorBase() { }
  260. #endif
  261. };
  262. //! \class TF_DecryptorBase
  263. //! \brief Trapdoor function cryptosystems encryption base class
  264. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
  265. {
  266. public:
  267. void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
  268. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  269. virtual ~TF_EncryptorBase() { }
  270. #endif
  271. };
  272. // ********************************************************
  273. typedef std::pair<const byte *, size_t> HashIdentifier;
  274. //! \class PK_SignatureMessageEncodingMethod
  275. //! \brief Interface for message encoding method for public key signature schemes.
  276. //! \details \p PK_SignatureMessageEncodingMethod provides interfaces for message
  277. //! encoding method for public key signature schemes. The methods support both
  278. //! trapdoor functions (<tt>TF_*</tt>) and discrete logarithm (<tt>DL_*</tt>)
  279. //! based schemes.
  280. class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
  281. {
  282. public:
  283. virtual ~PK_SignatureMessageEncodingMethod() {}
  284. virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const
  285. {CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
  286. virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const
  287. {CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
  288. bool IsProbabilistic() const
  289. {return true;}
  290. bool AllowNonrecoverablePart() const
  291. {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
  292. virtual bool RecoverablePartFirst() const
  293. {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
  294. // for verification, DL
  295. virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const
  296. {CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength);}
  297. // for signature
  298. virtual void ProcessRecoverableMessage(HashTransformation &hash,
  299. const byte *recoverableMessage, size_t recoverableMessageLength,
  300. const byte *presignature, size_t presignatureLength,
  301. SecByteBlock &semisignature) const
  302. {
  303. CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength);
  304. CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength); CRYPTOPP_UNUSED(semisignature);
  305. if (RecoverablePartFirst())
  306. assert(!"ProcessRecoverableMessage() not implemented");
  307. }
  308. virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng,
  309. const byte *recoverableMessage, size_t recoverableMessageLength,
  310. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  311. byte *representative, size_t representativeBitLength) const =0;
  312. virtual bool VerifyMessageRepresentative(
  313. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  314. byte *representative, size_t representativeBitLength) const =0;
  315. virtual DecodingResult RecoverMessageFromRepresentative( // for TF
  316. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  317. byte *representative, size_t representativeBitLength,
  318. byte *recoveredMessage) const
  319. {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty);
  320. CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(recoveredMessage);
  321. throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
  322. virtual DecodingResult RecoverMessageFromSemisignature( // for DL
  323. HashTransformation &hash, HashIdentifier hashIdentifier,
  324. const byte *presignature, size_t presignatureLength,
  325. const byte *semisignature, size_t semisignatureLength,
  326. byte *recoveredMessage) const
  327. {CRYPTOPP_UNUSED(hash);CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(presignature); CRYPTOPP_UNUSED(presignatureLength);
  328. CRYPTOPP_UNUSED(semisignature); CRYPTOPP_UNUSED(semisignatureLength); CRYPTOPP_UNUSED(recoveredMessage);
  329. throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
  330. // VC60 workaround
  331. struct HashIdentifierLookup
  332. {
  333. template <class H> struct HashIdentifierLookup2
  334. {
  335. static HashIdentifier CRYPTOPP_API Lookup()
  336. {
  337. return HashIdentifier((const byte *)NULL, 0);
  338. }
  339. };
  340. };
  341. };
  342. //! \class PK_DeterministicSignatureMessageEncodingMethod
  343. //! \brief Interface for message encoding method for public key signature schemes.
  344. //! \details \p PK_DeterministicSignatureMessageEncodingMethod provides interfaces
  345. //! for message encoding method for public key signature schemes.
  346. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
  347. {
  348. public:
  349. bool VerifyMessageRepresentative(
  350. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  351. byte *representative, size_t representativeBitLength) const;
  352. };
  353. //! \class PK_RecoverableSignatureMessageEncodingMethod
  354. //! \brief Interface for message encoding method for public key signature schemes.
  355. //! \details \p PK_RecoverableSignatureMessageEncodingMethod provides interfaces
  356. //! for message encoding method for public key signature schemes.
  357. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
  358. {
  359. public:
  360. bool VerifyMessageRepresentative(
  361. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  362. byte *representative, size_t representativeBitLength) const;
  363. };
  364. //! \class DL_SignatureMessageEncodingMethod_DSA
  365. //! \brief Interface for message encoding method for public key signature schemes.
  366. //! \details \p DL_SignatureMessageEncodingMethod_DSA provides interfaces
  367. //! for message encoding method for DSA.
  368. class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
  369. {
  370. public:
  371. void ComputeMessageRepresentative(RandomNumberGenerator &rng,
  372. const byte *recoverableMessage, size_t recoverableMessageLength,
  373. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  374. byte *representative, size_t representativeBitLength) const;
  375. };
  376. //! \class DL_SignatureMessageEncodingMethod_NR
  377. //! \brief Interface for message encoding method for public key signature schemes.
  378. //! \details \p DL_SignatureMessageEncodingMethod_NR provides interfaces
  379. //! for message encoding method for Nyberg-Rueppel.
  380. class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
  381. {
  382. public:
  383. void ComputeMessageRepresentative(RandomNumberGenerator &rng,
  384. const byte *recoverableMessage, size_t recoverableMessageLength,
  385. HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
  386. byte *representative, size_t representativeBitLength) const;
  387. };
  388. //! \class PK_MessageAccumulatorBase
  389. //! \brief Interface for message encoding method for public key signature schemes.
  390. //! \details \p PK_MessageAccumulatorBase provides interfaces
  391. //! for message encoding method.
  392. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
  393. {
  394. public:
  395. PK_MessageAccumulatorBase() : m_empty(true) {}
  396. virtual HashTransformation & AccessHash() =0;
  397. void Update(const byte *input, size_t length)
  398. {
  399. AccessHash().Update(input, length);
  400. m_empty = m_empty && length == 0;
  401. }
  402. SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
  403. Integer m_k, m_s;
  404. bool m_empty;
  405. };
  406. //! \class PK_MessageAccumulatorImpl
  407. //! \brief Interface for message encoding method for public key signature schemes.
  408. //! \details \p PK_MessageAccumulatorBase provides interfaces
  409. //! for message encoding method.
  410. template <class HASH_ALGORITHM>
  411. class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
  412. {
  413. public:
  414. HashTransformation & AccessHash() {return this->m_object;}
  415. };
  416. //! _
  417. template <class INTERFACE, class BASE>
  418. class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTERFACE, protected BASE
  419. {
  420. public:
  421. size_t SignatureLength() const
  422. {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
  423. size_t MaxRecoverableLength() const
  424. {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
  425. size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
  426. {CRYPTOPP_UNUSED(signatureLength); return this->MaxRecoverableLength();}
  427. bool IsProbabilistic() const
  428. {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
  429. bool AllowNonrecoverablePart() const
  430. {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
  431. bool RecoverablePartFirst() const
  432. {return this->GetMessageEncodingInterface().RecoverablePartFirst();}
  433. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  434. virtual ~TF_SignatureSchemeBase() { }
  435. #endif
  436. protected:
  437. size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
  438. // Coverity finding on potential overflow/underflow.
  439. size_t MessageRepresentativeBitLength() const {return SaturatingSubtract(this->GetTrapdoorFunctionBounds().ImageBound().BitCount(),1U);}
  440. virtual HashIdentifier GetHashIdentifier() const =0;
  441. virtual size_t GetDigestSize() const =0;
  442. };
  443. //! _
  444. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
  445. {
  446. public:
  447. void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const;
  448. size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
  449. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  450. virtual ~TF_SignerBase() { }
  451. #endif
  452. };
  453. //! _
  454. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
  455. {
  456. public:
  457. void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const;
  458. bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
  459. DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
  460. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  461. virtual ~TF_VerifierBase() { }
  462. #endif
  463. };
  464. // ********************************************************
  465. //! _
  466. template <class T1, class T2, class T3>
  467. struct TF_CryptoSchemeOptions
  468. {
  469. typedef T1 AlgorithmInfo;
  470. typedef T2 Keys;
  471. typedef typename Keys::PrivateKey PrivateKey;
  472. typedef typename Keys::PublicKey PublicKey;
  473. typedef T3 MessageEncodingMethod;
  474. };
  475. //! _
  476. template <class T1, class T2, class T3, class T4>
  477. struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3>
  478. {
  479. typedef T4 HashFunction;
  480. };
  481. //! _
  482. template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
  483. class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
  484. {
  485. public:
  486. typedef SCHEME_OPTIONS SchemeOptions;
  487. typedef KEY_CLASS KeyClass;
  488. PublicKey & AccessPublicKey() {return AccessKey();}
  489. const PublicKey & GetPublicKey() const {return GetKey();}
  490. PrivateKey & AccessPrivateKey() {return AccessKey();}
  491. const PrivateKey & GetPrivateKey() const {return GetKey();}
  492. virtual const KeyClass & GetKey() const =0;
  493. virtual KeyClass & AccessKey() =0;
  494. const KeyClass & GetTrapdoorFunction() const {return GetKey();}
  495. PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
  496. {
  497. CRYPTOPP_UNUSED(rng);
  498. return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
  499. }
  500. PK_MessageAccumulator * NewVerificationAccumulator() const
  501. {
  502. return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
  503. }
  504. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  505. virtual ~TF_ObjectImplBase() { }
  506. #endif
  507. protected:
  508. const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const
  509. {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
  510. const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const
  511. {return GetKey();}
  512. const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const
  513. {return GetKey();}
  514. // for signature scheme
  515. HashIdentifier GetHashIdentifier() const
  516. {
  517. typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L;
  518. return L::Lookup();
  519. }
  520. size_t GetDigestSize() const
  521. {
  522. typedef CPP_TYPENAME SchemeOptions::HashFunction H;
  523. return H::DIGESTSIZE;
  524. }
  525. };
  526. //! _
  527. template <class BASE, class SCHEME_OPTIONS, class KEY>
  528. class TF_ObjectImplExtRef : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
  529. {
  530. public:
  531. TF_ObjectImplExtRef(const KEY *pKey = NULL) : m_pKey(pKey) {}
  532. void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;}
  533. const KEY & GetKey() const {return *m_pKey;}
  534. KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");}
  535. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  536. virtual ~TF_ObjectImplExtRef() { }
  537. #endif
  538. private:
  539. const KEY * m_pKey;
  540. };
  541. //! _
  542. template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
  543. class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS>
  544. {
  545. public:
  546. typedef KEY_CLASS KeyClass;
  547. const KeyClass & GetKey() const {return m_trapdoorFunction;}
  548. KeyClass & AccessKey() {return m_trapdoorFunction;}
  549. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  550. virtual ~TF_ObjectImpl() { }
  551. #endif
  552. private:
  553. KeyClass m_trapdoorFunction;
  554. };
  555. //! _
  556. template <class SCHEME_OPTIONS>
  557. class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
  558. {
  559. };
  560. //! _
  561. template <class SCHEME_OPTIONS>
  562. class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
  563. {
  564. };
  565. //! _
  566. template <class SCHEME_OPTIONS>
  567. class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
  568. {
  569. };
  570. //! _
  571. template <class SCHEME_OPTIONS>
  572. class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
  573. {
  574. };
  575. // ********************************************************
  576. //! _
  577. class CRYPTOPP_NO_VTABLE MaskGeneratingFunction
  578. {
  579. public:
  580. virtual ~MaskGeneratingFunction() {}
  581. virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0;
  582. };
  583. CRYPTOPP_DLL void CRYPTOPP_API P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart);
  584. //! _
  585. class P1363_MGF1 : public MaskGeneratingFunction
  586. {
  587. public:
  588. static const char * CRYPTOPP_API StaticAlgorithmName() {return "MGF1";}
  589. void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const
  590. {
  591. P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0);
  592. }
  593. };
  594. // ********************************************************
  595. //! _
  596. template <class H>
  597. class P1363_KDF2
  598. {
  599. public:
  600. static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength)
  601. {
  602. H h;
  603. P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
  604. }
  605. };
  606. // ********************************************************
  607. //! to be thrown by DecodeElement and AgreeWithStaticPrivateKey
  608. class DL_BadElement : public InvalidDataFormat
  609. {
  610. public:
  611. DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {}
  612. };
  613. //! interface for DL group parameters
  614. template <class T>
  615. class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters
  616. {
  617. typedef DL_GroupParameters<T> ThisClass;
  618. public:
  619. typedef T Element;
  620. DL_GroupParameters() : m_validationLevel(0) {}
  621. // CryptoMaterial
  622. bool Validate(RandomNumberGenerator &rng, unsigned int level) const
  623. {
  624. if (!GetBasePrecomputation().IsInitialized())
  625. return false;
  626. if (m_validationLevel > level)
  627. return true;
  628. bool pass = ValidateGroup(rng, level);
  629. pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
  630. m_validationLevel = pass ? level+1 : 0;
  631. return pass;
  632. }
  633. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  634. {
  635. return GetValueHelper(this, name, valueType, pValue)
  636. CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
  637. CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
  638. ;
  639. }
  640. bool SupportsPrecomputation() const {return true;}
  641. void Precompute(unsigned int precomputationStorage=16)
  642. {
  643. AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
  644. }
  645. void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
  646. {
  647. AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
  648. m_validationLevel = 0;
  649. }
  650. void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
  651. {
  652. GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
  653. }
  654. // non-inherited
  655. virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
  656. virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
  657. virtual Element ExponentiateBase(const Integer &exponent) const
  658. {
  659. return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
  660. }
  661. virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
  662. {
  663. Element result;
  664. SimultaneousExponentiate(&result, base, &exponent, 1);
  665. return result;
  666. }
  667. virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0;
  668. virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0;
  669. virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0;
  670. virtual const Integer & GetSubgroupOrder() const =0; // order of subgroup generated by base element
  671. virtual Integer GetMaxExponent() const =0;
  672. virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();} // one of these two needs to be overriden
  673. virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();}
  674. virtual unsigned int GetEncodedElementSize(bool reversible) const =0;
  675. virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0;
  676. virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0;
  677. virtual Integer ConvertElementToInteger(const Element &element) const =0;
  678. virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0;
  679. virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0;
  680. virtual bool FastSubgroupCheckAvailable() const =0;
  681. virtual bool IsIdentity(const Element &element) const =0;
  682. virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0;
  683. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  684. virtual ~DL_GroupParameters() { }
  685. #endif
  686. protected:
  687. void ParametersChanged() {m_validationLevel = 0;}
  688. private:
  689. mutable unsigned int m_validationLevel;
  690. };
  691. //! _
  692. template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<CPP_TYPENAME GROUP_PRECOMP::Element> >
  693. class DL_GroupParametersImpl : public BASE
  694. {
  695. public:
  696. typedef GROUP_PRECOMP GroupPrecomputation;
  697. typedef typename GROUP_PRECOMP::Element Element;
  698. typedef BASE_PRECOMP BasePrecomputation;
  699. const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;}
  700. const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return m_gpc;}
  701. DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return m_gpc;}
  702. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  703. virtual ~DL_GroupParametersImpl() { }
  704. #endif
  705. protected:
  706. GROUP_PRECOMP m_groupPrecomputation;
  707. BASE_PRECOMP m_gpc;
  708. };
  709. //! _
  710. template <class T>
  711. class CRYPTOPP_NO_VTABLE DL_Key
  712. {
  713. public:
  714. virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0;
  715. virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0;
  716. };
  717. //! interface for DL public keys
  718. template <class T>
  719. class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T>
  720. {
  721. typedef DL_PublicKey<T> ThisClass;
  722. public:
  723. typedef T Element;
  724. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  725. {
  726. return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
  727. CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
  728. }
  729. void AssignFrom(const NameValuePairs &source);
  730. // non-inherited
  731. virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
  732. virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
  733. virtual Element ExponentiatePublicElement(const Integer &exponent) const
  734. {
  735. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  736. return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
  737. }
  738. virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
  739. {
  740. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  741. return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
  742. }
  743. virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation() const =0;
  744. virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0;
  745. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  746. virtual ~DL_PublicKey() { }
  747. #endif
  748. };
  749. //! interface for DL private keys
  750. template <class T>
  751. class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T>
  752. {
  753. typedef DL_PrivateKey<T> ThisClass;
  754. public:
  755. typedef T Element;
  756. void MakePublicKey(DL_PublicKey<T> &pub) const
  757. {
  758. pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters());
  759. pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
  760. }
  761. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  762. {
  763. return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
  764. CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
  765. }
  766. void AssignFrom(const NameValuePairs &source)
  767. {
  768. this->AccessAbstractGroupParameters().AssignFrom(source);
  769. AssignFromHelper(this, source)
  770. CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
  771. }
  772. virtual const Integer & GetPrivateExponent() const =0;
  773. virtual void SetPrivateExponent(const Integer &x) =0;
  774. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  775. virtual ~DL_PrivateKey() { }
  776. #endif
  777. };
  778. template <class T>
  779. void DL_PublicKey<T>::AssignFrom(const NameValuePairs &source)
  780. {
  781. DL_PrivateKey<T> *pPrivateKey = NULL;
  782. if (source.GetThisPointer(pPrivateKey))
  783. pPrivateKey->MakePublicKey(*this);
  784. else
  785. {
  786. this->AccessAbstractGroupParameters().AssignFrom(source);
  787. AssignFromHelper(this, source)
  788. CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
  789. }
  790. }
  791. class OID;
  792. //! _
  793. template <class PK, class GP, class O = OID>
  794. class DL_KeyImpl : public PK
  795. {
  796. public:
  797. typedef GP GroupParameters;
  798. O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();}
  799. // void BERDecode(BufferedTransformation &bt)
  800. // {PK::BERDecode(bt);}
  801. // void DEREncode(BufferedTransformation &bt) const
  802. // {PK::DEREncode(bt);}
  803. bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
  804. {AccessGroupParameters().BERDecode(bt); return true;}
  805. bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
  806. {GetGroupParameters().DEREncode(bt); return true;}
  807. const GP & GetGroupParameters() const {return m_groupParameters;}
  808. GP & AccessGroupParameters() {return m_groupParameters;}
  809. private:
  810. GP m_groupParameters;
  811. };
  812. class X509PublicKey;
  813. class PKCS8PrivateKey;
  814. //! _
  815. template <class GP>
  816. class DL_PrivateKeyImpl : public DL_PrivateKey<CPP_TYPENAME GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP>
  817. {
  818. public:
  819. typedef typename GP::Element Element;
  820. // GeneratableCryptoMaterial
  821. bool Validate(RandomNumberGenerator &rng, unsigned int level) const
  822. {
  823. bool pass = GetAbstractGroupParameters().Validate(rng, level);
  824. const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
  825. const Integer &x = GetPrivateExponent();
  826. pass = pass && x.IsPositive() && x < q;
  827. if (level >= 1)
  828. pass = pass && Integer::Gcd(x, q) == Integer::One();
  829. return pass;
  830. }
  831. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  832. {
  833. return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable();
  834. }
  835. void AssignFrom(const NameValuePairs &source)
  836. {
  837. AssignFromHelper<DL_PrivateKey<Element> >(this, source);
  838. }
  839. void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
  840. {
  841. if (!params.GetThisObject(this->AccessGroupParameters()))
  842. this->AccessGroupParameters().GenerateRandom(rng, params);
  843. // std::pair<const byte *, int> seed;
  844. Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
  845. // Integer::ANY, Integer::Zero(), Integer::One(),
  846. // params.GetValue("DeterministicKeyGenerationSeed", seed) ? &seed : NULL);
  847. SetPrivateExponent(x);
  848. }
  849. bool SupportsPrecomputation() const {return true;}
  850. void Precompute(unsigned int precomputationStorage=16)
  851. {AccessAbstractGroupParameters().Precompute(precomputationStorage);}
  852. void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
  853. {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
  854. void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
  855. {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
  856. // DL_Key
  857. const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
  858. DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
  859. // DL_PrivateKey
  860. const Integer & GetPrivateExponent() const {return m_x;}
  861. void SetPrivateExponent(const Integer &x) {m_x = x;}
  862. // PKCS8PrivateKey
  863. void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t)
  864. {m_x.BERDecode(bt);}
  865. void DEREncodePrivateKey(BufferedTransformation &bt) const
  866. {m_x.DEREncode(bt);}
  867. private:
  868. Integer m_x;
  869. };
  870. //! _
  871. template <class BASE, class SIGNATURE_SCHEME>
  872. class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE
  873. {
  874. public:
  875. void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
  876. {
  877. BASE::GenerateRandom(rng, params);
  878. if (FIPS_140_2_ComplianceEnabled())
  879. {
  880. typename SIGNATURE_SCHEME::Signer signer(*this);
  881. typename SIGNATURE_SCHEME::Verifier verifier(signer);
  882. SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
  883. }
  884. }
  885. };
  886. //! _
  887. template <class GP>
  888. class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP>
  889. {
  890. public:
  891. typedef typename GP::Element Element;
  892. // CryptoMaterial
  893. bool Validate(RandomNumberGenerator &rng, unsigned int level) const
  894. {
  895. bool pass = GetAbstractGroupParameters().Validate(rng, level);
  896. pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
  897. return pass;
  898. }
  899. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  900. {
  901. return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable();
  902. }
  903. void AssignFrom(const NameValuePairs &source)
  904. {
  905. AssignFromHelper<DL_PublicKey<Element> >(this, source);
  906. }
  907. bool SupportsPrecomputation() const {return true;}
  908. void Precompute(unsigned int precomputationStorage=16)
  909. {
  910. AccessAbstractGroupParameters().Precompute(precomputationStorage);
  911. AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
  912. }
  913. void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
  914. {
  915. AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
  916. AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
  917. }
  918. void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
  919. {
  920. GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
  921. GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
  922. }
  923. // DL_Key
  924. const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
  925. DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
  926. // DL_PublicKey
  927. const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;}
  928. DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;}
  929. // non-inherited
  930. bool operator==(const DL_PublicKeyImpl<GP> &rhs) const
  931. {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
  932. private:
  933. typename GP::BasePrecomputation m_ypc;
  934. };
  935. //! interface for Elgamal-like signature algorithms
  936. template <class T>
  937. class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm
  938. {
  939. public:
  940. virtual void Sign(const DL_GroupParameters<T> &params, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
  941. virtual bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
  942. virtual Integer RecoverPresignature(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
  943. {
  944. CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(publicKey); CRYPTOPP_UNUSED(r); CRYPTOPP_UNUSED(s);
  945. throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");
  946. }
  947. virtual size_t RLen(const DL_GroupParameters<T> &params) const
  948. {return params.GetSubgroupOrder().ByteCount();}
  949. virtual size_t SLen(const DL_GroupParameters<T> &params) const
  950. {return params.GetSubgroupOrder().ByteCount();}
  951. };
  952. //! interface for DL key agreement algorithms
  953. template <class T>
  954. class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm
  955. {
  956. public:
  957. typedef T Element;
  958. virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0;
  959. virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0;
  960. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  961. virtual ~DL_KeyAgreementAlgorithm() { }
  962. #endif
  963. };
  964. //! interface for key derivation algorithms used in DL cryptosystems
  965. template <class T>
  966. class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
  967. {
  968. public:
  969. virtual bool ParameterSupported(const char *name) const
  970. {CRYPTOPP_UNUSED(name); return false;}
  971. virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0;
  972. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  973. virtual ~DL_KeyDerivationAlgorithm() { }
  974. #endif
  975. };
  976. //! interface for symmetric encryption algorithms used in DL cryptosystems
  977. class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
  978. {
  979. public:
  980. virtual bool ParameterSupported(const char *name) const
  981. {CRYPTOPP_UNUSED(name); return false;}
  982. virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0;
  983. virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0;
  984. virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0;
  985. virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const =0;
  986. virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const =0;
  987. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  988. virtual ~DL_SymmetricEncryptionAlgorithm() { }
  989. #endif
  990. };
  991. //! _
  992. template <class KI>
  993. class CRYPTOPP_NO_VTABLE DL_Base
  994. {
  995. protected:
  996. typedef KI KeyInterface;
  997. typedef typename KI::Element Element;
  998. const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();}
  999. DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();}
  1000. virtual KeyInterface & AccessKeyInterface() =0;
  1001. virtual const KeyInterface & GetKeyInterface() const =0;
  1002. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1003. virtual ~DL_Base() { }
  1004. #endif
  1005. };
  1006. //! _
  1007. template <class INTERFACE, class KEY_INTERFACE>
  1008. class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTERFACE, public DL_Base<KEY_INTERFACE>
  1009. {
  1010. public:
  1011. size_t SignatureLength() const
  1012. {
  1013. return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
  1014. + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
  1015. }
  1016. size_t MaxRecoverableLength() const
  1017. {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
  1018. size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
  1019. {CRYPTOPP_UNUSED(signatureLength); assert(false); return 0;} // TODO
  1020. bool IsProbabilistic() const
  1021. {return true;}
  1022. bool AllowNonrecoverablePart() const
  1023. {return GetMessageEncodingInterface().AllowNonrecoverablePart();}
  1024. bool RecoverablePartFirst() const
  1025. {return GetMessageEncodingInterface().RecoverablePartFirst();}
  1026. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1027. virtual ~DL_SignatureSchemeBase() { }
  1028. #endif
  1029. protected:
  1030. size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
  1031. size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
  1032. virtual const DL_ElgamalLikeSignatureAlgorithm<CPP_TYPENAME KEY_INTERFACE::Element> & GetSignatureAlgorithm() const =0;
  1033. virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
  1034. virtual HashIdentifier GetHashIdentifier() const =0;
  1035. virtual size_t GetDigestSize() const =0;
  1036. };
  1037. //! _
  1038. template <class T>
  1039. class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
  1040. {
  1041. public:
  1042. // for validation testing
  1043. void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
  1044. {
  1045. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1046. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1047. const DL_PrivateKey<T> &key = this->GetKeyInterface();
  1048. r = params.ConvertElementToInteger(params.ExponentiateBase(k));
  1049. alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
  1050. }
  1051. void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
  1052. {
  1053. PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
  1054. ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
  1055. this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
  1056. recoverableMessage, recoverableMessageLength,
  1057. ma.m_presignature, ma.m_presignature.size(),
  1058. ma.m_semisignature);
  1059. }
  1060. size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
  1061. {
  1062. this->GetMaterial().DoQuickSanityCheck();
  1063. PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
  1064. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1065. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1066. const DL_PrivateKey<T> &key = this->GetKeyInterface();
  1067. SecByteBlock representative(this->MessageRepresentativeLength());
  1068. this->GetMessageEncodingInterface().ComputeMessageRepresentative(
  1069. rng,
  1070. ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
  1071. ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
  1072. representative, this->MessageRepresentativeBitLength());
  1073. ma.m_empty = true;
  1074. Integer e(representative, representative.size());
  1075. // hash message digest into random number k to prevent reusing the same k on a different messages
  1076. // after virtual machine rollback
  1077. if (rng.CanIncorporateEntropy())
  1078. rng.IncorporateEntropy(representative, representative.size());
  1079. Integer k(rng, 1, params.GetSubgroupOrder()-1);
  1080. Integer r, s;
  1081. r = params.ConvertElementToInteger(params.ExponentiateBase(k));
  1082. alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
  1083. /*
  1084. Integer r, s;
  1085. if (this->MaxRecoverableLength() > 0)
  1086. r.Decode(ma.m_semisignature, ma.m_semisignature.size());
  1087. else
  1088. r.Decode(ma.m_presignature, ma.m_presignature.size());
  1089. alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s);
  1090. */
  1091. size_t rLen = alg.RLen(params);
  1092. r.Encode(signature, rLen);
  1093. s.Encode(signature+rLen, alg.SLen(params));
  1094. if (restart)
  1095. RestartMessageAccumulator(rng, ma);
  1096. return this->SignatureLength();
  1097. }
  1098. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1099. virtual ~DL_SignerBase() { }
  1100. #endif
  1101. protected:
  1102. void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
  1103. {
  1104. // k needs to be generated before hashing for signature schemes with recovery
  1105. // but to defend against VM rollbacks we need to generate k after hashing.
  1106. // so this code is commented out, since no DL-based signature scheme with recovery
  1107. // has been implemented in Crypto++ anyway
  1108. /*
  1109. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1110. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1111. ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
  1112. ma.m_presignature.New(params.GetEncodedElementSize(false));
  1113. params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size());
  1114. */
  1115. CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(ma);
  1116. }
  1117. };
  1118. //! _
  1119. template <class T>
  1120. class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
  1121. {
  1122. public:
  1123. void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
  1124. {
  1125. CRYPTOPP_UNUSED(signature); CRYPTOPP_UNUSED(signatureLength);
  1126. PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
  1127. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1128. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1129. size_t rLen = alg.RLen(params);
  1130. ma.m_semisignature.Assign(signature, rLen);
  1131. ma.m_s.Decode(signature+rLen, alg.SLen(params));
  1132. this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
  1133. }
  1134. bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
  1135. {
  1136. this->GetMaterial().DoQuickSanityCheck();
  1137. PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
  1138. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1139. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1140. const DL_PublicKey<T> &key = this->GetKeyInterface();
  1141. SecByteBlock representative(this->MessageRepresentativeLength());
  1142. this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
  1143. ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
  1144. representative, this->MessageRepresentativeBitLength());
  1145. ma.m_empty = true;
  1146. Integer e(representative, representative.size());
  1147. Integer r(ma.m_semisignature, ma.m_semisignature.size());
  1148. return alg.Verify(params, key, e, r, ma.m_s);
  1149. }
  1150. DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
  1151. {
  1152. this->GetMaterial().DoQuickSanityCheck();
  1153. PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
  1154. const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
  1155. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1156. const DL_PublicKey<T> &key = this->GetKeyInterface();
  1157. SecByteBlock representative(this->MessageRepresentativeLength());
  1158. this->GetMessageEncodingInterface().ComputeMessageRepresentative(
  1159. NullRNG(),
  1160. ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
  1161. ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
  1162. representative, this->MessageRepresentativeBitLength());
  1163. ma.m_empty = true;
  1164. Integer e(representative, representative.size());
  1165. ma.m_presignature.New(params.GetEncodedElementSize(false));
  1166. Integer r(ma.m_semisignature, ma.m_semisignature.size());
  1167. alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
  1168. return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
  1169. ma.AccessHash(), this->GetHashIdentifier(),
  1170. ma.m_presignature, ma.m_presignature.size(),
  1171. ma.m_semisignature, ma.m_semisignature.size(),
  1172. recoveredMessage);
  1173. }
  1174. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1175. virtual ~DL_VerifierBase() { }
  1176. #endif
  1177. };
  1178. //! _
  1179. template <class PK, class KI>
  1180. class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
  1181. {
  1182. public:
  1183. typedef typename DL_Base<KI>::Element Element;
  1184. size_t MaxPlaintextLength(size_t ciphertextLength) const
  1185. {
  1186. unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
  1187. return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
  1188. }
  1189. size_t CiphertextLength(size_t plaintextLength) const
  1190. {
  1191. size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
  1192. return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
  1193. }
  1194. bool ParameterSupported(const char *name) const
  1195. {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
  1196. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1197. virtual ~DL_CryptoSystemBase() { }
  1198. #endif
  1199. protected:
  1200. virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
  1201. virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
  1202. virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
  1203. };
  1204. //! _
  1205. template <class T>
  1206. class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
  1207. {
  1208. public:
  1209. typedef T Element;
  1210. DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
  1211. {
  1212. try
  1213. {
  1214. CRYPTOPP_UNUSED(rng);
  1215. const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
  1216. const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
  1217. const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
  1218. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1219. const DL_PrivateKey<T> &key = this->GetKeyInterface();
  1220. Element q = params.DecodeElement(ciphertext, true);
  1221. size_t elementSize = params.GetEncodedElementSize(true);
  1222. ciphertext += elementSize;
  1223. ciphertextLength -= elementSize;
  1224. Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
  1225. SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
  1226. derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
  1227. return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
  1228. }
  1229. catch (DL_BadElement &)
  1230. {
  1231. return DecodingResult();
  1232. }
  1233. }
  1234. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1235. virtual ~DL_DecryptorBase() { }
  1236. #endif
  1237. };
  1238. //! _
  1239. template <class T>
  1240. class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
  1241. {
  1242. public:
  1243. typedef T Element;
  1244. void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const
  1245. {
  1246. const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
  1247. const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
  1248. const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
  1249. const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
  1250. const DL_PublicKey<T> &key = this->GetKeyInterface();
  1251. Integer x(rng, Integer::One(), params.GetMaxExponent());
  1252. Element q = params.ExponentiateBase(x);
  1253. params.EncodeElement(true, q, ciphertext);
  1254. unsigned int elementSize = params.GetEncodedElementSize(true);
  1255. ciphertext += elementSize;
  1256. Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
  1257. SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
  1258. derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
  1259. encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
  1260. }
  1261. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1262. virtual ~DL_EncryptorBase() { }
  1263. #endif
  1264. };
  1265. //! _
  1266. template <class T1, class T2>
  1267. struct DL_SchemeOptionsBase
  1268. {
  1269. typedef T1 AlgorithmInfo;
  1270. typedef T2 GroupParameters;
  1271. typedef typename GroupParameters::Element Element;
  1272. };
  1273. //! _
  1274. template <class T1, class T2>
  1275. struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
  1276. {
  1277. typedef T2 Keys;
  1278. typedef typename Keys::PrivateKey PrivateKey;
  1279. typedef typename Keys::PublicKey PublicKey;
  1280. };
  1281. //! _
  1282. template <class T1, class T2, class T3, class T4, class T5>
  1283. struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
  1284. {
  1285. typedef T3 SignatureAlgorithm;
  1286. typedef T4 MessageEncodingMethod;
  1287. typedef T5 HashFunction;
  1288. };
  1289. //! _
  1290. template <class T1, class T2, class T3, class T4, class T5>
  1291. struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
  1292. {
  1293. typedef T3 KeyAgreementAlgorithm;
  1294. typedef T4 KeyDerivationAlgorithm;
  1295. typedef T5 SymmetricEncryptionAlgorithm;
  1296. };
  1297. //! _
  1298. template <class BASE, class SCHEME_OPTIONS, class KEY>
  1299. class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
  1300. {
  1301. public:
  1302. typedef SCHEME_OPTIONS SchemeOptions;
  1303. typedef typename KEY::Element Element;
  1304. PrivateKey & AccessPrivateKey() {return m_key;}
  1305. PublicKey & AccessPublicKey() {return m_key;}
  1306. // KeyAccessor
  1307. const KEY & GetKey() const {return m_key;}
  1308. KEY & AccessKey() {return m_key;}
  1309. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1310. virtual ~DL_ObjectImplBase() { }
  1311. #endif
  1312. protected:
  1313. typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
  1314. const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
  1315. // for signature scheme
  1316. HashIdentifier GetHashIdentifier() const
  1317. {
  1318. typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
  1319. return HashLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction>::Lookup();
  1320. }
  1321. size_t GetDigestSize() const
  1322. {
  1323. typedef CPP_TYPENAME SchemeOptions::HashFunction H;
  1324. return H::DIGESTSIZE;
  1325. }
  1326. private:
  1327. KEY m_key;
  1328. };
  1329. //! _
  1330. template <class BASE, class SCHEME_OPTIONS, class KEY>
  1331. class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
  1332. {
  1333. public:
  1334. typedef typename KEY::Element Element;
  1335. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1336. virtual ~DL_ObjectImpl() { }
  1337. #endif
  1338. protected:
  1339. const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
  1340. {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SignatureAlgorithm>().Ref();}
  1341. const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
  1342. {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();}
  1343. const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
  1344. {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();}
  1345. const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
  1346. {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();}
  1347. HashIdentifier GetHashIdentifier() const
  1348. {return HashIdentifier();}
  1349. const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
  1350. {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
  1351. };
  1352. //! _
  1353. template <class SCHEME_OPTIONS>
  1354. class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
  1355. {
  1356. public:
  1357. PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
  1358. {
  1359. member_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>);
  1360. this->RestartMessageAccumulator(rng, *p);
  1361. return p.release();
  1362. }
  1363. };
  1364. //! _
  1365. template <class SCHEME_OPTIONS>
  1366. class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
  1367. {
  1368. public:
  1369. PK_MessageAccumulator * NewVerificationAccumulator() const
  1370. {
  1371. return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
  1372. }
  1373. };
  1374. //! _
  1375. template <class SCHEME_OPTIONS>
  1376. class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
  1377. {
  1378. };
  1379. //! _
  1380. template <class SCHEME_OPTIONS>
  1381. class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
  1382. {
  1383. };
  1384. // ********************************************************
  1385. //! _
  1386. template <class T>
  1387. class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain
  1388. {
  1389. public:
  1390. typedef T Element;
  1391. CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
  1392. unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
  1393. unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
  1394. unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
  1395. void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
  1396. {
  1397. Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
  1398. x.Encode(privateKey, PrivateKeyLength());
  1399. }
  1400. void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
  1401. {
  1402. CRYPTOPP_UNUSED(rng);
  1403. const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
  1404. Integer x(privateKey, PrivateKeyLength());
  1405. Element y = params.ExponentiateBase(x);
  1406. params.EncodeElement(true, y, publicKey);
  1407. }
  1408. bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
  1409. {
  1410. try
  1411. {
  1412. const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
  1413. Integer x(privateKey, PrivateKeyLength());
  1414. Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
  1415. Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
  1416. GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
  1417. params.EncodeElement(false, z, agreedValue);
  1418. }
  1419. catch (DL_BadElement &)
  1420. {
  1421. return false;
  1422. }
  1423. return true;
  1424. }
  1425. const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
  1426. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1427. virtual ~DL_SimpleKeyAgreementDomainBase() { }
  1428. #endif
  1429. protected:
  1430. virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
  1431. virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
  1432. const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
  1433. };
  1434. enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION};
  1435. typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication;
  1436. typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication;
  1437. typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication;
  1438. //! DH key agreement algorithm
  1439. template <class ELEMENT, class COFACTOR_OPTION>
  1440. class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT>
  1441. {
  1442. public:
  1443. typedef ELEMENT Element;
  1444. static const char * CRYPTOPP_API StaticAlgorithmName()
  1445. {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
  1446. Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
  1447. {
  1448. return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
  1449. COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
  1450. }
  1451. Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
  1452. {
  1453. if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
  1454. {
  1455. const Integer &k = params.GetCofactor();
  1456. return params.ExponentiateElement(publicElement,
  1457. ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
  1458. }
  1459. else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
  1460. return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
  1461. else
  1462. {
  1463. assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
  1464. if (!validateOtherPublicKey)
  1465. return params.ExponentiateElement(publicElement, privateExponent);
  1466. if (params.FastSubgroupCheckAvailable())
  1467. {
  1468. if (!params.ValidateElement(2, publicElement, NULL))
  1469. throw DL_BadElement();
  1470. return params.ExponentiateElement(publicElement, privateExponent);
  1471. }
  1472. else
  1473. {
  1474. const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
  1475. Element r[2];
  1476. params.SimultaneousExponentiate(r, publicElement, e, 2);
  1477. if (!params.IsIdentity(r[0]))
  1478. throw DL_BadElement();
  1479. return r[1];
  1480. }
  1481. }
  1482. }
  1483. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  1484. virtual ~DL_KeyAgreementAlgorithm_DH() {}
  1485. #endif
  1486. };
  1487. // ********************************************************
  1488. //! A template implementing constructors for public key algorithm classes
  1489. template <class BASE>
  1490. class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
  1491. {
  1492. public:
  1493. PK_FinalTemplate() {}
  1494. PK_FinalTemplate(const CryptoMaterial &key)
  1495. {this->AccessKey().AssignFrom(key);}
  1496. PK_FinalTemplate(BufferedTransformation &bt)
  1497. {this->AccessKey().BERDecode(bt);}
  1498. PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
  1499. {this->AccessKey().AssignFrom(algorithm.GetMaterial());}
  1500. PK_FinalTemplate(const Integer &v1)
  1501. {this->AccessKey().Initialize(v1);}
  1502. #if (defined(_MSC_VER) && _MSC_VER < 1300)
  1503. template <class T1, class T2>
  1504. PK_FinalTemplate(T1 &v1, T2 &v2)
  1505. {this->AccessKey().Initialize(v1, v2);}
  1506. template <class T1, class T2, class T3>
  1507. PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3)
  1508. {this->AccessKey().Initialize(v1, v2, v3);}
  1509. template <class T1, class T2, class T3, class T4>
  1510. PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4)
  1511. {this->AccessKey().Initialize(v1, v2, v3, v4);}
  1512. template <class T1, class T2, class T3, class T4, class T5>
  1513. PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5)
  1514. {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
  1515. template <class T1, class T2, class T3, class T4, class T5, class T6>
  1516. PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6)
  1517. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
  1518. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
  1519. PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7)
  1520. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
  1521. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
  1522. PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
  1523. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
  1524. #else
  1525. template <class T1, class T2>
  1526. PK_FinalTemplate(const T1 &v1, const T2 &v2)
  1527. {this->AccessKey().Initialize(v1, v2);}
  1528. template <class T1, class T2, class T3>
  1529. PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
  1530. {this->AccessKey().Initialize(v1, v2, v3);}
  1531. template <class T1, class T2, class T3, class T4>
  1532. PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
  1533. {this->AccessKey().Initialize(v1, v2, v3, v4);}
  1534. template <class T1, class T2, class T3, class T4, class T5>
  1535. PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
  1536. {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
  1537. template <class T1, class T2, class T3, class T4, class T5, class T6>
  1538. PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
  1539. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
  1540. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
  1541. PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
  1542. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
  1543. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
  1544. 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)
  1545. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
  1546. template <class T1, class T2>
  1547. PK_FinalTemplate(T1 &v1, const T2 &v2)
  1548. {this->AccessKey().Initialize(v1, v2);}
  1549. template <class T1, class T2, class T3>
  1550. PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
  1551. {this->AccessKey().Initialize(v1, v2, v3);}
  1552. template <class T1, class T2, class T3, class T4>
  1553. PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
  1554. {this->AccessKey().Initialize(v1, v2, v3, v4);}
  1555. template <class T1, class T2, class T3, class T4, class T5>
  1556. PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
  1557. {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
  1558. template <class T1, class T2, class T3, class T4, class T5, class T6>
  1559. PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
  1560. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
  1561. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
  1562. PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
  1563. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
  1564. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
  1565. 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)
  1566. {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
  1567. #endif
  1568. };
  1569. //! \brief Base class for public key encryption standard classes.
  1570. //! \details These classes are used to select from variants of algorithms.
  1571. //! \note Not all standards apply to all algorithms.
  1572. struct EncryptionStandard {};
  1573. //! \brief Base class for public key signature standard classes.
  1574. //! \details These classes are used to select from variants of algorithms.
  1575. //! \note Not all standards apply to all algorithms.
  1576. struct SignatureStandard {};
  1577. template <class STANDARD, class KEYS, class ALG_INFO>
  1578. class TF_ES;
  1579. //! Trapdoor Function Based Encryption Scheme
  1580. template <class STANDARD, class KEYS, class ALG_INFO = TF_ES<STANDARD, KEYS, int> >
  1581. class TF_ES : public KEYS
  1582. {
  1583. typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
  1584. public:
  1585. //! see EncryptionStandard for a list of standards
  1586. typedef STANDARD Standard;
  1587. typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions;
  1588. static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
  1589. //! implements PK_Decryptor interface
  1590. typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor;
  1591. //! implements PK_Encryptor interface
  1592. typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor;
  1593. };
  1594. template <class STANDARD, class H, class KEYS, class ALG_INFO> // VC60 workaround: doesn't work if KEYS is first parameter
  1595. class TF_SS;
  1596. //! Trapdoor Function Based Signature Scheme
  1597. template <class STANDARD, class H, class KEYS, class ALG_INFO = TF_SS<STANDARD, H, KEYS, int> > // VC60 workaround: doesn't work if KEYS is first parameter
  1598. class TF_SS : public KEYS
  1599. {
  1600. public:
  1601. //! see SignatureStandard for a list of standards
  1602. typedef STANDARD Standard;
  1603. typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
  1604. typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
  1605. static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
  1606. //! implements PK_Signer interface
  1607. typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer;
  1608. //! implements PK_Verifier interface
  1609. typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier;
  1610. };
  1611. template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
  1612. class DL_SS;
  1613. //! Discrete Log Based Signature Scheme
  1614. template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
  1615. class DL_SS : public KEYS
  1616. {
  1617. typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
  1618. public:
  1619. static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
  1620. //! implements PK_Signer interface
  1621. typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
  1622. //! implements PK_Verifier interface
  1623. typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
  1624. };
  1625. //! Discrete Log Based Encryption Scheme
  1626. template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
  1627. class DL_ES : public KEYS
  1628. {
  1629. typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions;
  1630. public:
  1631. //! implements PK_Decryptor interface
  1632. typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor;
  1633. //! implements PK_Encryptor interface
  1634. typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor;
  1635. };
  1636. NAMESPACE_END
  1637. #if CRYPTOPP_MSC_VERSION
  1638. # pragma warning(pop)
  1639. #endif
  1640. #endif