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

Generated on Tue Jul 8 23:34:22 2003 for Crypto++ by doxygen 1.3.2