Crypto++

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

pubkey.h
Go to the documentation of this file.

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