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

Generated on Sun Mar 14 20:44:28 2004 for Crypto++ by doxygen 1.3.6-20040222