Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

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