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.

536 lines
19 KiB

  1. #ifndef CRYPTOPP_GFPCRYPT_H
  2. #define CRYPTOPP_GFPCRYPT_H
  3. /** \file
  4. Implementation of schemes based on DL over GF(p)
  5. */
  6. #include "pubkey.h"
  7. #include "modexppc.h"
  8. #include "sha.h"
  9. #include "algparam.h"
  10. #include "asn.h"
  11. #include "smartptr.h"
  12. #include "hmac.h"
  13. #include <limits.h>
  14. NAMESPACE_BEGIN(CryptoPP)
  15. CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters<Integer>;
  16. //! _
  17. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial<DL_GroupParameters<Integer> >
  18. {
  19. typedef DL_GroupParameters_IntegerBased ThisClass;
  20. public:
  21. void Initialize(const DL_GroupParameters_IntegerBased &params)
  22. {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());}
  23. void Initialize(RandomNumberGenerator &rng, unsigned int pbits)
  24. {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));}
  25. void Initialize(const Integer &p, const Integer &g)
  26. {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);}
  27. void Initialize(const Integer &p, const Integer &q, const Integer &g)
  28. {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);}
  29. // ASN1Object interface
  30. void BERDecode(BufferedTransformation &bt);
  31. void DEREncode(BufferedTransformation &bt) const;
  32. // GeneratibleCryptoMaterial interface
  33. /*! parameters: (ModulusSize, SubgroupOrderSize (optional)) */
  34. void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
  35. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
  36. void AssignFrom(const NameValuePairs &source);
  37. // DL_GroupParameters
  38. const Integer & GetSubgroupOrder() const {return m_q;}
  39. Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();}
  40. bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
  41. bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const;
  42. bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;}
  43. void EncodeElement(bool reversible, const Element &element, byte *encoded) const
  44. {element.Encode(encoded, GetModulus().ByteCount());}
  45. unsigned int GetEncodedElementSize(bool reversible) const {return GetModulus().ByteCount();}
  46. Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const;
  47. Integer ConvertElementToInteger(const Element &element) const
  48. {return element;}
  49. Integer GetMaxExponent() const;
  50. static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
  51. OID GetAlgorithmID() const;
  52. virtual const Integer & GetModulus() const =0;
  53. virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0;
  54. void SetSubgroupOrder(const Integer &q)
  55. {m_q = q; ParametersChanged();}
  56. protected:
  57. Integer ComputeGroupOrder(const Integer &modulus) const
  58. {return modulus-(GetFieldType() == 1 ? 1 : -1);}
  59. // GF(p) = 1, GF(p^2) = 2
  60. virtual int GetFieldType() const =0;
  61. virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const;
  62. private:
  63. Integer m_q;
  64. };
  65. //! _
  66. template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element> >
  67. class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl<GROUP_PRECOMP, BASE_PRECOMP, DL_GroupParameters_IntegerBased>
  68. {
  69. typedef DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> ThisClass;
  70. public:
  71. typedef typename GROUP_PRECOMP::Element Element;
  72. // GeneratibleCryptoMaterial interface
  73. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  74. {return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();}
  75. void AssignFrom(const NameValuePairs &source)
  76. {AssignFromHelper<DL_GroupParameters_IntegerBased>(this, source);}
  77. // DL_GroupParameters
  78. const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
  79. DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;}
  80. // IntegerGroupParameters
  81. const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();}
  82. const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());}
  83. void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together
  84. {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();}
  85. // non-inherited
  86. bool operator==(const DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> &rhs) const
  87. {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();}
  88. bool operator!=(const DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> &rhs) const
  89. {return !operator==(rhs);}
  90. };
  91. CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>;
  92. //! GF(p) group parameters
  93. class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>
  94. {
  95. public:
  96. // DL_GroupParameters
  97. bool IsIdentity(const Integer &element) const {return element == Integer::One();}
  98. void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
  99. // NameValuePairs interface
  100. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  101. {
  102. return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();
  103. }
  104. // used by MQV
  105. Element MultiplyElements(const Element &a, const Element &b) const;
  106. Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
  107. protected:
  108. int GetFieldType() const {return 1;}
  109. };
  110. //! GF(p) group parameters that default to same primes
  111. class CRYPTOPP_DLL DL_GroupParameters_GFP_DefaultSafePrime : public DL_GroupParameters_GFP
  112. {
  113. public:
  114. typedef NoCofactorMultiplication DefaultCofactorOption;
  115. protected:
  116. unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;}
  117. };
  118. //! GDSA algorithm
  119. template <class T>
  120. class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm<T>
  121. {
  122. public:
  123. static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";}
  124. void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
  125. {
  126. const Integer &q = params.GetSubgroupOrder();
  127. r %= q;
  128. Integer kInv = k.InverseMod(q);
  129. s = (kInv * (x*r + e)) % q;
  130. assert(!!r && !!s);
  131. }
  132. bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
  133. {
  134. const Integer &q = params.GetSubgroupOrder();
  135. if (r>=q || r<1 || s>=q || s<1)
  136. return false;
  137. Integer w = s.InverseMod(q);
  138. Integer u1 = (e * w) % q;
  139. Integer u2 = (r * w) % q;
  140. // verify r == (g^u1 * y^u2 mod p) mod q
  141. return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
  142. }
  143. };
  144. CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer>;
  145. //! NR algorithm
  146. template <class T>
  147. class DL_Algorithm_NR : public DL_ElgamalLikeSignatureAlgorithm<T>
  148. {
  149. public:
  150. static const char * CRYPTOPP_API StaticAlgorithmName() {return "NR";}
  151. void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
  152. {
  153. const Integer &q = params.GetSubgroupOrder();
  154. r = (r + e) % q;
  155. s = (k - x*r) % q;
  156. assert(!!r);
  157. }
  158. bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
  159. {
  160. const Integer &q = params.GetSubgroupOrder();
  161. if (r>=q || r<1 || s>=q)
  162. return false;
  163. // check r == (m_g^s * m_y^r + m) mod m_q
  164. return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q;
  165. }
  166. };
  167. /*! DSA public key format is defined in 7.3.3 of RFC 2459. The
  168. private key format is defined in 12.9 of PKCS #11 v2.10. */
  169. template <class GP>
  170. class DL_PublicKey_GFP : public DL_PublicKeyImpl<GP>
  171. {
  172. public:
  173. void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &y)
  174. {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);}
  175. void Initialize(const Integer &p, const Integer &g, const Integer &y)
  176. {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);}
  177. void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
  178. {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);}
  179. // X509PublicKey
  180. void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t)
  181. {this->SetPublicElement(Integer(bt));}
  182. void DEREncodePublicKey(BufferedTransformation &bt) const
  183. {this->GetPublicElement().DEREncode(bt);}
  184. };
  185. //! DL private key (in GF(p) groups)
  186. template <class GP>
  187. class DL_PrivateKey_GFP : public DL_PrivateKeyImpl<GP>
  188. {
  189. public:
  190. void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
  191. {this->GenerateRandomWithKeySize(rng, modulusBits);}
  192. void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
  193. {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));}
  194. void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g)
  195. {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));}
  196. void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &x)
  197. {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);}
  198. void Initialize(const Integer &p, const Integer &g, const Integer &x)
  199. {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);}
  200. void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x)
  201. {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);}
  202. };
  203. //! DL signing/verification keys (in GF(p) groups)
  204. struct DL_SignatureKeys_GFP
  205. {
  206. typedef DL_GroupParameters_GFP GroupParameters;
  207. typedef DL_PublicKey_GFP<GroupParameters> PublicKey;
  208. typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey;
  209. };
  210. //! DL encryption/decryption keys (in GF(p) groups)
  211. struct DL_CryptoKeys_GFP
  212. {
  213. typedef DL_GroupParameters_GFP_DefaultSafePrime GroupParameters;
  214. typedef DL_PublicKey_GFP<GroupParameters> PublicKey;
  215. typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey;
  216. };
  217. //! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format
  218. template <class BASE>
  219. class DL_PublicKey_GFP_OldFormat : public BASE
  220. {
  221. public:
  222. void BERDecode(BufferedTransformation &bt)
  223. {
  224. BERSequenceDecoder seq(bt);
  225. Integer v1(seq);
  226. Integer v2(seq);
  227. Integer v3(seq);
  228. if (seq.EndReached())
  229. {
  230. this->AccessGroupParameters().Initialize(v1, v1/2, v2);
  231. this->SetPublicElement(v3);
  232. }
  233. else
  234. {
  235. Integer v4(seq);
  236. this->AccessGroupParameters().Initialize(v1, v2, v3);
  237. this->SetPublicElement(v4);
  238. }
  239. seq.MessageEnd();
  240. }
  241. void DEREncode(BufferedTransformation &bt) const
  242. {
  243. DERSequenceEncoder seq(bt);
  244. this->GetGroupParameters().GetModulus().DEREncode(seq);
  245. if (this->GetGroupParameters().GetCofactor() != 2)
  246. this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
  247. this->GetGroupParameters().GetGenerator().DEREncode(seq);
  248. this->GetPublicElement().DEREncode(seq);
  249. seq.MessageEnd();
  250. }
  251. };
  252. //! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format
  253. template <class BASE>
  254. class DL_PrivateKey_GFP_OldFormat : public BASE
  255. {
  256. public:
  257. void BERDecode(BufferedTransformation &bt)
  258. {
  259. BERSequenceDecoder seq(bt);
  260. Integer v1(seq);
  261. Integer v2(seq);
  262. Integer v3(seq);
  263. Integer v4(seq);
  264. if (seq.EndReached())
  265. {
  266. this->AccessGroupParameters().Initialize(v1, v1/2, v2);
  267. this->SetPrivateExponent(v4 % (v1/2)); // some old keys may have x >= q
  268. }
  269. else
  270. {
  271. Integer v5(seq);
  272. this->AccessGroupParameters().Initialize(v1, v2, v3);
  273. this->SetPrivateExponent(v5);
  274. }
  275. seq.MessageEnd();
  276. }
  277. void DEREncode(BufferedTransformation &bt) const
  278. {
  279. DERSequenceEncoder seq(bt);
  280. this->GetGroupParameters().GetModulus().DEREncode(seq);
  281. if (this->GetGroupParameters().GetCofactor() != 2)
  282. this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
  283. this->GetGroupParameters().GetGenerator().DEREncode(seq);
  284. this->GetGroupParameters().ExponentiateBase(this->GetPrivateExponent()).DEREncode(seq);
  285. this->GetPrivateExponent().DEREncode(seq);
  286. seq.MessageEnd();
  287. }
  288. };
  289. //! <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a>
  290. template <class H>
  291. struct GDSA : public DL_SS<
  292. DL_SignatureKeys_GFP,
  293. DL_Algorithm_GDSA<Integer>,
  294. DL_SignatureMessageEncodingMethod_DSA,
  295. H>
  296. {
  297. };
  298. //! <a href="http://www.weidai.com/scan-mirror/sig.html#NR">NR</a>
  299. template <class H>
  300. struct NR : public DL_SS<
  301. DL_SignatureKeys_GFP,
  302. DL_Algorithm_NR<Integer>,
  303. DL_SignatureMessageEncodingMethod_NR,
  304. H>
  305. {
  306. };
  307. //! DSA group parameters, these are GF(p) group parameters that are allowed by the DSA standard
  308. class CRYPTOPP_DLL DL_GroupParameters_DSA : public DL_GroupParameters_GFP
  309. {
  310. public:
  311. /*! also checks that the lengths of p and q are allowed by the DSA standard */
  312. bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
  313. /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */
  314. /*! ModulusSize must be between DSA::MIN_PRIME_LENGTH and DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE */
  315. void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
  316. };
  317. struct DSA;
  318. //! DSA keys
  319. struct DL_Keys_DSA
  320. {
  321. typedef DL_PublicKey_GFP<DL_GroupParameters_DSA> PublicKey;
  322. typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA> PrivateKey;
  323. };
  324. //! <a href="http://www.weidai.com/scan-mirror/sig.html#DSA">DSA</a>
  325. struct CRYPTOPP_DLL DSA : public DL_SS<
  326. DL_Keys_DSA,
  327. DL_Algorithm_GDSA<Integer>,
  328. DL_SignatureMessageEncodingMethod_DSA,
  329. SHA,
  330. DSA>
  331. {
  332. static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA";}
  333. //! Generate DSA primes according to NIST standard
  334. /*! Both seedLength and primeLength are in bits, but seedLength should
  335. be a multiple of 8.
  336. If useInputCounterValue == true, the counter parameter is taken as input, otherwise it's used for output
  337. */
  338. static bool CRYPTOPP_API GeneratePrimes(const byte *seed, unsigned int seedLength, int &counter,
  339. Integer &p, unsigned int primeLength, Integer &q, bool useInputCounterValue = false);
  340. static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits)
  341. {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;}
  342. //! FIPS 186-2 Change Notice 1 changed the minimum modulus length to 1024
  343. enum {
  344. #if (DSA_1024_BIT_MODULUS_ONLY)
  345. MIN_PRIME_LENGTH = 1024,
  346. #else
  347. MIN_PRIME_LENGTH = 512,
  348. #endif
  349. MAX_PRIME_LENGTH = 1024, PRIME_LENGTH_MULTIPLE = 64};
  350. };
  351. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP<DL_GroupParameters_DSA>;
  352. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP<DL_GroupParameters_DSA>;
  353. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA>;
  354. //! the XOR encryption method, for use with DL-based cryptosystems
  355. template <class MAC, bool DHAES_MODE>
  356. class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm
  357. {
  358. public:
  359. bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
  360. size_t GetSymmetricKeyLength(size_t plaintextLength) const
  361. {return plaintextLength + MAC::DEFAULT_KEYLENGTH;}
  362. size_t GetSymmetricCiphertextLength(size_t plaintextLength) const
  363. {return plaintextLength + MAC::DIGESTSIZE;}
  364. size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const
  365. {return (unsigned int)SaturatingSubtract(ciphertextLength, (unsigned int)MAC::DIGESTSIZE);}
  366. void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
  367. {
  368. const byte *cipherKey, *macKey;
  369. if (DHAES_MODE)
  370. {
  371. macKey = key;
  372. cipherKey = key + MAC::DEFAULT_KEYLENGTH;
  373. }
  374. else
  375. {
  376. cipherKey = key;
  377. macKey = key + plaintextLength;
  378. }
  379. ConstByteArrayParameter encodingParameters;
  380. parameters.GetValue(Name::EncodingParameters(), encodingParameters);
  381. xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
  382. MAC mac(macKey);
  383. mac.Update(ciphertext, plaintextLength);
  384. mac.Update(encodingParameters.begin(), encodingParameters.size());
  385. if (DHAES_MODE)
  386. {
  387. byte L[8] = {0,0,0,0};
  388. PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
  389. mac.Update(L, 8);
  390. }
  391. mac.Final(ciphertext + plaintextLength);
  392. }
  393. DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
  394. {
  395. size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength);
  396. const byte *cipherKey, *macKey;
  397. if (DHAES_MODE)
  398. {
  399. macKey = key;
  400. cipherKey = key + MAC::DEFAULT_KEYLENGTH;
  401. }
  402. else
  403. {
  404. cipherKey = key;
  405. macKey = key + plaintextLength;
  406. }
  407. ConstByteArrayParameter encodingParameters;
  408. parameters.GetValue(Name::EncodingParameters(), encodingParameters);
  409. MAC mac(macKey);
  410. mac.Update(ciphertext, plaintextLength);
  411. mac.Update(encodingParameters.begin(), encodingParameters.size());
  412. if (DHAES_MODE)
  413. {
  414. byte L[8] = {0,0,0,0};
  415. PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
  416. mac.Update(L, 8);
  417. }
  418. if (!mac.Verify(ciphertext + plaintextLength))
  419. return DecodingResult();
  420. xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
  421. return DecodingResult(plaintextLength);
  422. }
  423. };
  424. //! _
  425. template <class T, bool DHAES_MODE, class KDF>
  426. class DL_KeyDerivationAlgorithm_P1363 : public DL_KeyDerivationAlgorithm<T>
  427. {
  428. public:
  429. bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;}
  430. void Derive(const DL_GroupParameters<T> &params, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &parameters) const
  431. {
  432. SecByteBlock agreedSecret;
  433. if (DHAES_MODE)
  434. {
  435. agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false));
  436. params.EncodeElement(true, ephemeralPublicKey, agreedSecret);
  437. params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true));
  438. }
  439. else
  440. {
  441. agreedSecret.New(params.GetEncodedElementSize(false));
  442. params.EncodeElement(false, agreedElement, agreedSecret);
  443. }
  444. ConstByteArrayParameter derivationParameters;
  445. parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters);
  446. KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size());
  447. }
  448. };
  449. //! Discrete Log Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#DLIES">DLIES</a>
  450. template <class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true>
  451. struct DLIES
  452. : public DL_ES<
  453. DL_CryptoKeys_GFP,
  454. DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>,
  455. DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<SHA1> >,
  456. DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
  457. DLIES<> >
  458. {
  459. static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized
  460. };
  461. NAMESPACE_END
  462. #endif