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

pubkey.h

Go to the documentation of this file.
00001 // pubkey.h - written and placed in the public domain by Wei Dai
00002 
00003 #ifndef CRYPTOPP_PUBKEY_H
00004 #define CRYPTOPP_PUBKEY_H
00005 
00006 /** \file
00007 
00008         This file contains helper classes/functions for implementing public key algorithms.
00009 
00010         The class hierachies in this .h file tend to look like this:
00011 <pre>
00012                   x1
00013                  / \
00014                 y1  z1
00015                  |  |
00016             x2<y1>  x2<z1>
00017                  |  |
00018                 y2  z2
00019                  |  |
00020             x3<y2>  x3<z2>
00021                  |  |
00022                 y3  z3
00023 </pre>
00024         - x1, y1, z1 are abstract interface classes defined in cryptlib.h
00025         - x2, y2, z2 are implementations of the interfaces using "abstract policies", which
00026           are pure virtual functions that should return interfaces to interchangeable algorithms.
00027           These classes have "Base" suffixes.
00028         - x3, y3, z3 hold actual algorithms and implement those virtual functions.
00029           These classes have "Impl" suffixes.
00030 
00031         The "TF_" prefix means an implementation using trapdoor functions on integers.
00032         The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard).
00033 */
00034 
00035 #include "modarith.h"
00036 #include "filters.h"
00037 #include "eprecomp.h"
00038 #include "fips140.h"
00039 #include "argnames.h"
00040 #include <memory>
00041 
00042 // VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file
00043 #undef INTERFACE
00044 
00045 NAMESPACE_BEGIN(CryptoPP)
00046 
00047 //! _
00048 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds
00049 {
00050 public:
00051         virtual ~TrapdoorFunctionBounds() {}
00052 
00053         virtual Integer PreimageBound() const =0;
00054         virtual Integer ImageBound() const =0;
00055         virtual Integer MaxPreimage() const {return --PreimageBound();}
00056         virtual Integer MaxImage() const {return --ImageBound();}
00057 };
00058 
00059 //! _
00060 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
00061 {
00062 public:
00063         virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
00064         virtual bool IsRandomized() const {return true;}
00065 };
00066 
00067 //! _
00068 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction
00069 {
00070 public:
00071         Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
00072                 {return ApplyFunction(x);}
00073         bool IsRandomized() const {return false;}
00074 
00075         virtual Integer ApplyFunction(const Integer &x) const =0;
00076 };
00077 
00078 //! _
00079 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
00080 {
00081 public:
00082         virtual ~RandomizedTrapdoorFunctionInverse() {}
00083 
00084         virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
00085         virtual bool IsRandomized() const {return true;}
00086 };
00087 
00088 //! _
00089 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
00090 {
00091 public:
00092         virtual ~TrapdoorFunctionInverse() {}
00093 
00094         Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
00095                 {return CalculateInverse(rng, x);}
00096         bool IsRandomized() const {return false;}
00097 
00098         virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
00099 };
00100 
00101 // ********************************************************
00102 
00103 //! message encoding method for public key encryption
00104 class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
00105 {
00106 public:
00107         virtual ~PK_EncryptionMessageEncodingMethod() {}
00108 
00109         virtual bool ParameterSupported(const char *name) const {return false;}
00110 
00111         //! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
00112         virtual unsigned int MaxUnpaddedLength(unsigned int paddedLength) const =0;
00113 
00114         virtual void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedBitLength, const NameValuePairs &parameters) const =0;
00115 
00116         virtual DecodingResult Unpad(const byte *padded, unsigned int paddedBitLength, byte *raw, const NameValuePairs &parameters) const =0;
00117 };
00118 
00119 // ********************************************************
00120 
00121 //! _
00122 template <class TFI, class MEI>
00123 class CRYPTOPP_NO_VTABLE TF_Base
00124 {
00125 protected:
00126         virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
00127 
00128         typedef TFI TrapdoorFunctionInterface;
00129         virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
00130 
00131         typedef MEI MessageEncodingInterface;
00132         virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
00133 };
00134 
00135 // ********************************************************
00136 
00137 //! _
00138 template <class BASE>
00139 class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
00140 {
00141 public:
00142         unsigned int MaxPlaintextLength(unsigned int ciphertextLength) const
00143                 {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
00144         unsigned int CiphertextLength(unsigned int plaintextLength) const
00145                 {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
00146 
00147         virtual unsigned int FixedMaxPlaintextLength() const =0;
00148         virtual unsigned int FixedCiphertextLength() const =0;
00149 };
00150 
00151 //! _
00152 template <class INTERFACE, class BASE>
00153 class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE
00154 {
00155 public:
00156         bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);}
00157         unsigned int FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
00158         unsigned int FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
00159 
00160 protected:
00161         unsigned int PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
00162         unsigned int PaddedBlockBitLength() const {return this->GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;}
00163 };
00164 
00165 //! _
00166 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
00167 {
00168 public:
00169         DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
00170 };
00171 
00172 //! _
00173 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
00174 {
00175 public:
00176         void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
00177 };
00178 
00179 // ********************************************************
00180 
00181 typedef std::pair<const byte *, unsigned int> HashIdentifier;
00182 
00183 //! interface for message encoding method for public key signature schemes
00184 class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
00185 {
00186 public:
00187         virtual ~PK_SignatureMessageEncodingMethod() {}
00188 
00189         virtual unsigned int 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                 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

Generated on Fri Sep 9 19:01:22 2005 for Crypto++ by  doxygen 1.4.4