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