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

Generated on Sat Jul 10 22:55:25 2004 for Crypto++ by doxygen 1.3.6