- Main Page
- Namespaces
- Classes
- Files

# 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