00001 #ifndef CRYPTOPP_GFPCRYPT_H
00002 #define CRYPTOPP_GFPCRYPT_H
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #if CRYPTOPP_MSC_VERSION
00011 # pragma warning(push)
00012 # pragma warning(disable: 4189)
00013 #endif
00014
00015 #include "cryptlib.h"
00016 #include "pubkey.h"
00017 #include "integer.h"
00018 #include "modexppc.h"
00019 #include "algparam.h"
00020 #include "smartptr.h"
00021 #include "sha.h"
00022 #include "asn.h"
00023 #include "hmac.h"
00024 #include "misc.h"
00025
00026 NAMESPACE_BEGIN(CryptoPP)
00027
00028 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters<Integer>;
00029
00030
00031 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial<DL_GroupParameters<Integer> >
00032 {
00033 typedef DL_GroupParameters_IntegerBased ThisClass;
00034
00035 public:
00036 void Initialize(const DL_GroupParameters_IntegerBased ¶ms)
00037 {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());}
00038 void Initialize(RandomNumberGenerator &rng, unsigned int pbits)
00039 {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));}
00040 void Initialize(const Integer &p, const Integer &g)
00041 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);}
00042 void Initialize(const Integer &p, const Integer &q, const Integer &g)
00043 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);}
00044
00045
00046 void BERDecode(BufferedTransformation &bt);
00047 void DEREncode(BufferedTransformation &bt) const;
00048
00049
00050
00051 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
00052 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
00053 void AssignFrom(const NameValuePairs &source);
00054
00055
00056 const Integer & GetSubgroupOrder() const {return m_q;}
00057 Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();}
00058 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
00059 bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const;
00060 bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;}
00061
00062 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00063
00064 void EncodeElement(bool reversible, const Element &element, byte *encoded) const;
00065 unsigned int GetEncodedElementSize(bool reversible) const;
00066 #else
00067 void EncodeElement(bool reversible, const Element &element, byte *encoded) const
00068 {CRYPTOPP_UNUSED(reversible); element.Encode(encoded, GetModulus().ByteCount());}
00069 unsigned int GetEncodedElementSize(bool reversible) const
00070 {CRYPTOPP_UNUSED(reversible); return GetModulus().ByteCount();}
00071 #endif
00072
00073 Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const;
00074 Integer ConvertElementToInteger(const Element &element) const
00075 {return element;}
00076 Integer GetMaxExponent() const;
00077 static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
00078
00079 OID GetAlgorithmID() const;
00080
00081 virtual const Integer & GetModulus() const =0;
00082 virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0;
00083
00084 void SetSubgroupOrder(const Integer &q)
00085 {m_q = q; ParametersChanged();}
00086
00087 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00088 virtual ~DL_GroupParameters_IntegerBased() {}
00089 #endif
00090
00091 protected:
00092 Integer ComputeGroupOrder(const Integer &modulus) const
00093 {return modulus-(GetFieldType() == 1 ? 1 : -1);}
00094
00095
00096 virtual int GetFieldType() const =0;
00097 virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const;
00098
00099 private:
00100 Integer m_q;
00101 };
00102
00103
00104 template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element> >
00105 class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl<GROUP_PRECOMP, BASE_PRECOMP, DL_GroupParameters_IntegerBased>
00106 {
00107 typedef DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> ThisClass;
00108
00109 public:
00110 typedef typename GROUP_PRECOMP::Element Element;
00111
00112
00113 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00114 {return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();}
00115
00116 void AssignFrom(const NameValuePairs &source)
00117 {AssignFromHelper<DL_GroupParameters_IntegerBased>(this, source);}
00118
00119
00120 const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
00121 DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;}
00122
00123
00124 const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();}
00125 const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());}
00126
00127 void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g)
00128 {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();}
00129
00130
00131 bool operator==(const DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> &rhs) const
00132 {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();}
00133 bool operator!=(const DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> &rhs) const
00134 {return !operator==(rhs);}
00135
00136 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00137 virtual ~DL_GroupParameters_IntegerBasedImpl() {}
00138 #endif
00139 };
00140
00141 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>;
00142
00143
00144 class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>
00145 {
00146 public:
00147
00148 bool IsIdentity(const Integer &element) const {return element == Integer::One();}
00149 void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
00150
00151
00152 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00153 {
00154 return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();
00155 }
00156
00157
00158 Element MultiplyElements(const Element &a, const Element &b) const;
00159 Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
00160
00161 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00162 virtual ~DL_GroupParameters_GFP() {}
00163 #endif
00164
00165 protected:
00166 int GetFieldType() const {return 1;}
00167 };
00168
00169
00170 class CRYPTOPP_DLL DL_GroupParameters_GFP_DefaultSafePrime : public DL_GroupParameters_GFP
00171 {
00172 public:
00173 typedef NoCofactorMultiplication DefaultCofactorOption;
00174
00175 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00176 virtual ~DL_GroupParameters_GFP_DefaultSafePrime() {}
00177 #endif
00178
00179 protected:
00180 unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;}
00181 };
00182
00183
00184 template <class T>
00185 class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm<T>
00186 {
00187 public:
00188 static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";}
00189
00190 void Sign(const DL_GroupParameters<T> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
00191 {
00192 const Integer &q = params.GetSubgroupOrder();
00193 r %= q;
00194 Integer kInv = k.InverseMod(q);
00195 s = (kInv * (x*r + e)) % q;
00196 assert(!!r && !!s);
00197 }
00198
00199 bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
00200 {
00201 const Integer &q = params.GetSubgroupOrder();
00202 if (r>=q || r<1 || s>=q || s<1)
00203 return false;
00204
00205 Integer w = s.InverseMod(q);
00206 Integer u1 = (e * w) % q;
00207 Integer u2 = (r * w) % q;
00208
00209 return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
00210 }
00211
00212 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00213 virtual ~DL_Algorithm_GDSA() {}
00214 #endif
00215 };
00216
00217 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer>;
00218
00219
00220 template <class T>
00221 class DL_Algorithm_NR : public DL_ElgamalLikeSignatureAlgorithm<T>
00222 {
00223 public:
00224 static const char * CRYPTOPP_API StaticAlgorithmName() {return "NR";}
00225
00226 void Sign(const DL_GroupParameters<T> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
00227 {
00228 const Integer &q = params.GetSubgroupOrder();
00229 r = (r + e) % q;
00230 s = (k - x*r) % q;
00231 assert(!!r);
00232 }
00233
00234 bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
00235 {
00236 const Integer &q = params.GetSubgroupOrder();
00237 if (r>=q || r<1 || s>=q)
00238 return false;
00239
00240
00241 return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q;
00242 }
00243
00244 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00245 virtual ~DL_Algorithm_NR() {}
00246 #endif
00247 };
00248
00249
00250
00251 template <class GP>
00252 class DL_PublicKey_GFP : public DL_PublicKeyImpl<GP>
00253 {
00254 public:
00255 void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &y)
00256 {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);}
00257 void Initialize(const Integer &p, const Integer &g, const Integer &y)
00258 {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);}
00259 void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
00260 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);}
00261
00262
00263 void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t)
00264 {this->SetPublicElement(Integer(bt));}
00265 void DEREncodePublicKey(BufferedTransformation &bt) const
00266 {this->GetPublicElement().DEREncode(bt);}
00267
00268 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00269 virtual ~DL_PublicKey_GFP() {}
00270 #endif
00271 };
00272
00273
00274 template <class GP>
00275 class DL_PrivateKey_GFP : public DL_PrivateKeyImpl<GP>
00276 {
00277 public:
00278 void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
00279 {this->GenerateRandomWithKeySize(rng, modulusBits);}
00280 void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
00281 {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));}
00282 void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g)
00283 {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));}
00284 void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &x)
00285 {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);}
00286 void Initialize(const Integer &p, const Integer &g, const Integer &x)
00287 {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);}
00288 void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x)
00289 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);}
00290
00291 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00292 virtual ~DL_PrivateKey_GFP() {}
00293 #endif
00294 };
00295
00296
00297 struct DL_SignatureKeys_GFP
00298 {
00299 typedef DL_GroupParameters_GFP GroupParameters;
00300 typedef DL_PublicKey_GFP<GroupParameters> PublicKey;
00301 typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey;
00302
00303 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00304 virtual ~DL_SignatureKeys_GFP() {}
00305 #endif
00306 };
00307
00308
00309 struct DL_CryptoKeys_GFP
00310 {
00311 typedef DL_GroupParameters_GFP_DefaultSafePrime GroupParameters;
00312 typedef DL_PublicKey_GFP<GroupParameters> PublicKey;
00313 typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey;
00314
00315 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00316 virtual ~DL_CryptoKeys_GFP() {}
00317 #endif
00318 };
00319
00320
00321 template <class BASE>
00322 class DL_PublicKey_GFP_OldFormat : public BASE
00323 {
00324 public:
00325 void BERDecode(BufferedTransformation &bt)
00326 {
00327 BERSequenceDecoder seq(bt);
00328 Integer v1(seq);
00329 Integer v2(seq);
00330 Integer v3(seq);
00331
00332 if (seq.EndReached())
00333 {
00334 this->AccessGroupParameters().Initialize(v1, v1/2, v2);
00335 this->SetPublicElement(v3);
00336 }
00337 else
00338 {
00339 Integer v4(seq);
00340 this->AccessGroupParameters().Initialize(v1, v2, v3);
00341 this->SetPublicElement(v4);
00342 }
00343
00344 seq.MessageEnd();
00345 }
00346
00347 void DEREncode(BufferedTransformation &bt) const
00348 {
00349 DERSequenceEncoder seq(bt);
00350 this->GetGroupParameters().GetModulus().DEREncode(seq);
00351 if (this->GetGroupParameters().GetCofactor() != 2)
00352 this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
00353 this->GetGroupParameters().GetGenerator().DEREncode(seq);
00354 this->GetPublicElement().DEREncode(seq);
00355 seq.MessageEnd();
00356 }
00357
00358 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00359 virtual ~DL_PublicKey_GFP_OldFormat() {}
00360 #endif
00361 };
00362
00363
00364 template <class BASE>
00365 class DL_PrivateKey_GFP_OldFormat : public BASE
00366 {
00367 public:
00368 void BERDecode(BufferedTransformation &bt)
00369 {
00370 BERSequenceDecoder seq(bt);
00371 Integer v1(seq);
00372 Integer v2(seq);
00373 Integer v3(seq);
00374 Integer v4(seq);
00375
00376 if (seq.EndReached())
00377 {
00378 this->AccessGroupParameters().Initialize(v1, v1/2, v2);
00379 this->SetPrivateExponent(v4 % (v1/2));
00380 }
00381 else
00382 {
00383 Integer v5(seq);
00384 this->AccessGroupParameters().Initialize(v1, v2, v3);
00385 this->SetPrivateExponent(v5);
00386 }
00387
00388 seq.MessageEnd();
00389 }
00390
00391 void DEREncode(BufferedTransformation &bt) const
00392 {
00393 DERSequenceEncoder seq(bt);
00394 this->GetGroupParameters().GetModulus().DEREncode(seq);
00395 if (this->GetGroupParameters().GetCofactor() != 2)
00396 this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
00397 this->GetGroupParameters().GetGenerator().DEREncode(seq);
00398 this->GetGroupParameters().ExponentiateBase(this->GetPrivateExponent()).DEREncode(seq);
00399 this->GetPrivateExponent().DEREncode(seq);
00400 seq.MessageEnd();
00401 }
00402
00403 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00404 virtual ~DL_PrivateKey_GFP_OldFormat() {}
00405 #endif
00406 };
00407
00408
00409 template <class H>
00410 struct GDSA : public DL_SS<
00411 DL_SignatureKeys_GFP,
00412 DL_Algorithm_GDSA<Integer>,
00413 DL_SignatureMessageEncodingMethod_DSA,
00414 H>
00415 {
00416 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00417 virtual ~GDSA() {}
00418 #endif
00419 };
00420
00421
00422 template <class H>
00423 struct NR : public DL_SS<
00424 DL_SignatureKeys_GFP,
00425 DL_Algorithm_NR<Integer>,
00426 DL_SignatureMessageEncodingMethod_NR,
00427 H>
00428 {
00429 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00430 virtual ~NR() {}
00431 #endif
00432 };
00433
00434
00435 class CRYPTOPP_DLL DL_GroupParameters_DSA : public DL_GroupParameters_GFP
00436 {
00437 public:
00438
00439 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
00440
00441
00442 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
00443
00444 static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits)
00445 {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;}
00446
00447 enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024};
00448
00449 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00450 virtual ~DL_GroupParameters_DSA() {}
00451 #endif
00452 };
00453
00454 template <class H>
00455 class DSA2;
00456
00457
00458 struct DL_Keys_DSA
00459 {
00460 typedef DL_PublicKey_GFP<DL_GroupParameters_DSA> PublicKey;
00461 typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA2<SHA> > PrivateKey;
00462
00463 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00464 virtual ~DL_Keys_DSA() {}
00465 #endif
00466 };
00467
00468
00469
00470 template <class H>
00471 class DSA2 : public DL_SS<
00472 DL_Keys_DSA,
00473 DL_Algorithm_GDSA<Integer>,
00474 DL_SignatureMessageEncodingMethod_DSA,
00475 H,
00476 DSA2<H> >
00477 {
00478 public:
00479 static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();}
00480
00481 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00482 enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024};
00483 #endif
00484
00485 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00486 virtual ~DSA2() {}
00487 #endif
00488 };
00489
00490
00491 typedef DSA2<SHA> DSA;
00492
00493 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP<DL_GroupParameters_DSA>;
00494 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP<DL_GroupParameters_DSA>;
00495 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA2<SHA> >;
00496
00497
00498 template <class MAC, bool DHAES_MODE>
00499 class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm
00500 {
00501 public:
00502 bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
00503 size_t GetSymmetricKeyLength(size_t plaintextLength) const
00504 {return plaintextLength + MAC::DEFAULT_KEYLENGTH;}
00505 size_t GetSymmetricCiphertextLength(size_t plaintextLength) const
00506 {return plaintextLength + MAC::DIGESTSIZE;}
00507 size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const
00508 {return (unsigned int)SaturatingSubtract(ciphertextLength, (unsigned int)MAC::DIGESTSIZE);}
00509 void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const
00510 {
00511 CRYPTOPP_UNUSED(rng);
00512 const byte *cipherKey = NULL, *macKey = NULL;
00513 if (DHAES_MODE)
00514 {
00515 macKey = key;
00516 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
00517 }
00518 else
00519 {
00520 cipherKey = key;
00521 macKey = key + plaintextLength;
00522 }
00523
00524 ConstByteArrayParameter encodingParameters;
00525 parameters.GetValue(Name::EncodingParameters(), encodingParameters);
00526
00527 if (plaintextLength)
00528 xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
00529
00530 MAC mac(macKey);
00531 mac.Update(ciphertext, plaintextLength);
00532 mac.Update(encodingParameters.begin(), encodingParameters.size());
00533 if (DHAES_MODE)
00534 {
00535 byte L[8] = {0,0,0,0};
00536 PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
00537 mac.Update(L, 8);
00538 }
00539 mac.Final(ciphertext + plaintextLength);
00540 }
00541 DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const
00542 {
00543 size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength);
00544 const byte *cipherKey, *macKey;
00545 if (DHAES_MODE)
00546 {
00547 macKey = key;
00548 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
00549 }
00550 else
00551 {
00552 cipherKey = key;
00553 macKey = key + plaintextLength;
00554 }
00555
00556 ConstByteArrayParameter encodingParameters;
00557 parameters.GetValue(Name::EncodingParameters(), encodingParameters);
00558
00559 MAC mac(macKey);
00560 mac.Update(ciphertext, plaintextLength);
00561 mac.Update(encodingParameters.begin(), encodingParameters.size());
00562 if (DHAES_MODE)
00563 {
00564 byte L[8] = {0,0,0,0};
00565 PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
00566 mac.Update(L, 8);
00567 }
00568 if (!mac.Verify(ciphertext + plaintextLength))
00569 return DecodingResult();
00570
00571 if (plaintextLength)
00572 xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
00573
00574 return DecodingResult(plaintextLength);
00575 }
00576
00577 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00578 virtual ~DL_EncryptionAlgorithm_Xor() {}
00579 #endif
00580 };
00581
00582
00583 template <class T, bool DHAES_MODE, class KDF>
00584 class DL_KeyDerivationAlgorithm_P1363 : public DL_KeyDerivationAlgorithm<T>
00585 {
00586 public:
00587 bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;}
00588 void Derive(const DL_GroupParameters<T> ¶ms, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs ¶meters) const
00589 {
00590 SecByteBlock agreedSecret;
00591 if (DHAES_MODE)
00592 {
00593 agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false));
00594 params.EncodeElement(true, ephemeralPublicKey, agreedSecret);
00595 params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true));
00596 }
00597 else
00598 {
00599 agreedSecret.New(params.GetEncodedElementSize(false));
00600 params.EncodeElement(false, agreedElement, agreedSecret);
00601 }
00602
00603 ConstByteArrayParameter derivationParameters;
00604 parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters);
00605 KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size());
00606 }
00607
00608 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00609 virtual ~DL_KeyDerivationAlgorithm_P1363() {}
00610 #endif
00611 };
00612
00613
00614 template <class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true>
00615 struct DLIES
00616 : public DL_ES<
00617 DL_CryptoKeys_GFP,
00618 DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>,
00619 DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<SHA1> >,
00620 DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
00621 DLIES<> >
00622 {
00623 static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";}
00624
00625 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00626 virtual ~DLIES() {}
00627 #endif
00628 };
00629
00630 NAMESPACE_END
00631
00632 #if CRYPTOPP_MSC_VERSION
00633 # pragma warning(pop)
00634 #endif
00635
00636 #endif