pubkey.h

Go to the documentation of this file.
00001 // pubkey.h - written and placed in the public domain by Wei Dai
00002 
00003 #ifndef CRYPTOPP_PUBKEY_H
00004 #define CRYPTOPP_PUBKEY_H
00005 
00006 /** \file
00007 
00008     This file contains helper classes/functions for implementing public key algorithms.
00009 
00010     The class hierachies in this .h file tend to look like this:
00011 <pre>
00012                   x1
00013                  / \
00014                 y1  z1
00015                  |  |
00016             x2<y1>  x2<z1>
00017                  |  |
00018                 y2  z2
00019                  |  |
00020             x3<y2>  x3<z2>
00021                  |  |
00022                 y3  z3
00023 </pre>
00024     - x1, y1, z1 are abstract interface classes defined in cryptlib.h
00025     - x2, y2, z2 are implementations of the interfaces using "abstract policies", which
00026       are pure virtual functions that should return interfaces to interchangeable algorithms.
00027       These classes have "Base" suffixes.
00028     - x3, y3, z3 hold actual algorithms and implement those virtual functions.
00029       These classes have "Impl" suffixes.
00030 
00031     The "TF_" prefix means an implementation using trapdoor functions on integers.
00032     The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard).
00033 */
00034 
00035 #include "modarith.h"
00036 #include "filters.h"
00037 #include "eprecomp.h"
00038 #include "fips140.h"
00039 #include "argnames.h"
00040 #include <memory>
00041 
00042 // VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file
00043 #undef INTERFACE
00044 
00045 NAMESPACE_BEGIN(CryptoPP)
00046 
00047 //! _
00048 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
00049 {
00050 public:
00051     virtual ~TrapdoorFunctionBounds() {}
00052 
00053     virtual Integer PreimageBound() const =0;
00054     virtual Integer ImageBound() const =0;
00055     virtual Integer MaxPreimage() const {return --PreimageBound();}
00056     virtual Integer MaxImage() const {return --ImageBound();}
00057 };
00058 
00059 //! _
00060 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
00061 {
00062 public:
00063     virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
00064     virtual bool IsRandomized() const {return true;}
00065 };
00066 
00067 //! _
00068 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
00069 {
00070 public:
00071     Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
00072         {return ApplyFunction(x);}
00073     bool IsRandomized() const {return false;}
00074 
00075     virtual Integer ApplyFunction(const Integer &x) const =0;
00076 };
00077 
00078 //! _
00079 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
00080 {
00081 public:
00082     virtual ~RandomizedTrapdoorFunctionInverse() {}
00083 
00084     virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
00085     virtual bool IsRandomized() const {return true;}
00086 };
00087 
00088 //! _
00089 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
00090 {
00091 public:
00092     virtual ~TrapdoorFunctionInverse() {}
00093 
00094     Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
00095         {return CalculateInverse(rng, x);}
00096     bool IsRandomized() const {return false;}
00097 
00098     virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
00099 };
00100 
00101 // ********************************************************
00102 
00103 //! message encoding method for public key encryption
00104 class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
00105 {
00106 public:
00107     virtual ~PK_EncryptionMessageEncodingMethod() {}
00108 
00109     virtual bool ParameterSupported(const char *name) const {return false;}
00110 
00111     //! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
00112     virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0;
00113 
00114     virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs &parameters) const =0;
00115 
00116     virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs &parameters) const =0;
00117 };
00118 
00119 // ********************************************************
00120 
00121 //! _
00122 template <class TFI, class MEI>
00123 class CRYPTOPP_NO_VTABLE TF_Base
00124 {
00125 protected:
00126     virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
00127 
00128     typedef TFI TrapdoorFunctionInterface;
00129     virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
00130 
00131     typedef MEI MessageEncodingInterface;
00132     virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
00133 };
00134 
00135 // ********************************************************
00136 
00137 //! _
00138 template <class BASE>
00139 class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
00140 {
00141 public:
00142     size_t MaxPlaintextLength(size_t ciphertextLength) const
00143         {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
00144     size_t CiphertextLength(size_t plaintextLength) const
00145         {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
00146 
00147     virtual size_t FixedMaxPlaintextLength() const =0;
00148     virtual size_t FixedCiphertextLength() const =0;
00149 };
00150 
00151 //! _
00152 template <class INTERFACE, class BASE>
00153 class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE
00154 {
00155 public:
00156     bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);}
00157     size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
00158     size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
00159 
00160 protected:
00161     size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
00162     size_t PaddedBlockBitLength() const {return this->GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;}
00163 };
00164 
00165 //! _
00166 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
00167 {
00168 public:
00169     DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
00170 };
00171 
00172 //! _
00173 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
00174 {
00175 public:
00176     void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
00177 };
00178 
00179 // ********************************************************
00180 
00181 typedef std::pair<const byte *, size_t> HashIdentifier;
00182 
00183 //! interface for message encoding method for public key signature schemes
00184 class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
00185 {
00186 public:
00187     virtual ~PK_SignatureMessageEncodingMethod() {}
00188 
00189     virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const
00190         {return 0;}
00191     virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const
00192         {return 0;}
00193 
00194     bool IsProbabilistic() const 
00195         {return true;}
00196     bool AllowNonrecoverablePart() const
00197         {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00198     virtual bool RecoverablePartFirst() const
00199         {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00200 
00201     // for verification, DL
00202     virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const {}
00203 
00204     // for signature
00205     virtual void ProcessRecoverableMessage(HashTransformation &hash, 
00206         const byte *recoverableMessage, size_t recoverableMessageLength, 
00207         const byte *presignature, size_t presignatureLength,
00208         SecByteBlock &semisignature) const
00209     {
00210         if (RecoverablePartFirst())
00211             assert(!"ProcessRecoverableMessage() not implemented");
00212     }
00213 
00214     virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng, 
00215         const byte *recoverableMessage, size_t recoverableMessageLength,
00216         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00217         byte *representative, size_t representativeBitLength) const =0;
00218 
00219     virtual bool VerifyMessageRepresentative(
00220         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00221         byte *representative, size_t representativeBitLength) const =0;
00222 
00223     virtual DecodingResult RecoverMessageFromRepresentative(    // for TF
00224         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00225         byte *representative, size_t representativeBitLength,
00226         byte *recoveredMessage) const
00227         {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00228 
00229     virtual DecodingResult RecoverMessageFromSemisignature(     // for DL
00230         HashTransformation &hash, HashIdentifier hashIdentifier,
00231         const byte *presignature, size_t presignatureLength,
00232         const byte *semisignature, size_t semisignatureLength,
00233         byte *recoveredMessage) const
00234         {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00235 
00236     // VC60 workaround
00237     struct HashIdentifierLookup
00238     {
00239         template <class H> struct HashIdentifierLookup2
00240         {
00241             static HashIdentifier CRYPTOPP_API Lookup()
00242             {
00243                 return HashIdentifier(NULL, 0);
00244             }
00245         };
00246     };
00247 };
00248 
00249 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
00250 {
00251 public:
00252     bool VerifyMessageRepresentative(
00253         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00254         byte *representative, size_t representativeBitLength) const;
00255 };
00256 
00257 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
00258 {
00259 public:
00260     bool VerifyMessageRepresentative(
00261         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00262         byte *representative, size_t representativeBitLength) const;
00263 };
00264 
00265 class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
00266 {
00267 public:
00268     void ComputeMessageRepresentative(RandomNumberGenerator &rng, 
00269         const byte *recoverableMessage, size_t recoverableMessageLength,
00270         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00271         byte *representative, size_t representativeBitLength) const;
00272 };
00273 
00274 class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
00275 {
00276 public:
00277     void ComputeMessageRepresentative(RandomNumberGenerator &rng, 
00278         const byte *recoverableMessage, size_t recoverableMessageLength,
00279         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00280         byte *representative, size_t representativeBitLength) const;
00281 };
00282 
00283 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator
00284 {
00285 public:
00286     PK_MessageAccumulatorBase() : m_empty(true) {}
00287 
00288     virtual HashTransformation & AccessHash() =0;
00289 
00290     void Update(const byte *input, size_t length)
00291     {
00292         AccessHash().Update(input, length);
00293         m_empty = m_empty && length == 0;
00294     }
00295 
00296     SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
00297     Integer m_k, m_s;
00298     bool m_empty;
00299 };
00300 
00301 template <class HASH_ALGORITHM>
00302 class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
00303 {
00304 public:
00305     HashTransformation & AccessHash() {return this->m_object;}
00306 };
00307 
00308 //! _
00309 template <class INTERFACE, class BASE>
00310 class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTERFACE, protected BASE
00311 {
00312 public:
00313     size_t SignatureLength() const 
00314         {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
00315     size_t MaxRecoverableLength() const 
00316         {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
00317     size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
00318         {return this->MaxRecoverableLength();}
00319 
00320     bool IsProbabilistic() const 
00321         {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
00322     bool AllowNonrecoverablePart() const 
00323         {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
00324     bool RecoverablePartFirst() const 
00325         {return this->GetMessageEncodingInterface().RecoverablePartFirst();}
00326 
00327 protected:
00328     size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
00329     size_t MessageRepresentativeBitLength() const {return this->GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;}
00330     virtual HashIdentifier GetHashIdentifier() const =0;
00331     virtual size_t GetDigestSize() const =0;
00332 };
00333 
00334 //! _
00335 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
00336 {
00337 public:
00338     void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const;
00339     size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
00340 };
00341 
00342 //! _
00343 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
00344 {
00345 public:
00346     void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const;
00347     bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
00348     DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
00349 };
00350 
00351 // ********************************************************
00352 
00353 //! _
00354 template <class T1, class T2, class T3>
00355 struct TF_CryptoSchemeOptions
00356 {
00357     typedef T1 AlgorithmInfo;
00358     typedef T2 Keys;
00359     typedef typename Keys::PrivateKey PrivateKey;
00360     typedef typename Keys::PublicKey PublicKey;
00361     typedef T3 MessageEncodingMethod;
00362 };
00363 
00364 //! _
00365 template <class T1, class T2, class T3, class T4>
00366 struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3>
00367 {
00368     typedef T4 HashFunction;
00369 };
00370 
00371 //! _
00372 template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
00373 class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
00374 {
00375 public:
00376     typedef SCHEME_OPTIONS SchemeOptions;
00377     typedef KEY_CLASS KeyClass;
00378 
00379     PublicKey & AccessPublicKey() {return AccessKey();}
00380     const PublicKey & GetPublicKey() const {return GetKey();}
00381 
00382     PrivateKey & AccessPrivateKey() {return AccessKey();}
00383     const PrivateKey & GetPrivateKey() const {return GetKey();}
00384 
00385     virtual const KeyClass & GetKey() const =0;
00386     virtual KeyClass & AccessKey() =0;
00387 
00388     const KeyClass & GetTrapdoorFunction() const {return GetKey();}
00389 
00390     PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
00391     {
00392         return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
00393     }
00394     PK_MessageAccumulator * NewVerificationAccumulator() const
00395     {
00396         return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
00397     }
00398 
00399 protected:
00400     const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const 
00401         {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
00402     const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const 
00403         {return GetKey();}
00404     const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const 
00405         {return GetKey();}
00406 
00407     // for signature scheme
00408     HashIdentifier GetHashIdentifier() const
00409     {
00410         typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L;
00411         return L::Lookup();
00412     }
00413     size_t GetDigestSize() const
00414     {
00415         typedef CPP_TYPENAME SchemeOptions::HashFunction H;
00416         return H::DIGESTSIZE;
00417     }
00418 };
00419 
00420 //! _
00421 template <class BASE, class SCHEME_OPTIONS, class KEY>
00422 class TF_ObjectImplExtRef : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
00423 {
00424 public:
00425     TF_ObjectImplExtRef(const KEY *pKey = NULL) : m_pKey(pKey) {}
00426     void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;}
00427 
00428     const KEY & GetKey() const {return *m_pKey;}
00429     KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");}
00430 
00431 private:
00432     const KEY * m_pKey;
00433 };
00434 
00435 //! _
00436 template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS>
00437 class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS>
00438 {
00439 public:
00440     typedef KEY_CLASS KeyClass;
00441 
00442     const KeyClass & GetKey() const {return m_trapdoorFunction;}
00443     KeyClass & AccessKey() {return m_trapdoorFunction;}
00444 
00445 private:
00446     KeyClass m_trapdoorFunction;
00447 };
00448 
00449 //! _
00450 template <class SCHEME_OPTIONS>
00451 class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
00452 {
00453 };
00454 
00455 //! _
00456 template <class SCHEME_OPTIONS>
00457 class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
00458 {
00459 };
00460 
00461 //! _
00462 template <class SCHEME_OPTIONS>
00463 class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
00464 {
00465 };
00466 
00467 //! _
00468 template <class SCHEME_OPTIONS>
00469 class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
00470 {
00471 };
00472 
00473 // ********************************************************
00474 
00475 //! _
00476 class CRYPTOPP_NO_VTABLE MaskGeneratingFunction
00477 {
00478 public:
00479     virtual ~MaskGeneratingFunction() {}
00480     virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0;
00481 };
00482 
00483 CRYPTOPP_DLL void CRYPTOPP_API P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart);
00484 
00485 //! _
00486 class P1363_MGF1 : public MaskGeneratingFunction
00487 {
00488 public:
00489     static const char * CRYPTOPP_API StaticAlgorithmName() {return "MGF1";}
00490     void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const
00491     {
00492         P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0);
00493     }
00494 };
00495 
00496 // ********************************************************
00497 
00498 //! _
00499 template <class H>
00500 class P1363_KDF2
00501 {
00502 public:
00503     static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength)
00504     {
00505         H h;
00506         P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
00507     }
00508 };
00509 
00510 // ********************************************************
00511 
00512 //! to be thrown by DecodeElement and AgreeWithStaticPrivateKey
00513 class DL_BadElement : public InvalidDataFormat
00514 {
00515 public:
00516     DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {}
00517 };
00518 
00519 //! interface for DL group parameters
00520 template <class T>
00521 class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters
00522 {
00523     typedef DL_GroupParameters<T> ThisClass;
00524     
00525 public:
00526     typedef T Element;
00527 
00528     DL_GroupParameters() : m_validationLevel(0) {}
00529 
00530     // CryptoMaterial
00531     bool Validate(RandomNumberGenerator &rng, unsigned int level) const
00532     {
00533         if (!GetBasePrecomputation().IsInitialized())
00534             return false;
00535 
00536         if (m_validationLevel > level)
00537             return true;
00538 
00539         bool pass = ValidateGroup(rng, level);
00540         pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
00541 
00542         m_validationLevel = pass ? level+1 : 0;
00543 
00544         return pass;
00545     }
00546 
00547     bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00548     {
00549         return GetValueHelper(this, name, valueType, pValue)
00550             CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
00551             CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
00552             ;
00553     }
00554 
00555     bool SupportsPrecomputation() const {return true;}
00556 
00557     void Precompute(unsigned int precomputationStorage=16)
00558     {
00559         AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
00560     }
00561 
00562     void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
00563     {
00564         AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
00565         m_validationLevel = 0;
00566     }
00567 
00568     void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
00569     {
00570         GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
00571     }
00572 
00573     // non-inherited
00574     virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
00575     virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
00576     virtual Element ExponentiateBase(const Integer &exponent) const
00577     {
00578         return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
00579     }
00580     virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
00581     {
00582         Element result;
00583         SimultaneousExponentiate(&result, base, &exponent, 1);
00584         return result;
00585     }
00586 
00587     virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0;
00588     virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0;
00589     virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0;
00590     virtual const Integer & GetSubgroupOrder() const =0;    // order of subgroup generated by base element
00591     virtual Integer GetMaxExponent() const =0;
00592     virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();}    // one of these two needs to be overriden
00593     virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();}
00594     virtual unsigned int GetEncodedElementSize(bool reversible) const =0;
00595     virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0;
00596     virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0;
00597     virtual Integer ConvertElementToInteger(const Element &element) const =0;
00598     virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0;
00599     virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0;
00600     virtual bool FastSubgroupCheckAvailable() const =0;
00601     virtual bool IsIdentity(const Element &element) const =0;
00602     virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0;
00603 
00604 protected:
00605     void ParametersChanged() {m_validationLevel = 0;}
00606 
00607 private:
00608     mutable unsigned int m_validationLevel;
00609 };
00610 
00611 //! _
00612 template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<CPP_TYPENAME GROUP_PRECOMP::Element> >
00613 class DL_GroupParametersImpl : public BASE
00614 {
00615 public:
00616     typedef GROUP_PRECOMP GroupPrecomputation;
00617     typedef typename GROUP_PRECOMP::Element Element;
00618     typedef BASE_PRECOMP BasePrecomputation;
00619     
00620     const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;}
00621     const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return m_gpc;}
00622     DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return m_gpc;}
00623 
00624 protected:
00625     GROUP_PRECOMP m_groupPrecomputation;
00626     BASE_PRECOMP m_gpc;
00627 };
00628 
00629 //! _
00630 template <class T>
00631 class CRYPTOPP_NO_VTABLE DL_Key
00632 {
00633 public:
00634     virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0;
00635     virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0;
00636 };
00637 
00638 //! interface for DL public keys
00639 template <class T>
00640 class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T>
00641 {
00642     typedef DL_PublicKey<T> ThisClass;
00643 
00644 public:
00645     typedef T Element;
00646 
00647     bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00648     {
00649         return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
00650                 CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
00651     }
00652 
00653     void AssignFrom(const NameValuePairs &source);
00654     
00655     // non-inherited
00656     virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
00657     virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
00658     virtual Element ExponentiatePublicElement(const Integer &exponent) const
00659     {
00660         const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
00661         return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
00662     }
00663     virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
00664     {
00665         const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
00666         return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
00667     }
00668 
00669     virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation() const =0;
00670     virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0;
00671 };
00672 
00673 //! interface for DL private keys
00674 template <class T>
00675 class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T>
00676 {
00677     typedef DL_PrivateKey<T> ThisClass;
00678 
00679 public:
00680     typedef T Element;
00681 
00682     void MakePublicKey(DL_PublicKey<T> &pub) const
00683     {
00684         pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters());
00685         pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
00686     }
00687 
00688     bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00689     {
00690         return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters())
00691                 CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
00692     }
00693 
00694     void AssignFrom(const NameValuePairs &source)
00695     {
00696         this->AccessAbstractGroupParameters().AssignFrom(source);
00697         AssignFromHelper(this, source)
00698             CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
00699     }
00700 
00701     virtual const Integer & GetPrivateExponent() const =0;
00702     virtual void SetPrivateExponent(const Integer &x) =0;
00703 };
00704 
00705 template <class T>
00706 void DL_PublicKey<T>::AssignFrom(const NameValuePairs &source)
00707 {
00708     DL_PrivateKey<T> *pPrivateKey = NULL;
00709     if (source.GetThisPointer(pPrivateKey))
00710         pPrivateKey->MakePublicKey(*this);
00711     else
00712     {
00713         this->AccessAbstractGroupParameters().AssignFrom(source);
00714         AssignFromHelper(this, source)
00715             CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
00716     }
00717 }
00718 
00719 class OID;
00720 
00721 //! _
00722 template <class PK, class GP, class O = OID>
00723 class DL_KeyImpl : public PK
00724 {
00725 public:
00726     typedef GP GroupParameters;
00727 
00728     O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();}
00729 //  void BERDecode(BufferedTransformation &bt)
00730 //      {PK::BERDecode(bt);}
00731 //  void DEREncode(BufferedTransformation &bt) const
00732 //      {PK::DEREncode(bt);}
00733     bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
00734         {AccessGroupParameters().BERDecode(bt); return true;}
00735     bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
00736         {GetGroupParameters().DEREncode(bt); return true;}
00737 
00738     const GP & GetGroupParameters() const {return m_groupParameters;}
00739     GP & AccessGroupParameters() {return m_groupParameters;}
00740 
00741 private:
00742     GP m_groupParameters;
00743 };
00744 
00745 class X509PublicKey;
00746 class PKCS8PrivateKey;
00747 
00748 //! _
00749 template <class GP>
00750 class DL_PrivateKeyImpl : public DL_PrivateKey<CPP_TYPENAME GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP>
00751 {
00752 public:
00753     typedef typename GP::Element Element;
00754 
00755     // GeneratableCryptoMaterial
00756     bool Validate(RandomNumberGenerator &rng, unsigned int level) const
00757     {
00758         bool pass = GetAbstractGroupParameters().Validate(rng, level);
00759 
00760         const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
00761         const Integer &x = GetPrivateExponent();
00762 
00763         pass = pass && x.IsPositive() && x < q;
00764         if (level >= 1)
00765             pass = pass && Integer::Gcd(x, q) == Integer::One();
00766         return pass;
00767     }
00768 
00769     bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00770     {
00771         return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable();
00772     }
00773 
00774     void AssignFrom(const NameValuePairs &source)
00775     {
00776         AssignFromHelper<DL_PrivateKey<Element> >(this, source);
00777     }
00778 
00779     void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
00780     {
00781         if (!params.GetThisObject(this->AccessGroupParameters()))
00782             this->AccessGroupParameters().GenerateRandom(rng, params);
00783 //      std::pair<const byte *, int> seed;
00784         Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
00785 //          Integer::ANY, Integer::Zero(), Integer::One(),
00786 //          params.GetValue("DeterministicKeyGenerationSeed", seed) ? &seed : NULL);
00787         SetPrivateExponent(x);
00788     }
00789 
00790     bool SupportsPrecomputation() const {return true;}
00791 
00792     void Precompute(unsigned int precomputationStorage=16)
00793         {AccessAbstractGroupParameters().Precompute(precomputationStorage);}
00794 
00795     void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
00796         {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
00797 
00798     void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
00799         {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
00800 
00801     // DL_Key
00802     const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
00803     DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
00804 
00805     // DL_PrivateKey
00806     const Integer & GetPrivateExponent() const {return m_x;}
00807     void SetPrivateExponent(const Integer &x) {m_x = x;}
00808 
00809     // PKCS8PrivateKey
00810     void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t)
00811         {m_x.BERDecode(bt);}
00812     void DEREncodePrivateKey(BufferedTransformation &bt) const
00813         {m_x.DEREncode(bt);}
00814 
00815 private:
00816     Integer m_x;
00817 };
00818 
00819 //! _
00820 template <class BASE, class SIGNATURE_SCHEME>
00821 class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE
00822 {
00823 public:
00824     void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
00825     {
00826         BASE::GenerateRandom(rng, params);
00827 
00828         if (FIPS_140_2_ComplianceEnabled())
00829         {
00830             typename SIGNATURE_SCHEME::Signer signer(*this);
00831             typename SIGNATURE_SCHEME::Verifier verifier(signer);
00832             SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
00833         }
00834     }
00835 };
00836 
00837 //! _
00838 template <class GP>
00839 class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP>
00840 {
00841 public:
00842     typedef typename GP::Element Element;
00843 
00844     // CryptoMaterial
00845     bool Validate(RandomNumberGenerator &rng, unsigned int level) const
00846     {
00847         bool pass = GetAbstractGroupParameters().Validate(rng, level);
00848         pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
00849         return pass;
00850     }
00851 
00852     bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00853     {
00854         return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable();
00855     }
00856 
00857     void AssignFrom(const NameValuePairs &source)
00858     {
00859         AssignFromHelper<DL_PublicKey<Element> >(this, source);
00860     }
00861 
00862     bool SupportsPrecomputation() const {return true;}
00863 
00864     void Precompute(unsigned int precomputationStorage=16)
00865     {
00866         AccessAbstractGroupParameters().Precompute(precomputationStorage);
00867         AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
00868     }
00869 
00870     void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
00871     {
00872         AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
00873         AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
00874     }
00875 
00876     void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
00877     {
00878         GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
00879         GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
00880     }
00881 
00882     // DL_Key
00883     const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();}
00884     DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();}
00885 
00886     // DL_PublicKey
00887     const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;}
00888     DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;}
00889 
00890     // non-inherited
00891     bool operator==(const DL_PublicKeyImpl<GP> &rhs) const
00892         {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
00893 
00894 private:
00895     typename GP::BasePrecomputation m_ypc;
00896 };
00897 
00898 //! interface for Elgamal-like signature algorithms
00899 template <class T>
00900 class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm
00901 {
00902 public:
00903     virtual void Sign(const DL_GroupParameters<T> &params, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
00904     virtual bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
00905     virtual Integer RecoverPresignature(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
00906         {throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");}
00907     virtual size_t RLen(const DL_GroupParameters<T> &params) const
00908         {return params.GetSubgroupOrder().ByteCount();}
00909     virtual size_t SLen(const DL_GroupParameters<T> &params) const
00910         {return params.GetSubgroupOrder().ByteCount();}
00911 };
00912 
00913 //! interface for DL key agreement algorithms
00914 template <class T>
00915 class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm
00916 {
00917 public:
00918     typedef T Element;
00919 
00920     virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0;
00921     virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0;
00922 };
00923 
00924 //! interface for key derivation algorithms used in DL cryptosystems
00925 template <class T>
00926 class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
00927 {
00928 public:
00929     virtual bool ParameterSupported(const char *name) const {return false;}
00930     virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0;
00931 };
00932 
00933 //! interface for symmetric encryption algorithms used in DL cryptosystems
00934 class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
00935 {
00936 public:
00937     virtual bool ParameterSupported(const char *name) const {return false;}
00938     virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0;
00939     virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0;
00940     virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0;
00941     virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const =0;
00942     virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const =0;
00943 };
00944 
00945 //! _
00946 template <class KI>
00947 class CRYPTOPP_NO_VTABLE DL_Base
00948 {
00949 protected:
00950     typedef KI KeyInterface;
00951     typedef typename KI::Element Element;
00952 
00953     const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();}
00954     DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();}
00955 
00956     virtual KeyInterface & AccessKeyInterface() =0;
00957     virtual const KeyInterface & GetKeyInterface() const =0;
00958 };
00959 
00960 //! _
00961 template <class INTERFACE, class KEY_INTERFACE>
00962 class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTERFACE, public DL_Base<KEY_INTERFACE>
00963 {
00964 public:
00965     size_t SignatureLength() const
00966     {
00967         return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
00968             + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
00969     }
00970     size_t MaxRecoverableLength() const 
00971         {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
00972     size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
00973         {assert(false); return 0;}  // TODO
00974 
00975     bool IsProbabilistic() const 
00976         {return true;}
00977     bool AllowNonrecoverablePart() const 
00978         {return GetMessageEncodingInterface().AllowNonrecoverablePart();}
00979     bool RecoverablePartFirst() const 
00980         {return GetMessageEncodingInterface().RecoverablePartFirst();}
00981 
00982 protected:
00983     size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
00984     size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
00985 
00986     virtual const DL_ElgamalLikeSignatureAlgorithm<CPP_TYPENAME KEY_INTERFACE::Element> & GetSignatureAlgorithm() const =0;
00987     virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
00988     virtual HashIdentifier GetHashIdentifier() const =0;
00989     virtual size_t GetDigestSize() const =0;
00990 };
00991 
00992 //! _
00993 template <class T>
00994 class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
00995 {
00996 public:
00997     // for validation testing
00998     void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
00999     {
01000         const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01001         const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01002         const DL_PrivateKey<T> &key = this->GetKeyInterface();
01003 
01004         r = params.ConvertElementToInteger(params.ExponentiateBase(k));
01005         alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
01006     }
01007 
01008     void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
01009     {
01010         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01011         ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
01012         this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(), 
01013             recoverableMessage, recoverableMessageLength, 
01014             ma.m_presignature, ma.m_presignature.size(),
01015             ma.m_semisignature);
01016     }
01017 
01018     size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
01019     {
01020         this->GetMaterial().DoQuickSanityCheck();
01021 
01022         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01023         const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01024         const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01025         const DL_PrivateKey<T> &key = this->GetKeyInterface();
01026 
01027         SecByteBlock representative(this->MessageRepresentativeLength());
01028         this->GetMessageEncodingInterface().ComputeMessageRepresentative(
01029             rng, 
01030             ma.m_recoverableMessage, ma.m_recoverableMessage.size(), 
01031             ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty, 
01032             representative, this->MessageRepresentativeBitLength());
01033         ma.m_empty = true;
01034         Integer e(representative, representative.size());
01035 
01036         // hash message digest into random number k to prevent reusing the same k on a different messages
01037         // after virtual machine rollback
01038         if (rng.CanIncorporateEntropy())
01039             rng.IncorporateEntropy(representative, representative.size());
01040         Integer k(rng, 1, params.GetSubgroupOrder()-1);
01041         Integer r, s;
01042         r = params.ConvertElementToInteger(params.ExponentiateBase(k));
01043         alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
01044 
01045         /*
01046         Integer r, s;
01047         if (this->MaxRecoverableLength() > 0)
01048             r.Decode(ma.m_semisignature, ma.m_semisignature.size());
01049         else
01050             r.Decode(ma.m_presignature, ma.m_presignature.size());
01051         alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s);
01052         */
01053 
01054         size_t rLen = alg.RLen(params);
01055         r.Encode(signature, rLen);
01056         s.Encode(signature+rLen, alg.SLen(params));
01057 
01058         if (restart)
01059             RestartMessageAccumulator(rng, ma);
01060 
01061         return this->SignatureLength();
01062     }
01063 
01064 protected:
01065     void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
01066     {
01067         // k needs to be generated before hashing for signature schemes with recovery
01068         // but to defend against VM rollbacks we need to generate k after hashing.
01069         // so this code is commented out, since no DL-based signature scheme with recovery
01070         // has been implemented in Crypto++ anyway
01071         /*
01072         const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01073         const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01074         ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
01075         ma.m_presignature.New(params.GetEncodedElementSize(false));
01076         params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size());
01077         */
01078     }
01079 };
01080 
01081 //! _
01082 template <class T>
01083 class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
01084 {
01085 public:
01086     void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
01087     {
01088         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01089         const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01090         const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01091 
01092         size_t rLen = alg.RLen(params);
01093         ma.m_semisignature.Assign(signature, rLen);
01094         ma.m_s.Decode(signature+rLen, alg.SLen(params));
01095 
01096         this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
01097     }
01098     
01099     bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
01100     {
01101         this->GetMaterial().DoQuickSanityCheck();
01102 
01103         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01104         const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01105         const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01106         const DL_PublicKey<T> &key = this->GetKeyInterface();
01107 
01108         SecByteBlock representative(this->MessageRepresentativeLength());
01109         this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(), 
01110             ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01111             representative, this->MessageRepresentativeBitLength());
01112         ma.m_empty = true;
01113         Integer e(representative, representative.size());
01114 
01115         Integer r(ma.m_semisignature, ma.m_semisignature.size());
01116         return alg.Verify(params, key, e, r, ma.m_s);
01117     }
01118 
01119     DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
01120     {
01121         this->GetMaterial().DoQuickSanityCheck();
01122 
01123         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01124         const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01125         const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01126         const DL_PublicKey<T> &key = this->GetKeyInterface();
01127 
01128         SecByteBlock representative(this->MessageRepresentativeLength());
01129         this->GetMessageEncodingInterface().ComputeMessageRepresentative(
01130             NullRNG(), 
01131             ma.m_recoverableMessage, ma.m_recoverableMessage.size(), 
01132             ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01133             representative, this->MessageRepresentativeBitLength());
01134         ma.m_empty = true;
01135         Integer e(representative, representative.size());
01136 
01137         ma.m_presignature.New(params.GetEncodedElementSize(false));
01138         Integer r(ma.m_semisignature, ma.m_semisignature.size());
01139         alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
01140 
01141         return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
01142             ma.AccessHash(), this->GetHashIdentifier(),
01143             ma.m_presignature, ma.m_presignature.size(),
01144             ma.m_semisignature, ma.m_semisignature.size(),
01145             recoveredMessage);
01146     }
01147 };
01148 
01149 //! _
01150 template <class PK, class KI>
01151 class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
01152 {
01153 public:
01154     typedef typename DL_Base<KI>::Element Element;
01155 
01156     size_t MaxPlaintextLength(size_t ciphertextLength) const
01157     {
01158         unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
01159         return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
01160     }
01161 
01162     size_t CiphertextLength(size_t plaintextLength) const
01163     {
01164         size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
01165         return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
01166     }
01167 
01168     bool ParameterSupported(const char *name) const
01169         {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
01170 
01171 protected:
01172     virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
01173     virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
01174     virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
01175 };
01176 
01177 //! _
01178 template <class T>
01179 class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
01180 {
01181 public:
01182     typedef T Element;
01183 
01184     DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
01185     {
01186         try
01187         {
01188             const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
01189             const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
01190             const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
01191             const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01192             const DL_PrivateKey<T> &key = this->GetKeyInterface();
01193 
01194             Element q = params.DecodeElement(ciphertext, true);
01195             size_t elementSize = params.GetEncodedElementSize(true);
01196             ciphertext += elementSize;
01197             ciphertextLength -= elementSize;
01198 
01199             Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
01200 
01201             SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
01202             derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
01203 
01204             return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
01205         }
01206         catch (DL_BadElement &)
01207         {
01208             return DecodingResult();
01209         }
01210     }
01211 };
01212 
01213 //! _
01214 template <class T>
01215 class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
01216 {
01217 public:
01218     typedef T Element;
01219 
01220     void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const
01221     {
01222         const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
01223         const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
01224         const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
01225         const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01226         const DL_PublicKey<T> &key = this->GetKeyInterface();
01227 
01228         Integer x(rng, Integer::One(), params.GetMaxExponent());
01229         Element q = params.ExponentiateBase(x);
01230         params.EncodeElement(true, q, ciphertext);
01231         unsigned int elementSize = params.GetEncodedElementSize(true);
01232         ciphertext += elementSize;
01233 
01234         Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
01235 
01236         SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
01237         derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
01238 
01239         encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
01240     }
01241 };
01242 
01243 //! _
01244 template <class T1, class T2>
01245 struct DL_SchemeOptionsBase
01246 {
01247     typedef T1 AlgorithmInfo;
01248     typedef T2 GroupParameters;
01249     typedef typename GroupParameters::Element Element;
01250 };
01251 
01252 //! _
01253 template <class T1, class T2>
01254 struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
01255 {
01256     typedef T2 Keys;
01257     typedef typename Keys::PrivateKey PrivateKey;
01258     typedef typename Keys::PublicKey PublicKey;
01259 };
01260 
01261 //! _
01262 template <class T1, class T2, class T3, class T4, class T5>
01263 struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
01264 {
01265     typedef T3 SignatureAlgorithm;
01266     typedef T4 MessageEncodingMethod;
01267     typedef T5 HashFunction;
01268 };
01269 
01270 //! _
01271 template <class T1, class T2, class T3, class T4, class T5>
01272 struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
01273 {
01274     typedef T3 KeyAgreementAlgorithm;
01275     typedef T4 KeyDerivationAlgorithm;
01276     typedef T5 SymmetricEncryptionAlgorithm;
01277 };
01278 
01279 //! _
01280 template <class BASE, class SCHEME_OPTIONS, class KEY>
01281 class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
01282 {
01283 public:
01284     typedef SCHEME_OPTIONS SchemeOptions;
01285     typedef typename KEY::Element Element;
01286 
01287     PrivateKey & AccessPrivateKey() {return m_key;}
01288     PublicKey & AccessPublicKey() {return m_key;}
01289 
01290     // KeyAccessor
01291     const KEY & GetKey() const {return m_key;}
01292     KEY & AccessKey() {return m_key;}
01293 
01294 protected:
01295     typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
01296     const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
01297 
01298     // for signature scheme
01299     HashIdentifier GetHashIdentifier() const
01300     {
01301         typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
01302         return HashLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction>::Lookup();
01303     }
01304     size_t GetDigestSize() const
01305     {
01306         typedef CPP_TYPENAME SchemeOptions::HashFunction H;
01307         return H::DIGESTSIZE;
01308     }
01309 
01310 private:
01311     KEY m_key;
01312 };
01313 
01314 //! _
01315 template <class BASE, class SCHEME_OPTIONS, class KEY>
01316 class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
01317 {
01318 public:
01319     typedef typename KEY::Element Element;
01320 
01321 protected:
01322     const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
01323         {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SignatureAlgorithm>().Ref();}
01324     const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
01325         {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();}
01326     const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
01327         {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();}
01328     const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
01329         {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();}
01330     HashIdentifier GetHashIdentifier() const
01331         {return HashIdentifier();}
01332     const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const 
01333         {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
01334 };
01335 
01336 //! _
01337 template <class SCHEME_OPTIONS>
01338 class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
01339 {
01340 public:
01341     PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
01342     {
01343         std::auto_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>);
01344         this->RestartMessageAccumulator(rng, *p);
01345         return p.release();
01346     }
01347 };
01348 
01349 //! _
01350 template <class SCHEME_OPTIONS>
01351 class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
01352 {
01353 public:
01354     PK_MessageAccumulator * NewVerificationAccumulator() const
01355     {
01356         return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
01357     }
01358 };
01359 
01360 //! _
01361 template <class SCHEME_OPTIONS>
01362 class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
01363 {
01364 };
01365 
01366 //! _
01367 template <class SCHEME_OPTIONS>
01368 class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
01369 {
01370 };
01371 
01372 // ********************************************************
01373 
01374 //! _
01375 template <class T>
01376 class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain
01377 {
01378 public:
01379     typedef T Element;
01380 
01381     CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
01382     unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
01383     unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
01384     unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
01385 
01386     void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
01387     {
01388         Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
01389         x.Encode(privateKey, PrivateKeyLength());
01390     }
01391 
01392     void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
01393     {
01394         const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
01395         Integer x(privateKey, PrivateKeyLength());
01396         Element y = params.ExponentiateBase(x);
01397         params.EncodeElement(true, y, publicKey);
01398     }
01399     
01400     bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
01401     {
01402         try
01403         {
01404             const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
01405             Integer x(privateKey, PrivateKeyLength());
01406             Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
01407 
01408             Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
01409                 GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
01410             params.EncodeElement(false, z, agreedValue);
01411         }
01412         catch (DL_BadElement &)
01413         {
01414             return false;
01415         }
01416         return true;
01417     }
01418 
01419     const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
01420 
01421 protected:
01422     virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
01423     virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
01424     const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
01425 };
01426 
01427 enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION};
01428 typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication;
01429 typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication;
01430 typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication;
01431 
01432 //! DH key agreement algorithm
01433 template <class ELEMENT, class COFACTOR_OPTION>
01434 class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT>
01435 {
01436 public:
01437     typedef ELEMENT Element;
01438 
01439     static const char * CRYPTOPP_API StaticAlgorithmName()
01440         {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
01441 
01442     Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
01443     {
01444         return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(), 
01445             COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
01446     }
01447 
01448     Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
01449     {
01450         if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
01451         {
01452             const Integer &k = params.GetCofactor();
01453             return params.ExponentiateElement(publicElement, 
01454                 ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
01455         }
01456         else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
01457             return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
01458         else
01459         {
01460             assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
01461 
01462             if (!validateOtherPublicKey)
01463                 return params.ExponentiateElement(publicElement, privateExponent);
01464 
01465             if (params.FastSubgroupCheckAvailable())
01466             {
01467                 if (!params.ValidateElement(2, publicElement, NULL))
01468                     throw DL_BadElement();
01469                 return params.ExponentiateElement(publicElement, privateExponent);
01470             }
01471             else
01472             {
01473                 const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
01474                 Element r[2];
01475                 params.SimultaneousExponentiate(r, publicElement, e, 2);
01476                 if (!params.IsIdentity(r[0]))
01477                     throw DL_BadElement();
01478                 return r[1];
01479             }
01480         }
01481     }
01482 };
01483 
01484 // ********************************************************
01485 
01486 //! A template implementing constructors for public key algorithm classes
01487 template <class BASE>
01488 class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
01489 {
01490 public:
01491     PK_FinalTemplate() {}
01492 
01493     PK_FinalTemplate(const CryptoMaterial &key)
01494         {this->AccessKey().AssignFrom(key);}
01495 
01496     PK_FinalTemplate(BufferedTransformation &bt)
01497         {this->AccessKey().BERDecode(bt);}
01498 
01499     PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
01500         {this->AccessKey().AssignFrom(algorithm.GetMaterial());}
01501 
01502     PK_FinalTemplate(const Integer &v1)
01503         {this->AccessKey().Initialize(v1);}
01504 
01505 #if (defined(_MSC_VER) && _MSC_VER < 1300)
01506 
01507     template <class T1, class T2>
01508     PK_FinalTemplate(T1 &v1, T2 &v2)
01509         {this->AccessKey().Initialize(v1, v2);}
01510 
01511     template <class T1, class T2, class T3>
01512     PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3)
01513         {this->AccessKey().Initialize(v1, v2, v3);}
01514     
01515     template <class T1, class T2, class T3, class T4>
01516     PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4)
01517         {this->AccessKey().Initialize(v1, v2, v3, v4);}
01518 
01519     template <class T1, class T2, class T3, class T4, class T5>
01520     PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5)
01521         {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01522 
01523     template <class T1, class T2, class T3, class T4, class T5, class T6>
01524     PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6)
01525         {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01526 
01527     template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01528     PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7)
01529         {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01530 
01531     template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01532     PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
01533         {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01534 
01535 #else
01536 
01537     template <class T1, class T2>
01538     PK_FinalTemplate(const T1 &v1, const T2 &v2)
01539         {this->AccessKey().Initialize(v1, v2);}
01540 
01541     template <class T1, class T2, class T3>
01542     PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
01543         {this->AccessKey().Initialize(v1, v2, v3);}
01544     
01545     template <class T1, class T2, class T3, class T4>
01546     PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
01547         {this->AccessKey().Initialize(v1, v2, v3, v4);}
01548 
01549     template <class T1, class T2, class T3, class T4, class T5>
01550     PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
01551         {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01552 
01553     template <class T1, class T2, class T3, class T4, class T5, class T6>
01554     PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
01555         {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01556 
01557     template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01558     PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
01559         {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01560 
01561     template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01562     PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8)
01563         {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01564 
01565     template <class T1, class T2>
01566     PK_FinalTemplate(T1 &v1, const T2 &v2)
01567         {this->AccessKey().Initialize(v1, v2);}
01568 
01569     template <class T1, class T2, class T3>
01570     PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
01571         {this->AccessKey().Initialize(v1, v2, v3);}
01572     
01573     template <class T1, class T2, class T3, class T4>
01574     PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
01575         {this->AccessKey().Initialize(v1, v2, v3, v4);}
01576 
01577     template <class T1, class T2, class T3, class T4, class T5>
01578     PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
01579         {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01580 
01581     template <class T1, class T2, class T3, class T4, class T5, class T6>
01582     PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
01583         {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01584 
01585     template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01586     PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
01587         {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01588 
01589     template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01590     PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8)
01591         {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01592 
01593 #endif
01594 };
01595 
01596 //! Base class for public key encryption standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms.
01597 struct EncryptionStandard {};
01598 
01599 //! Base class for public key signature standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms.
01600 struct SignatureStandard {};
01601 
01602 template <class STANDARD, class KEYS, class ALG_INFO>
01603 class TF_ES;
01604 
01605 //! Trapdoor Function Based Encryption Scheme
01606 template <class STANDARD, class KEYS, class ALG_INFO = TF_ES<STANDARD, KEYS, int> >
01607 class TF_ES : public KEYS
01608 {
01609     typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
01610 
01611 public:
01612     //! see EncryptionStandard for a list of standards
01613     typedef STANDARD Standard;
01614     typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions;
01615 
01616     static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
01617 
01618     //! implements PK_Decryptor interface
01619     typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor;
01620     //! implements PK_Encryptor interface
01621     typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor;
01622 };
01623 
01624 template <class STANDARD, class H, class KEYS, class ALG_INFO>  // VC60 workaround: doesn't work if KEYS is first parameter
01625 class TF_SS;
01626 
01627 //! Trapdoor Function Based Signature Scheme
01628 template <class STANDARD, class H, class KEYS, class ALG_INFO = TF_SS<STANDARD, H, KEYS, int> > // VC60 workaround: doesn't work if KEYS is first parameter
01629 class TF_SS : public KEYS
01630 {
01631 public:
01632     //! see SignatureStandard for a list of standards
01633     typedef STANDARD Standard;
01634     typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
01635     typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
01636 
01637     static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
01638 
01639     //! implements PK_Signer interface
01640     typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer;
01641     //! implements PK_Verifier interface
01642     typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier;
01643 };
01644 
01645 template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
01646 class DL_SS;
01647 
01648 //! Discrete Log Based Signature Scheme
01649 template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
01650 class DL_SS : public KEYS
01651 {
01652     typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
01653 
01654 public:
01655     static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
01656 
01657     //! implements PK_Signer interface
01658     typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
01659     //! implements PK_Verifier interface
01660     typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
01661 };
01662 
01663 //! Discrete Log Based Encryption Scheme
01664 template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
01665 class DL_ES : public KEYS
01666 {
01667     typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions;
01668 
01669 public:
01670     //! implements PK_Decryptor interface
01671     typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor;
01672     //! implements PK_Encryptor interface
01673     typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor;
01674 };
01675 
01676 NAMESPACE_END
01677 
01678 #endif

Generated on Thu Jul 5 22:21:37 2007 for Crypto++ by  doxygen 1.5.2