Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

gfpcrypt.h

Go to the documentation of this file.
00001 #ifndef CRYPTOPP_GFPCRYPT_H 00002 #define CRYPTOPP_GFPCRYPT_H 00003 00004 /** \file 00005 Implementation of schemes based on DL over GF(p) 00006 */ 00007 00008 #include "pubkey.h" 00009 #include "modexppc.h" 00010 #include "sha.h" 00011 #include "algparam.h" 00012 #include "asn.h" 00013 #include "smartptr.h" 00014 #include "hmac.h" 00015 00016 #include <limits.h> 00017 00018 NAMESPACE_BEGIN(CryptoPP) 00019 00020 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters<Integer>; 00021 00022 //! _ 00023 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public DL_GroupParameters<Integer>, public ASN1CryptoMaterial 00024 { 00025 typedef DL_GroupParameters_IntegerBased ThisClass; 00026 00027 public: 00028 void Initialize(const DL_GroupParameters_IntegerBased &params) 00029 {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());} 00030 void Initialize(RandomNumberGenerator &rng, unsigned int pbits) 00031 {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));} 00032 void Initialize(const Integer &p, const Integer &g) 00033 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);} 00034 void Initialize(const Integer &p, const Integer &q, const Integer &g) 00035 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);} 00036 00037 // ASN1Object interface 00038 void BERDecode(BufferedTransformation &bt); 00039 void DEREncode(BufferedTransformation &bt) const; 00040 00041 // GeneratibleCryptoMaterial interface 00042 /*! parameters: (ModulusSize, SubgroupOrderSize (optional)) */ 00043 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); 00044 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; 00045 void AssignFrom(const NameValuePairs &source); 00046 00047 // DL_GroupParameters 00048 const Integer & GetSubgroupOrder() const {return m_q;} 00049 Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();} 00050 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; 00051 bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const; 00052 bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;} 00053 void EncodeElement(bool reversible, const Element &element, byte *encoded) const 00054 {element.Encode(encoded, GetModulus().ByteCount());} 00055 unsigned int GetEncodedElementSize(bool reversible) const {return GetModulus().ByteCount();} 00056 Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const; 00057 Integer ConvertElementToInteger(const Element &element) const 00058 {return element;} 00059 Integer GetMaxExponent() const; 00060 static std::string StaticAlgorithmNamePrefix() {return "";} 00061 00062 OID GetAlgorithmID() const; 00063 00064 virtual const Integer & GetModulus() const =0; 00065 virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0; 00066 00067 void SetSubgroupOrder(const Integer &q) 00068 {m_q = q; ParametersChanged();} 00069 00070 protected: 00071 Integer ComputeGroupOrder(const Integer &modulus) const 00072 {return modulus-(GetFieldType() == 1 ? 1 : -1);} 00073 00074 // GF(p) = 1, GF(p^2) = 2 00075 virtual int GetFieldType() const =0; 00076 virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const; 00077 00078 private: 00079 Integer m_q; 00080 }; 00081 00082 //! _ 00083 template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element> > 00084 class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl<GROUP_PRECOMP, BASE_PRECOMP, DL_GroupParameters_IntegerBased> 00085 { 00086 typedef DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> ThisClass; 00087 00088 public: 00089 typedef typename GROUP_PRECOMP::Element Element; 00090 00091 // GeneratibleCryptoMaterial interface 00092 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const 00093 {return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();} 00094 00095 void AssignFrom(const NameValuePairs &source) 00096 {AssignFromHelper<DL_GroupParameters_IntegerBased>(this, source);} 00097 00098 // DL_GroupParameters 00099 const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;} 00100 DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;} 00101 00102 // IntegerGroupParameters 00103 const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();} 00104 const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());} 00105 00106 void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together 00107 {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();} 00108 00109 // non-inherited 00110 bool operator==(const DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> &rhs) const 00111 {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();} 00112 bool operator!=(const DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> &rhs) const 00113 {return !operator==(rhs);} 00114 }; 00115 00116 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>; 00117 00118 //! GF(p) group parameters 00119 class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation> 00120 { 00121 public: 00122 // DL_GroupParameters 00123 bool IsIdentity(const Integer &element) const {return element == Integer::One();} 00124 void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; 00125 00126 // NameValuePairs interface 00127 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const 00128 { 00129 return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable(); 00130 } 00131 00132 // used by MQV 00133 Element MultiplyElements(const Element &a, const Element &b) const; 00134 Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; 00135 00136 protected: 00137 int GetFieldType() const {return 1;} 00138 }; 00139 00140 //! GF(p) group parameters that default to same primes 00141 class CRYPTOPP_DLL DL_GroupParameters_GFP_DefaultSafePrime : public DL_GroupParameters_GFP 00142 { 00143 public: 00144 typedef NoCofactorMultiplication DefaultCofactorOption; 00145 00146 protected: 00147 unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;} 00148 }; 00149 00150 //! GDSA algorithm 00151 template <class T> 00152 class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm<T> 00153 { 00154 public: 00155 static const char * StaticAlgorithmName() {return "DSA-1363";} 00156 00157 void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const 00158 { 00159 const Integer &q = params.GetSubgroupOrder(); 00160 r %= q; 00161 Integer kInv = k.InverseMod(q); 00162 s = (kInv * (x*r + e)) % q; 00163 assert(!!r && !!s); 00164 } 00165 00166 bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const 00167 { 00168 const Integer &q = params.GetSubgroupOrder(); 00169 if (r>=q || r<1 || s>=q || s<1) 00170 return false; 00171 00172 Integer w = s.InverseMod(q); 00173 Integer u1 = (e * w) % q; 00174 Integer u2 = (r * w) % q; 00175 // verify r == (g^u1 * y^u2 mod p) mod q 00176 return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q; 00177 } 00178 }; 00179 00180 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer>; 00181 00182 //! NR algorithm 00183 template <class T> 00184 class DL_Algorithm_NR : public DL_ElgamalLikeSignatureAlgorithm<T> 00185 { 00186 public: 00187 static const char * StaticAlgorithmName() {return "NR";} 00188 00189 void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const 00190 { 00191 const Integer &q = params.GetSubgroupOrder(); 00192 r = (r + e) % q; 00193 s = (k - x*r) % q; 00194 assert(!!r); 00195 } 00196 00197 bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const 00198 { 00199 const Integer &q = params.GetSubgroupOrder(); 00200 if (r>=q || r<1 || s>=q) 00201 return false; 00202 00203 // check r == (m_g^s * m_y^r + m) mod m_q 00204 return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q; 00205 } 00206 }; 00207 00208 /*! DSA public key format is defined in 7.3.3 of RFC 2459. The 00209 private key format is defined in 12.9 of PKCS #11 v2.10. */ 00210 template <class GP> 00211 class DL_PublicKey_GFP : public DL_PublicKeyImpl<GP> 00212 { 00213 public: 00214 void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &y) 00215 {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);} 00216 void Initialize(const Integer &p, const Integer &g, const Integer &y) 00217 {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);} 00218 void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y) 00219 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);} 00220 00221 // X509PublicKey 00222 void BERDecodeKey(BufferedTransformation &bt) 00223 {this->SetPublicElement(Integer(bt));} 00224 void DEREncodeKey(BufferedTransformation &bt) const 00225 {this->GetPublicElement().DEREncode(bt);} 00226 }; 00227 00228 //! DL private key (in GF(p) groups) 00229 template <class GP> 00230 class DL_PrivateKey_GFP : public DL_PrivateKeyImpl<GP> 00231 { 00232 public: 00233 void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) 00234 {this->GenerateRandomWithKeySize(rng, modulusBits);} 00235 void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g) 00236 {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));} 00237 void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g) 00238 {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));} 00239 void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &x) 00240 {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);} 00241 void Initialize(const Integer &p, const Integer &g, const Integer &x) 00242 {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);} 00243 void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x) 00244 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);} 00245 }; 00246 00247 //! DL signing/verification keys (in GF(p) groups) 00248 struct DL_SignatureKeys_GFP 00249 { 00250 typedef DL_GroupParameters_GFP GroupParameters; 00251 typedef DL_PublicKey_GFP<GroupParameters> PublicKey; 00252 typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey; 00253 }; 00254 00255 //! DL encryption/decryption keys (in GF(p) groups) 00256 struct DL_CryptoKeys_GFP 00257 { 00258 typedef DL_GroupParameters_GFP_DefaultSafePrime GroupParameters; 00259 typedef DL_PublicKey_GFP<GroupParameters> PublicKey; 00260 typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey; 00261 }; 00262 00263 //! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format 00264 template <class BASE> 00265 class DL_PublicKey_GFP_OldFormat : public BASE 00266 { 00267 public: 00268 void BERDecode(BufferedTransformation &bt) 00269 { 00270 BERSequenceDecoder seq(bt); 00271 Integer v1(seq); 00272 Integer v2(seq); 00273 Integer v3(seq); 00274 00275 if (seq.EndReached()) 00276 { 00277 this->AccessGroupParameters().Initialize(v1, v1/2, v2); 00278 this->SetPublicElement(v3); 00279 } 00280 else 00281 { 00282 Integer v4(seq); 00283 this->AccessGroupParameters().Initialize(v1, v2, v3); 00284 this->SetPublicElement(v4); 00285 } 00286 00287 seq.MessageEnd(); 00288 } 00289 00290 void DEREncode(BufferedTransformation &bt) const 00291 { 00292 DERSequenceEncoder seq(bt); 00293 this->GetGroupParameters().GetModulus().DEREncode(seq); 00294 if (this->GetGroupParameters().GetCofactor() != 2) 00295 this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq); 00296 this->GetGroupParameters().GetGenerator().DEREncode(seq); 00297 this->GetPublicElement().DEREncode(seq); 00298 seq.MessageEnd(); 00299 } 00300 }; 00301 00302 //! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format 00303 template <class BASE> 00304 class DL_PrivateKey_GFP_OldFormat : public BASE 00305 { 00306 public: 00307 void BERDecode(BufferedTransformation &bt) 00308 { 00309 BERSequenceDecoder seq(bt); 00310 Integer v1(seq); 00311 Integer v2(seq); 00312 Integer v3(seq); 00313 Integer v4(seq); 00314 00315 if (seq.EndReached()) 00316 { 00317 this->AccessGroupParameters().Initialize(v1, v1/2, v2); 00318 this->SetPrivateExponent(v4 % (v1/2)); // some old keys may have x >= q 00319 } 00320 else 00321 { 00322 Integer v5(seq); 00323 this->AccessGroupParameters().Initialize(v1, v2, v3); 00324 this->SetPrivateExponent(v5); 00325 } 00326 00327 seq.MessageEnd(); 00328 } 00329 00330 void DEREncode(BufferedTransformation &bt) const 00331 { 00332 DERSequenceEncoder seq(bt); 00333 this->GetGroupParameters().GetModulus().DEREncode(seq); 00334 if (this->GetGroupParameters().GetCofactor() != 2) 00335 this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq); 00336 this->GetGroupParameters().GetGenerator().DEREncode(seq); 00337 this->GetGroupParameters().ExponentiateBase(this->GetPrivateExponent()).DEREncode(seq); 00338 this->GetPrivateExponent().DEREncode(seq); 00339 seq.MessageEnd(); 00340 } 00341 }; 00342 00343 //! <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a> 00344 template <class H> 00345 struct GDSA : public DL_SS< 00346 DL_SignatureKeys_GFP, 00347 DL_Algorithm_GDSA<Integer>, 00348 DL_SignatureMessageEncodingMethod_DSA, 00349 H> 00350 { 00351 }; 00352 00353 //! <a href="http://www.weidai.com/scan-mirror/sig.html#NR">NR</a> 00354 template <class H> 00355 struct NR : public DL_SS< 00356 DL_SignatureKeys_GFP, 00357 DL_Algorithm_NR<Integer>, 00358 DL_SignatureMessageEncodingMethod_NR, 00359 H> 00360 { 00361 }; 00362 00363 //! DSA group parameters, these are GF(p) group parameters that are allowed by the DSA standard 00364 class CRYPTOPP_DLL DL_GroupParameters_DSA : public DL_GroupParameters_GFP 00365 { 00366 public: 00367 /*! also checks that the lengths of p and q are allowed by the DSA standard */ 00368 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; 00369 /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */ 00370 /*! ModulusSize must be between DSA::MIN_PRIME_LENGTH and DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE */ 00371 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); 00372 }; 00373 00374 struct DSA; 00375 00376 //! DSA keys 00377 struct DL_Keys_DSA 00378 { 00379 typedef DL_PublicKey_GFP<DL_GroupParameters_DSA> PublicKey; 00380 typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA> PrivateKey; 00381 }; 00382 00383 //! <a href="http://www.weidai.com/scan-mirror/sig.html#DSA">DSA</a> 00384 struct CRYPTOPP_DLL DSA : public DL_SS< 00385 DL_Keys_DSA, 00386 DL_Algorithm_GDSA<Integer>, 00387 DL_SignatureMessageEncodingMethod_DSA, 00388 SHA, 00389 DSA> 00390 { 00391 static std::string StaticAlgorithmName() {return std::string("DSA");} 00392 00393 //! Generate DSA primes according to NIST standard 00394 /*! Both seedLength and primeLength are in bits, but seedLength should 00395 be a multiple of 8. 00396 If useInputCounterValue == true, the counter parameter is taken as input, otherwise it's used for output 00397 */ 00398 static bool GeneratePrimes(const byte *seed, unsigned int seedLength, int &counter, 00399 Integer &p, unsigned int primeLength, Integer &q, bool useInputCounterValue = false); 00400 00401 static bool IsValidPrimeLength(unsigned int pbits) 00402 {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} 00403 00404 //! FIPS 186-2 Change Notice 1 changed the minimum modulus length to 1024 00405 enum { 00406 #if (DSA_1024_BIT_MODULUS_ONLY) 00407 MIN_PRIME_LENGTH = 1024, 00408 #else 00409 MIN_PRIME_LENGTH = 512, 00410 #endif 00411 MAX_PRIME_LENGTH = 1024, PRIME_LENGTH_MULTIPLE = 64}; 00412 }; 00413 00414 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP<DL_GroupParameters_DSA>; 00415 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP<DL_GroupParameters_DSA>; 00416 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA>; 00417 00418 //! the XOR encryption method, for use with DL-based cryptosystems 00419 template <class MAC, bool DHAES_MODE> 00420 class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm 00421 { 00422 public: 00423 bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} 00424 unsigned int GetSymmetricKeyLength(unsigned int plaintextLength) const 00425 {return plaintextLength + MAC::DEFAULT_KEYLENGTH;} 00426 unsigned int GetSymmetricCiphertextLength(unsigned int plaintextLength) const 00427 {return plaintextLength + MAC::DIGESTSIZE;} 00428 unsigned int GetMaxSymmetricPlaintextLength(unsigned int ciphertextLength) const 00429 {return SaturatingSubtract(ciphertextLength, (unsigned int)MAC::DIGESTSIZE);} 00430 void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const 00431 { 00432 const byte *cipherKey, *macKey; 00433 if (DHAES_MODE) 00434 { 00435 macKey = key; 00436 cipherKey = key + MAC::DEFAULT_KEYLENGTH; 00437 } 00438 else 00439 { 00440 cipherKey = key; 00441 macKey = key + plaintextLength; 00442 } 00443 00444 ConstByteArrayParameter encodingParameters; 00445 parameters.GetValue(Name::EncodingParameters(), encodingParameters); 00446 00447 xorbuf(ciphertext, plaintext, cipherKey, plaintextLength); 00448 MAC mac(macKey); 00449 mac.Update(ciphertext, plaintextLength); 00450 mac.Update(encodingParameters.begin(), encodingParameters.size()); 00451 if (DHAES_MODE) 00452 { 00453 byte L[8] = {0,0,0,0}; 00454 UnalignedPutWord(BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); 00455 mac.Update(L, 8); 00456 } 00457 mac.Final(ciphertext + plaintextLength); 00458 } 00459 DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const 00460 { 00461 unsigned int plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength); 00462 const byte *cipherKey, *macKey; 00463 if (DHAES_MODE) 00464 { 00465 macKey = key; 00466 cipherKey = key + MAC::DEFAULT_KEYLENGTH; 00467 } 00468 else 00469 { 00470 cipherKey = key; 00471 macKey = key + plaintextLength; 00472 } 00473 00474 ConstByteArrayParameter encodingParameters; 00475 parameters.GetValue(Name::EncodingParameters(), encodingParameters); 00476 00477 MAC mac(macKey); 00478 mac.Update(ciphertext, plaintextLength); 00479 mac.Update(encodingParameters.begin(), encodingParameters.size()); 00480 if (DHAES_MODE) 00481 { 00482 byte L[8] = {0,0,0,0}; 00483 UnalignedPutWord(BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); 00484 mac.Update(L, 8); 00485 } 00486 if (!mac.Verify(ciphertext + plaintextLength)) 00487 return DecodingResult(); 00488 00489 xorbuf(plaintext, ciphertext, cipherKey, plaintextLength); 00490 return DecodingResult(plaintextLength); 00491 } 00492 }; 00493 00494 //! _ 00495 template <class T, bool DHAES_MODE, class KDF> 00496 class DL_KeyDerivationAlgorithm_P1363 : public DL_KeyDerivationAlgorithm<T> 00497 { 00498 public: 00499 bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;} 00500 void Derive(const DL_GroupParameters<T> &params, byte *derivedKey, unsigned int derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &parameters) const 00501 { 00502 SecByteBlock agreedSecret; 00503 if (DHAES_MODE) 00504 { 00505 agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false)); 00506 params.EncodeElement(true, ephemeralPublicKey, agreedSecret); 00507 params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true)); 00508 } 00509 else 00510 { 00511 agreedSecret.New(params.GetEncodedElementSize(false)); 00512 params.EncodeElement(false, agreedElement, agreedSecret); 00513 } 00514 00515 ConstByteArrayParameter derivationParameters; 00516 parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters); 00517 KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size()); 00518 } 00519 }; 00520 00521 //! Discrete Log Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#DLIES">DLIES</a> 00522 template <class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true> 00523 struct DLIES 00524 : public DL_ES< 00525 DL_CryptoKeys_GFP, 00526 DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>, 00527 DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<SHA1> >, 00528 DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>, 00529 DLIES<> > 00530 { 00531 static std::string StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized 00532 }; 00533 00534 NAMESPACE_END 00535 00536 #endif

Generated on Fri Aug 27 14:00:19 2004 for Crypto++ by doxygen 1.3.8