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