Counter Strike : Global Offensive Source Code
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.

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