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 Fri Jun 1 11:11:23 2007 for Crypto++ by  doxygen 1.5.2