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