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

pubkey.h

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

Generated on Sat Jul 10 22:55:26 2004 for Crypto++ by doxygen 1.3.6