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                 Integer r;
01037                 if (this->MaxRecoverableLength() > 0)
01038                         r.Decode(ma.m_semisignature, ma.m_semisignature.size());
01039                 else
01040                         r.Decode(ma.m_presignature, ma.m_presignature.size());
01041                 Integer s;
01042                 alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s);
01043 
01044                 size_t rLen = alg.RLen(params);
01045                 r.Encode(signature, rLen);
01046                 s.Encode(signature+rLen, alg.SLen(params));
01047 
01048                 if (restart)
01049                         RestartMessageAccumulator(rng, ma);
01050 
01051                 return this->SignatureLength();
01052         }
01053 
01054 protected:
01055         void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
01056         {
01057                 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01058                 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01059                 ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
01060                 ma.m_presignature.New(params.GetEncodedElementSize(false));
01061                 params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size());
01062         }
01063 };
01064 
01065 //! _
01066 template <class T>
01067 class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
01068 {
01069 public:
01070         void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
01071         {
01072                 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01073                 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01074                 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01075 
01076                 size_t rLen = alg.RLen(params);
01077                 ma.m_semisignature.Assign(signature, rLen);
01078                 ma.m_s.Decode(signature+rLen, alg.SLen(params));
01079 
01080                 this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
01081         }
01082         
01083         bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
01084         {
01085                 this->GetMaterial().DoQuickSanityCheck();
01086 
01087                 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01088                 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01089                 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01090                 const DL_PublicKey<T> &key = this->GetKeyInterface();
01091 
01092                 SecByteBlock representative(this->MessageRepresentativeLength());
01093                 this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(), 
01094                         ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01095                         representative, this->MessageRepresentativeBitLength());
01096                 ma.m_empty = true;
01097                 Integer e(representative, representative.size());
01098 
01099                 Integer r(ma.m_semisignature, ma.m_semisignature.size());
01100                 return alg.Verify(params, key, e, r, ma.m_s);
01101         }
01102 
01103         DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
01104         {
01105                 this->GetMaterial().DoQuickSanityCheck();
01106 
01107                 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01108                 const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01109                 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01110                 const DL_PublicKey<T> &key = this->GetKeyInterface();
01111 
01112                 SecByteBlock representative(this->MessageRepresentativeLength());
01113                 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
01114                         NullRNG(), 
01115                         ma.m_recoverableMessage, ma.m_recoverableMessage.size(), 
01116                         ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01117                         representative, this->MessageRepresentativeBitLength());
01118                 ma.m_empty = true;
01119                 Integer e(representative, representative.size());
01120 
01121                 ma.m_presignature.New(params.GetEncodedElementSize(false));
01122                 Integer r(ma.m_semisignature, ma.m_semisignature.size());
01123                 alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
01124 
01125                 return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
01126                         ma.AccessHash(), this->GetHashIdentifier(),
01127                         ma.m_presignature, ma.m_presignature.size(),
01128                         ma.m_semisignature, ma.m_semisignature.size(),
01129                         recoveredMessage);
01130         }
01131 };
01132 
01133 //! _
01134 template <class PK, class KI>
01135 class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
01136 {
01137 public:
01138         typedef typename DL_Base<KI>::Element Element;
01139 
01140         size_t MaxPlaintextLength(size_t ciphertextLength) const
01141         {
01142                 unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true);
01143                 return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
01144         }
01145 
01146         size_t CiphertextLength(size_t plaintextLength) const
01147         {
01148                 size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
01149                 return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
01150         }
01151 
01152         bool ParameterSupported(const char *name) const
01153                 {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
01154 
01155 protected:
01156         virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
01157         virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
01158         virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
01159 };
01160 
01161 //! _
01162 template <class T>
01163 class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
01164 {
01165 public:
01166         typedef T Element;
01167 
01168         DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
01169         {
01170                 try
01171                 {
01172                         const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
01173                         const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
01174                         const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
01175                         const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01176                         const DL_PrivateKey<T> &key = this->GetKeyInterface();
01177 
01178                         Element q = params.DecodeElement(ciphertext, true);
01179                         size_t elementSize = params.GetEncodedElementSize(true);
01180                         ciphertext += elementSize;
01181                         ciphertextLength -= elementSize;
01182 
01183                         Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
01184 
01185                         SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
01186                         derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
01187 
01188                         return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
01189                 }
01190                 catch (DL_BadElement &)
01191                 {
01192                         return DecodingResult();
01193                 }
01194         }
01195 };
01196 
01197 //! _
01198 template <class T>
01199 class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
01200 {
01201 public:
01202         typedef T Element;
01203 
01204         void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const
01205         {
01206                 const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
01207                 const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
01208                 const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
01209                 const DL_GroupParameters<T> &params = this->GetAbstractGroupParameters();
01210                 const DL_PublicKey<T> &key = this->GetKeyInterface();
01211 
01212                 Integer x(rng, Integer::One(), params.GetMaxExponent());
01213                 Element q = params.ExponentiateBase(x);
01214                 params.EncodeElement(true, q, ciphertext);
01215                 unsigned int elementSize = params.GetEncodedElementSize(true);
01216                 ciphertext += elementSize;
01217 
01218                 Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
01219 
01220                 SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
01221                 derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
01222 
01223                 encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
01224         }
01225 };
01226 
01227 //! _
01228 template <class T1, class T2>
01229 struct DL_SchemeOptionsBase
01230 {
01231         typedef T1 AlgorithmInfo;
01232         typedef T2 GroupParameters;
01233         typedef typename GroupParameters::Element Element;
01234 };
01235 
01236 //! _
01237 template <class T1, class T2>
01238 struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
01239 {
01240         typedef T2 Keys;
01241         typedef typename Keys::PrivateKey PrivateKey;
01242         typedef typename Keys::PublicKey PublicKey;
01243 };
01244 
01245 //! _
01246 template <class T1, class T2, class T3, class T4, class T5>
01247 struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
01248 {
01249         typedef T3 SignatureAlgorithm;
01250         typedef T4 MessageEncodingMethod;
01251         typedef T5 HashFunction;
01252 };
01253 
01254 //! _
01255 template <class T1, class T2, class T3, class T4, class T5>
01256 struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
01257 {
01258         typedef T3 KeyAgreementAlgorithm;
01259         typedef T4 KeyDerivationAlgorithm;
01260         typedef T5 SymmetricEncryptionAlgorithm;
01261 };
01262 
01263 //! _
01264 template <class BASE, class SCHEME_OPTIONS, class KEY>
01265 class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
01266 {
01267 public:
01268         typedef SCHEME_OPTIONS SchemeOptions;
01269         typedef typename KEY::Element Element;
01270 
01271         PrivateKey & AccessPrivateKey() {return m_key;}
01272         PublicKey & AccessPublicKey() {return m_key;}
01273 
01274         // KeyAccessor
01275         const KEY & GetKey() const {return m_key;}
01276         KEY & AccessKey() {return m_key;}
01277 
01278 protected:
01279         typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
01280         const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
01281 
01282         // for signature scheme
01283         HashIdentifier GetHashIdentifier() const
01284         {
01285                 typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
01286                 return HashLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction>::Lookup();
01287         }
01288         size_t GetDigestSize() const
01289         {
01290                 typedef CPP_TYPENAME SchemeOptions::HashFunction H;
01291                 return H::DIGESTSIZE;
01292         }
01293 
01294 private:
01295         KEY m_key;
01296 };
01297 
01298 //! _
01299 template <class BASE, class SCHEME_OPTIONS, class KEY>
01300 class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
01301 {
01302 public:
01303         typedef typename KEY::Element Element;
01304 
01305 protected:
01306         const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
01307                 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SignatureAlgorithm>().Ref();}
01308         const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
01309                 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();}
01310         const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
01311                 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();}
01312         const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
01313                 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();}
01314         HashIdentifier GetHashIdentifier() const
01315                 {return HashIdentifier();}
01316         const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const 
01317                 {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
01318 };
01319 
01320 //! _
01321 template <class SCHEME_OPTIONS>
01322 class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
01323 {
01324 public:
01325         PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
01326         {
01327                 std::auto_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>);
01328                 this->RestartMessageAccumulator(rng, *p);
01329                 return p.release();
01330         }
01331 };
01332 
01333 //! _
01334 template <class SCHEME_OPTIONS>
01335 class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
01336 {
01337 public:
01338         PK_MessageAccumulator * NewVerificationAccumulator() const
01339         {
01340                 return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
01341         }
01342 };
01343 
01344 //! _
01345 template <class SCHEME_OPTIONS>
01346 class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>
01347 {
01348 };
01349 
01350 //! _
01351 template <class SCHEME_OPTIONS>
01352 class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>
01353 {
01354 };
01355 
01356 // ********************************************************
01357 
01358 //! _
01359 template <class T>
01360 class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain
01361 {
01362 public:
01363         typedef T Element;
01364 
01365         CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
01366         unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
01367         unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
01368         unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
01369 
01370         void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
01371         {
01372                 Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
01373                 x.Encode(privateKey, PrivateKeyLength());
01374         }
01375 
01376         void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
01377         {
01378                 const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
01379                 Integer x(privateKey, PrivateKeyLength());
01380                 Element y = params.ExponentiateBase(x);
01381                 params.EncodeElement(true, y, publicKey);
01382         }
01383         
01384         bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
01385         {
01386                 try
01387                 {
01388                         const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
01389                         Integer x(privateKey, PrivateKeyLength());
01390                         Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
01391 
01392                         Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
01393                                 GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
01394                         params.EncodeElement(false, z, agreedValue);
01395                 }
01396                 catch (DL_BadElement &)
01397                 {
01398                         return false;
01399                 }
01400                 return true;
01401         }
01402 
01403         const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
01404 
01405 protected:
01406         virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
01407         virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
01408         const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
01409 };
01410 
01411 enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION};
01412 typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication;
01413 typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication;
01414 typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication;
01415 
01416 //! DH key agreement algorithm
01417 template <class ELEMENT, class COFACTOR_OPTION>
01418 class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT>
01419 {
01420 public:
01421         typedef ELEMENT Element;
01422 
01423         static const char * CRYPTOPP_API StaticAlgorithmName()
01424                 {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";}
01425 
01426         Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
01427         {
01428                 return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(), 
01429                         COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
01430         }
01431 
01432         Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
01433         {
01434                 if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
01435                 {
01436                         const Integer &k = params.GetCofactor();
01437                         return params.ExponentiateElement(publicElement, 
01438                                 ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
01439                 }
01440                 else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
01441                         return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
01442                 else
01443                 {
01444                         assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
01445 
01446                         if (!validateOtherPublicKey)
01447                                 return params.ExponentiateElement(publicElement, privateExponent);
01448 
01449                         if (params.FastSubgroupCheckAvailable())
01450                         {
01451                                 if (!params.ValidateElement(2, publicElement, NULL))
01452                                         throw DL_BadElement();
01453                                 return params.ExponentiateElement(publicElement, privateExponent);
01454                         }
01455                         else
01456                         {
01457                                 const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
01458                                 Element r[2];
01459                                 params.SimultaneousExponentiate(r, publicElement, e, 2);
01460                                 if (!params.IsIdentity(r[0]))
01461                                         throw DL_BadElement();
01462                                 return r[1];
01463                         }
01464                 }
01465         }
01466 };
01467 
01468 // ********************************************************
01469 
01470 //! A template implementing constructors for public key algorithm classes
01471 template <class BASE>
01472 class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE
01473 {
01474 public:
01475         PK_FinalTemplate() {}
01476 
01477         PK_FinalTemplate(const CryptoMaterial &key)
01478                 {this->AccessKey().AssignFrom(key);}
01479 
01480         PK_FinalTemplate(BufferedTransformation &bt)
01481                 {this->AccessKey().BERDecode(bt);}
01482 
01483         PK_FinalTemplate(const AsymmetricAlgorithm &algorithm)
01484                 {this->AccessKey().AssignFrom(algorithm.GetMaterial());}
01485 
01486         PK_FinalTemplate(const Integer &v1)
01487                 {this->AccessKey().Initialize(v1);}
01488 
01489 #if (defined(_MSC_VER) && _MSC_VER < 1300)
01490 
01491         template <class T1, class T2>
01492         PK_FinalTemplate(T1 &v1, T2 &v2)
01493                 {this->AccessKey().Initialize(v1, v2);}
01494 
01495         template <class T1, class T2, class T3>
01496         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3)
01497                 {this->AccessKey().Initialize(v1, v2, v3);}
01498         
01499         template <class T1, class T2, class T3, class T4>
01500         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4)
01501                 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01502 
01503         template <class T1, class T2, class T3, class T4, class T5>
01504         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5)
01505                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01506 
01507         template <class T1, class T2, class T3, class T4, class T5, class T6>
01508         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6)
01509                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01510 
01511         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01512         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7)
01513                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01514 
01515         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01516         PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
01517                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01518 
01519 #else
01520 
01521         template <class T1, class T2>
01522         PK_FinalTemplate(const T1 &v1, const T2 &v2)
01523                 {this->AccessKey().Initialize(v1, v2);}
01524 
01525         template <class T1, class T2, class T3>
01526         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
01527                 {this->AccessKey().Initialize(v1, v2, v3);}
01528         
01529         template <class T1, class T2, class T3, class T4>
01530         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
01531                 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01532 
01533         template <class T1, class T2, class T3, class T4, class T5>
01534         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
01535                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01536 
01537         template <class T1, class T2, class T3, class T4, class T5, class T6>
01538         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
01539                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01540 
01541         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01542         PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
01543                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01544 
01545         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01546         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)
01547                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01548 
01549         template <class T1, class T2>
01550         PK_FinalTemplate(T1 &v1, const T2 &v2)
01551                 {this->AccessKey().Initialize(v1, v2);}
01552 
01553         template <class T1, class T2, class T3>
01554         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
01555                 {this->AccessKey().Initialize(v1, v2, v3);}
01556         
01557         template <class T1, class T2, class T3, class T4>
01558         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
01559                 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01560 
01561         template <class T1, class T2, class T3, class T4, class T5>
01562         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
01563                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01564 
01565         template <class T1, class T2, class T3, class T4, class T5, class T6>
01566         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
01567                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01568 
01569         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
01570         PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
01571                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01572 
01573         template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
01574         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)
01575                 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01576 
01577 #endif
01578 };
01579 
01580 //! 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.
01581 struct EncryptionStandard {};
01582 
01583 //! 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.
01584 struct SignatureStandard {};
01585 
01586 template <class STANDARD, class KEYS, class ALG_INFO>
01587 class TF_ES;
01588 
01589 //! Trapdoor Function Based Encryption Scheme
01590 template <class STANDARD, class KEYS, class ALG_INFO = TF_ES<STANDARD, KEYS, int> >
01591 class TF_ES : public KEYS
01592 {
01593         typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
01594 
01595 public:
01596         //! see EncryptionStandard for a list of standards
01597         typedef STANDARD Standard;
01598         typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions;
01599 
01600         static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();}
01601 
01602         //! implements PK_Decryptor interface
01603         typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor;
01604         //! implements PK_Encryptor interface
01605         typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor;
01606 };
01607 
01608 template <class STANDARD, class H, class KEYS, class ALG_INFO>  // VC60 workaround: doesn't work if KEYS is first parameter
01609 class TF_SS;
01610 
01611 //! Trapdoor Function Based Signature Scheme
01612 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
01613 class TF_SS : public KEYS
01614 {
01615 public:
01616         //! see SignatureStandard for a list of standards
01617         typedef STANDARD Standard;
01618         typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
01619         typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
01620 
01621         static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
01622 
01623         //! implements PK_Signer interface
01624         typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer;
01625         //! implements PK_Verifier interface
01626         typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier;
01627 };
01628 
01629 template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
01630 class DL_SS;
01631 
01632 //! Discrete Log Based Signature Scheme
01633 template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
01634 class DL_SS : public KEYS
01635 {
01636         typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
01637 
01638 public:
01639         static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
01640 
01641         //! implements PK_Signer interface
01642         typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
01643         //! implements PK_Verifier interface
01644         typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
01645 };
01646 
01647 //! Discrete Log Based Encryption Scheme
01648 template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
01649 class DL_ES : public KEYS
01650 {
01651         typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions;
01652 
01653 public:
01654         //! implements PK_Decryptor interface
01655         typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor;
01656         //! implements PK_Encryptor interface
01657         typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor;
01658 };
01659 
01660 NAMESPACE_END
01661 
01662 #endif

Generated on Sat Dec 23 02:07:09 2006 for Crypto++ by  doxygen 1.5.1-p1