// pubkey.h - written and placed in the public domain by Wei Dai #ifndef CRYPTOPP_PUBKEY_H #define CRYPTOPP_PUBKEY_H /** \file This file contains helper classes/functions for implementing public key algorithms. The class hierachies in this .h file tend to look like this:
                  x1
                 / \
                y1  z1
                 |  |
            x2  x2
                 |  |
                y2  z2
                 |  |
            x3  x3
                 |  |
                y3  z3
- x1, y1, z1 are abstract interface classes defined in cryptlib.h - x2, y2, z2 are implementations of the interfaces using "abstract policies", which are pure virtual functions that should return interfaces to interchangeable algorithms. These classes have "Base" suffixes. - x3, y3, z3 hold actual algorithms and implement those virtual functions. These classes have "Impl" suffixes. The "TF_" prefix means an implementation using trapdoor functions on integers. The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard). */ #include "integer.h" #include "filters.h" #include "eprecomp.h" #include "fips140.h" #include "argnames.h" #include // VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file #undef INTERFACE NAMESPACE_BEGIN(CryptoPP) Integer NR_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen); Integer DSA_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen); template struct CryptoStandardTraits { typedef typename STANDARD::EncryptionPaddingAlgorithm EncryptionPaddingAlgorithm; template class SignaturePaddingAlgorithm {}; template class DecoratedHashingAlgorithm {}; }; // ******************************************************** //! . class TrapdoorFunctionBounds { public: virtual ~TrapdoorFunctionBounds() {} virtual Integer PreimageBound() const =0; virtual Integer ImageBound() const =0; virtual Integer MaxPreimage() const {return --PreimageBound();} virtual Integer MaxImage() const {return --ImageBound();} }; //! . class RandomizedTrapdoorFunction : public TrapdoorFunctionBounds { public: virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0; }; //! . class TrapdoorFunction : public RandomizedTrapdoorFunction { public: Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const {return ApplyFunction(x);} virtual Integer ApplyFunction(const Integer &x) const =0; }; //! . class RandomizedTrapdoorFunctionInverse { public: virtual ~RandomizedTrapdoorFunctionInverse() {} virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0; }; //! . class TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse { public: virtual ~TrapdoorFunctionInverse() {} Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const {return CalculateInverse(x);} virtual Integer CalculateInverse(const Integer &x) const =0; }; // ******************************************************** //! . class PK_PaddingAlgorithm { public: virtual ~PK_PaddingAlgorithm() {} virtual unsigned int MaxUnpaddedLength(unsigned int paddedLength) const =0; virtual void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedBitLength) const =0; virtual DecodingResult Unpad(const byte *padded, unsigned int paddedBitLength, byte *raw) const =0; virtual bool IsReversible() const {return true;} }; //! . class PK_NonreversiblePaddingAlgorithm : public PK_PaddingAlgorithm { DecodingResult Unpad(const byte *padded, unsigned int paddedBitLength, byte *raw) const {assert(false); return DecodingResult();} bool IsReversible() const {return false;} }; // ******************************************************** //! . template class TF_Base { protected: unsigned int PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());} virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0; virtual const PK_PaddingAlgorithm & GetPaddingAlgorithm() const =0; virtual unsigned int PaddedBlockBitLength() const =0; typedef TFI TrapdoorFunctionInterface; virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0; }; // ******************************************************** //! . template class TF_CryptoSystemBase : public INTERFACE, protected BASE { public: unsigned int FixedMaxPlaintextLength() const {return GetPaddingAlgorithm().MaxUnpaddedLength(PaddedBlockBitLength());} unsigned int FixedCiphertextLength() const {return GetTrapdoorFunctionBounds().MaxImage().ByteCount();} protected: unsigned int PaddedBlockBitLength() const {return GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;} }; //! . class TF_DecryptorBase : public TF_CryptoSystemBase > { public: DecodingResult FixedLengthDecrypt(const byte *cipherText, byte *plainText) const; }; //! . class TF_EncryptorBase : public TF_CryptoSystemBase > { public: void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const; }; // ******************************************************** //! . class DigestSignatureSystem { public: virtual unsigned int MaxDigestLength() const =0; virtual unsigned int DigestSignatureLength() const =0; }; //! . class DigestSigner : virtual public DigestSignatureSystem, public PrivateKeyAlgorithm { public: virtual void SignDigest(RandomNumberGenerator &rng, const byte *digest, unsigned int digestLen, byte *signature) const =0; }; //! . class DigestVerifier : virtual public DigestSignatureSystem, public PublicKeyAlgorithm { public: virtual bool VerifyDigest(const byte *digest, unsigned int digestLen, const byte *sig) const =0; }; // ******************************************************** //! . template class TF_DigestSignatureSystemBase : public INTERFACE, protected BASE { public: unsigned int MaxDigestLength() const {return GetPaddingAlgorithm().MaxUnpaddedLength(PaddedBlockBitLength());} unsigned int DigestSignatureLength() const {return GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();} protected: unsigned int PaddedBlockBitLength() const {return GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;} }; //! . class TF_DigestSignerBase : public TF_DigestSignatureSystemBase > { public: void SignDigest(RandomNumberGenerator &rng, const byte *message, unsigned int messageLength, byte *signature) const; }; //! . class TF_DigestVerifierBase : public TF_DigestSignatureSystemBase > { public: bool VerifyDigest(const byte *digest, unsigned int digestLen, const byte *sig) const; }; // ******************************************************** //! . template struct TF_SchemeOptions { typedef T1 AlgorithmInfo; typedef T2 Keys; typedef typename Keys::PrivateKey PrivateKey; typedef typename Keys::PublicKey PublicKey; typedef T3 PaddingAlgorithm; }; //! . template class PublicKeyCopier { public: virtual void CopyKeyInto(typename KEYS::PublicKey &key) const =0; }; //! . template class PrivateKeyCopier { public: virtual void CopyKeyInto(typename KEYS::PublicKey &key) const =0; virtual void CopyKeyInto(typename KEYS::PrivateKey &key) const =0; }; //! . template class TF_ObjectImplBase : public AlgorithmImpl { public: typedef SCHEME_OPTIONS SchemeOptions; typedef KEY KeyClass; PublicKey & AccessPublicKey() {return AccessKey();} const PublicKey & GetPublicKey() const {return GetKey();} PrivateKey & AccessPrivateKey() {return AccessKey();} const PrivateKey & GetPrivateKey() const {return GetKey();} virtual const KeyClass & GetKey() const =0; virtual KeyClass & AccessKey() =0; const KeyClass & GetTrapdoorFunction() const {return GetKey();} protected: const PK_PaddingAlgorithm & GetPaddingAlgorithm() const {static typename SCHEME_OPTIONS::PaddingAlgorithm paddingScheme; return paddingScheme;} const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const {return GetKey();} const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const {return GetKey();} }; //! . template class TF_ObjectImplExtRef : public TF_ObjectImplBase { public: TF_ObjectImplExtRef(const KEY *pKey = NULL) : m_pKey(pKey) {} void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;} const KEY & GetKey() const {return *m_pKey;} KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");} void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const {assert(false);} void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {assert(false);} private: const KEY * m_pKey; }; //! . template class TF_ObjectImpl : public TF_ObjectImplBase { public: const KEY & GetKey() const {return m_trapdoorFunction;} KEY & AccessKey() {return m_trapdoorFunction;} private: KEY m_trapdoorFunction; }; //! . template class TF_PublicObjectImpl : public TF_ObjectImpl, public PublicKeyCopier { public: void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {key = GetKey();} }; //! . template class TF_PrivateObjectImpl : public TF_ObjectImpl, public PrivateKeyCopier { public: void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const {key = GetKey();} void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {key = GetKey();} }; //! . template class TF_DecryptorImpl : public TF_PrivateObjectImpl { }; //! . template class TF_EncryptorImpl : public TF_PublicObjectImpl { }; //! . template class TF_DigestSignerImpl : public TF_PrivateObjectImpl { }; //! . template class TF_DigestVerifierImpl : public TF_PublicObjectImpl { }; // ******************************************************** //! . template class P1363_MGF1 { public: static std::string StaticAlgorithmName() {return std::string("MGF1(") + H::StaticAlgorithmName() + ")";} static void GenerateAndMask(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength); }; template void P1363_MGF1::GenerateAndMask(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength) { H h; ArrayXorSink *sink; HashFilter filter(h, sink = new ArrayXorSink(output, outputLength)); word32 counter = 0; while (sink->AvailableSize() > 0) { filter.Put(input, inputLength); filter.PutWord32(counter++); filter.MessageEnd(); } } // ******************************************************** //! . template class P1363_KDF2 { public: static void DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength); }; template void P1363_KDF2::DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength) { H h; ArraySink *sink; HashFilter filter(h, sink = new ArraySink(output, outputLength)); word32 counter = 1; while (sink->AvailableSize() > 0) { filter.Put(input, inputLength); filter.PutWord32(counter++); filter.MessageEnd(); } } // ******************************************************** //! . template class PK_SignatureSchemeBase : public INTERFACE { public: unsigned int SignatureLength() const {return GetDigestSignatureSchemeInterface().DigestSignatureLength();} HashTransformation * NewMessageAccumulator() const {return new H;} virtual const DS_INTERFACE & GetDigestSignatureSchemeInterface() const =0; }; //! . template class PK_SignerBase : public PK_SignatureSchemeBase { public: void SignAndRestart(RandomNumberGenerator &rng, HashTransformation &messageAccumulator, byte *signature) const; }; //! . template class PK_VerifierBase : public PK_SignatureSchemeBase { public: bool VerifyAndRestart(HashTransformation &messageAccumulator, const byte *sig) const; }; template void PK_SignerBase::SignAndRestart(RandomNumberGenerator &rng, HashTransformation &messageAccumulator, byte *signature) const { if (messageAccumulator.DigestSize() > GetDigestSignatureSchemeInterface().MaxDigestLength()) throw PK_Signer::KeyTooShort(); SecByteBlock digest(messageAccumulator.DigestSize()); messageAccumulator.Final(digest); GetDigestSignatureSchemeInterface().SignDigest(rng, digest, digest.size(), signature); } template bool PK_VerifierBase::VerifyAndRestart(HashTransformation &messageAccumulator, const byte *sig) const { SecByteBlock digest(messageAccumulator.DigestSize()); messageAccumulator.Final(digest); return GetDigestSignatureSchemeInterface().VerifyDigest(digest, digest.size(), sig); } //! . template class PK_SignatureSchemeImpl : public BASE { public: typedef typename DS::KeyClass KeyClass; // PublicKeyAlgorithm or PrivateKeyAlgorithm std::string AlgorithmName() const {return m_ds.AlgorithmName();} PrivateKey & AccessPrivateKey() {return m_ds.AccessPrivateKey();} const PrivateKey & GetPrivateKey() const {return m_ds.GetPrivateKey();} PublicKey & AccessPublicKey() {return m_ds.AccessPublicKey();} const PublicKey & GetPublicKey() const {return m_ds.GetPublicKey();} KeyClass & AccessKey() {return m_ds.AccessKey();} const KeyClass & GetKey() const {return m_ds.GetKey();} const KeyClass & GetTrapdoorFunction() const {return m_ds.GetTrapdoorFunction();} DS & AccessDigestSignatureScheme() {return m_ds;} const DS & GetDigestSignatureScheme() const {return m_ds;} protected: DS m_ds; }; //! . template class PK_SignerImpl : public PK_SignatureSchemeImpl, DS>, public PrivateKeyCopier { const DigestSigner & GetDigestSignatureSchemeInterface() const {return m_ds;} public: // PrivateKeyCopier void CopyKeyInto(typename DS::SchemeOptions::PublicKey &key) const {m_ds.CopyKeyInto(key);} void CopyKeyInto(typename DS::SchemeOptions::PrivateKey &key) const {m_ds.CopyKeyInto(key);} }; //! . template class PK_VerifierImpl : public PK_SignatureSchemeImpl, DS>, public PublicKeyCopier { const DigestVerifier & GetDigestSignatureSchemeInterface() const {return m_ds;} public: // PublicKeyCopier void CopyKeyInto(typename DS::SchemeOptions::PublicKey &key) const {m_ds.CopyKeyInto(key);} }; // ******************************************************** //! . class SignatureEncodingMethodWithRecovery : public HashTransformationWithDefaultTruncation { public: void Final(byte *digest) {} virtual void Encode(RandomNumberGenerator &rng, byte *representative) =0; virtual bool Verify(const byte *representative) =0; virtual DecodingResult Decode(byte *message) =0; virtual unsigned int MaximumRecoverableLength() const =0; }; //! . template class SignatureSystemWithRecoveryBaseTemplate : virtual public PK_SignatureSchemeWithRecovery { public: unsigned int SignatureLength() const {return GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();} HashTransformation * NewMessageAccumulator() const {return new H(PaddedBlockBitLength());} unsigned int MaximumRecoverableLength() const {return H::MaximumRecoverableLength(PaddedBlockBitLength());} bool AllowLeftoverMessage() const {return H::AllowLeftoverMessage();} protected: unsigned int PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());} unsigned int PaddedBlockBitLength() const {return GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;} virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0; }; //! . template class SignerWithRecoveryTemplate : virtual public SignatureSystemWithRecoveryBaseTemplate, virtual public PK_SignerWithRecovery, public TF { public: typedef TF KeyClass; const KeyClass & GetKey() const {return *this;} KeyClass & AccessKey() {return *this;} PrivateKey & AccessPrivateKey() {return *this;} SignerWithRecoveryTemplate() {} void SignAndRestart(RandomNumberGenerator &rng, HashTransformation &messageAccumulator, byte *signature) const; const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const {return *this;} }; //! . template class VerifierWithRecoveryTemplate : virtual public SignatureSystemWithRecoveryBaseTemplate, virtual public PK_VerifierWithRecovery, public TF { public: typedef TF KeyClass; const KeyClass & GetKey() const {return *this;} KeyClass & AccessKey() {return *this;} PublicKey & AccessPublicKey() {return *this;} VerifierWithRecoveryTemplate() {} bool VerifyAndRestart(HashTransformation &messageAccumulator, const byte *sig) const; bool SignatureUpfrontForRecovery() const {return true;} HashTransformation * NewRecoveryAccumulator(const byte *signature) const; DecodingResult Recover(byte *recoveredMessage, HashTransformation *recoveryAccumulator, const byte *signature) const; const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const {return *this;} }; template void SignerWithRecoveryTemplate::SignAndRestart(RandomNumberGenerator &rng, HashTransformation &messageAccumulator, byte *signature) const { H &ma = static_cast(messageAccumulator); if (ma.MaximumRecoverableLength() == 0) throw KeyTooShort(); SecByteBlock representative(PaddedBlockByteLength()); ma.Encode(rng, representative); CalculateInverse(Integer(representative, representative.size())).Encode(signature, SignatureLength()); } template bool VerifierWithRecoveryTemplate::VerifyAndRestart(HashTransformation &messageAccumulator, const byte *signature) const { SecByteBlock representative(PaddedBlockByteLength()); ApplyFunction(Integer(signature, SignatureLength())).Encode(representative, representative.size()); return messageAccumulator.Verify(representative); } template HashTransformation * VerifierWithRecoveryTemplate::NewRecoveryAccumulator(const byte *signature) const { SecByteBlock representative(PaddedBlockByteLength()); ApplyFunction(Integer(signature, SignatureLength())).Encode(representative, representative.size()); return new H(representative, PaddedBlockBitLength()); } template DecodingResult VerifierWithRecoveryTemplate::Recover(byte *recoveredMessage, HashTransformation *recoveryAccumulator, const byte *signature) const { std::auto_ptr ma(static_cast(recoveryAccumulator)); return ma->Decode(recoveredMessage); } // ******************************************************** // to be thrown by DecodeElement and AgreeWithStaticPrivateKey class DL_BadElement : public InvalidDataFormat { public: DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {} }; //! . template class DL_GroupParameters : public CryptoParameters { typedef DL_GroupParameters ThisClass; public: typedef T Element; DL_GroupParameters() : m_validationLevel(0) {} // CryptoMaterial bool Validate(RandomNumberGenerator &rng, unsigned int level) const { if (!GetBasePrecomputation().IsInitialized()) return false; if (m_validationLevel > level) return true; bool pass = ValidateGroup(rng, level); pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation()); m_validationLevel = pass ? level+1 : 0; return pass; } bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const { return GetValueHelper(this, name, valueType, pValue) CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder) CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator) ; } bool SupportsPrecomputation() const {return true;} void Precompute(unsigned int precomputationStorage=16) { AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage); } void LoadPrecomputation(BufferedTransformation &storedPrecomputation) { AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation); m_validationLevel = 0; } void SavePrecomputation(BufferedTransformation &storedPrecomputation) const { GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation); } // non-inherited virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());} virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);} virtual Element ExponentiateBase(const Integer &exponent) const { return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent); } virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const { Element result; SimultaneousExponentiate(&result, base, &exponent, 1); return result; } virtual const DL_GroupPrecomputation & GetGroupPrecomputation() const =0; virtual const DL_FixedBasePrecomputation & GetBasePrecomputation() const =0; virtual DL_FixedBasePrecomputation & AccessBasePrecomputation() =0; virtual const Integer & GetSubgroupOrder() const =0; // order of subgroup generated by base element virtual Integer GetMaxExponent() const =0; virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();} // one of these two needs to be overriden virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();} virtual unsigned int GetEncodedElementSize(bool reversible) const =0; virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0; virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0; virtual Integer ConvertElementToInteger(const Element &element) const =0; virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0; virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation *precomp) const =0; virtual bool FastSubgroupCheckAvailable() const =0; virtual bool IsIdentity(const Element &element) const =0; virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0; protected: void ParametersChanged() {m_validationLevel = 0;} private: mutable unsigned int m_validationLevel; }; //! . template , class BASE = DL_GroupParameters > class DL_GroupParametersImpl : public BASE { public: typedef GROUP_PRECOMP GroupPrecomputation; typedef typename GROUP_PRECOMP::Element Element; typedef BASE_PRECOMP BasePrecomputation; const DL_GroupPrecomputation & GetGroupPrecomputation() const {return m_groupPrecomputation;} const DL_FixedBasePrecomputation & GetBasePrecomputation() const {return m_gpc;} DL_FixedBasePrecomputation & AccessBasePrecomputation() {return m_gpc;} protected: GROUP_PRECOMP m_groupPrecomputation; BASE_PRECOMP m_gpc; }; //! . template class DL_Key { public: virtual const DL_GroupParameters & GetAbstractGroupParameters() const =0; virtual DL_GroupParameters & AccessAbstractGroupParameters() =0; }; //! . template class DL_PublicKey : public DL_Key { typedef DL_PublicKey ThisClass; public: typedef T Element; bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const { return GetAbstractGroupParameters().GetVoidValue(name, valueType, pValue) || GetValueHelper(this, name, valueType, pValue) CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement); } void AssignFrom(const NameValuePairs &source); // non-inherited virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(GetAbstractGroupParameters().GetGroupPrecomputation());} virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(GetAbstractGroupParameters().GetGroupPrecomputation(), y);} virtual Element ExponentiatePublicElement(const Integer &exponent) const { const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent); } virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const { const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp); } virtual const DL_FixedBasePrecomputation & GetPublicPrecomputation() const =0; virtual DL_FixedBasePrecomputation & AccessPublicPrecomputation() =0; }; //! . template class DL_PrivateKey : public DL_Key { typedef DL_PrivateKey ThisClass; public: typedef T Element; void MakePublicKey(DL_PublicKey &pub) const { pub.AccessAbstractGroupParameters().AssignFrom(GetAbstractGroupParameters()); pub.SetPublicElement(GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent())); } bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const { return GetAbstractGroupParameters().GetVoidValue(name, valueType, pValue) || GetValueHelper(this, name, valueType, pValue) CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent); } void AssignFrom(const NameValuePairs &source) { AccessAbstractGroupParameters().AssignFrom(source); AssignFromHelper(this, source) CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent); } virtual const Integer & GetPrivateExponent() const =0; virtual void SetPrivateExponent(const Integer &x) =0; }; template void DL_PublicKey::AssignFrom(const NameValuePairs &source) { DL_PrivateKey *pPrivateKey = NULL; if (source.GetThisPointer(pPrivateKey)) pPrivateKey->MakePublicKey(*this); else { AccessAbstractGroupParameters().AssignFrom(source); AssignFromHelper(this, source) CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement); } } class OID; //! . template class DL_KeyImpl : public PK { public: typedef GP GroupParameters; OID GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();} // void BERDecode(BufferedTransformation &bt) // {PK::BERDecode(bt);} // void DEREncode(BufferedTransformation &bt) const // {PK::DEREncode(bt);} bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) {AccessGroupParameters().BERDecode(bt); return true;} bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const {GetGroupParameters().DEREncode(bt); return true;} const GP & GetGroupParameters() const {return m_groupParameters;} GP & AccessGroupParameters() {return m_groupParameters;} private: GP m_groupParameters; }; class X509PublicKey; class PKCS8PrivateKey; //! . template class DL_PrivateKeyImpl : public DL_PrivateKey, public DL_KeyImpl { public: typedef typename GP::Element Element; // GeneratableCryptoMaterial bool Validate(RandomNumberGenerator &rng, unsigned int level) const { bool pass = GetAbstractGroupParameters().Validate(rng, level); const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder(); const Integer &x = GetPrivateExponent(); pass = pass && x.IsPositive() && x < q; if (level >= 1) pass = pass && Integer::Gcd(x, q) == Integer::One(); return pass; } bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const { return GetValueHelper >(this, name, valueType, pValue).Assignable(); } void AssignFrom(const NameValuePairs &source) { AssignFromHelper >(this, source); } void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms) { if (!params.GetThisObject(AccessGroupParameters())) AccessGroupParameters().GenerateRandom(rng, params); // std::pair seed; Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); // Integer::ANY, Integer::Zero(), Integer::One(), // params.GetValue("DeterministicKeyGenerationSeed", seed) ? &seed : NULL); SetPrivateExponent(x); } bool SupportsPrecomputation() const {return true;} void Precompute(unsigned int precomputationStorage=16) {AccessAbstractGroupParameters().Precompute(precomputationStorage);} void LoadPrecomputation(BufferedTransformation &storedPrecomputation) {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);} void SavePrecomputation(BufferedTransformation &storedPrecomputation) const {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);} // DL_Key const DL_GroupParameters & GetAbstractGroupParameters() const {return GetGroupParameters();} DL_GroupParameters & AccessAbstractGroupParameters() {return AccessGroupParameters();} // DL_PrivateKey const Integer & GetPrivateExponent() const {return m_x;} void SetPrivateExponent(const Integer &x) {m_x = x;} // PKCS8PrivateKey void BERDecodeKey(BufferedTransformation &bt) {m_x.BERDecode(bt);} void DEREncodeKey(BufferedTransformation &bt) const {m_x.DEREncode(bt);} private: Integer m_x; }; //! . template class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE { public: void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms) { BASE::GenerateRandom(rng, params); if (FIPS_140_2_ComplianceEnabled()) { typename SIGNATURE_SCHEME::Signer signer(*this); typename SIGNATURE_SCHEME::Verifier verifier(signer); SignaturePairwiseConsistencyTest(signer, verifier); } } }; //! . template class DL_PublicKeyImpl : public DL_PublicKey, public DL_KeyImpl { public: typedef typename GP::Element Element; // CryptoMaterial bool Validate(RandomNumberGenerator &rng, unsigned int level) const { bool pass = GetAbstractGroupParameters().Validate(rng, level); pass = pass && GetAbstractGroupParameters().ValidateElement(level, GetPublicElement(), &GetPublicPrecomputation()); return pass; } bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const { return GetValueHelper >(this, name, valueType, pValue).Assignable(); } void AssignFrom(const NameValuePairs &source) { AssignFromHelper >(this, source); } bool SupportsPrecomputation() const {return true;} void Precompute(unsigned int precomputationStorage=16) { AccessAbstractGroupParameters().Precompute(precomputationStorage); AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage); } void LoadPrecomputation(BufferedTransformation &storedPrecomputation) { AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation); AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation); } void SavePrecomputation(BufferedTransformation &storedPrecomputation) const { GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation); GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation); } // DL_Key const DL_GroupParameters & GetAbstractGroupParameters() const {return GetGroupParameters();} DL_GroupParameters & AccessAbstractGroupParameters() {return AccessGroupParameters();} // DL_PublicKey const DL_FixedBasePrecomputation & GetPublicPrecomputation() const {return m_ypc;} DL_FixedBasePrecomputation & AccessPublicPrecomputation() {return m_ypc;} // non-inherited bool operator==(const DL_PublicKeyImpl &rhs) const {return GetGroupParameters() == rhs.GetGroupParameters() && GetPublicElement() == rhs.GetPublicElement();} private: typename GP::BasePrecomputation m_ypc; }; //! . template class DL_ElgamalLikeSignatureAlgorithm { public: virtual Integer EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLength) const =0; virtual bool Sign(const DL_GroupParameters ¶ms, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0; virtual bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0; virtual unsigned int RLen(const DL_GroupParameters ¶ms) const {return params.GetSubgroupOrder().ByteCount();} virtual unsigned int SLen(const DL_GroupParameters ¶ms) const {return params.GetSubgroupOrder().ByteCount();} }; //! . template class DL_KeyAgreementAlgorithm { public: typedef T Element; virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters ¶ms, const DL_FixedBasePrecomputation &publicPrecomputation, const Integer &privateExponent) const =0; virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0; }; //! . template class DL_KeyDerivationAlgorithm { public: virtual void Derive(const DL_GroupParameters ¶ms, byte *derivedKey, unsigned int derivedLength, const T &agreedElement, const T &ephemeralPublicKey) const =0; }; //! . class DL_SymmetricEncryptionAlgorithm { public: virtual unsigned int GetSymmetricKeyLength(unsigned int plainTextLength) const =0; virtual unsigned int GetSymmetricCiphertextLength(unsigned int plainTextLength) const =0; virtual unsigned int GetMaxSymmetricPlaintextLength(unsigned int cipherTextLength) const =0; virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const =0; virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const =0; }; //! . template class DL_Base { protected: typedef KI KeyInterface; typedef typename KI::Element Element; const DL_GroupParameters & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();} DL_GroupParameters & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();} virtual KeyInterface & AccessKeyInterface() =0; virtual const KeyInterface & GetKeyInterface() const =0; }; //! . template class DL_DigestSignatureSystemBase : public INTERFACE, public DL_Base { public: unsigned int MaxDigestLength() const {return UINT_MAX;} unsigned int DigestSignatureLength() const { return GetSignatureAlgorithm().RLen(GetAbstractGroupParameters()) + GetSignatureAlgorithm().SLen(GetAbstractGroupParameters()); } protected: virtual const DL_ElgamalLikeSignatureAlgorithm & GetSignatureAlgorithm() const =0; }; //! . template class DL_DigestSignerBase : public DL_DigestSignatureSystemBase > { public: // for validation testing void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const { const DL_ElgamalLikeSignatureAlgorithm &alg = GetSignatureAlgorithm(); const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); const DL_PrivateKey &key = GetKeyInterface(); alg.Sign(params, key.GetPrivateExponent(), k, e, r, s); } void SignDigest(RandomNumberGenerator &rng, const byte *digest, unsigned int digestLength, byte *signature) const { const DL_ElgamalLikeSignatureAlgorithm &alg = GetSignatureAlgorithm(); const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); const DL_PrivateKey &key = GetKeyInterface(); GetMaterial().DoQuickSanityCheck(); const Integer &q = params.GetSubgroupOrder(); Integer e = alg.EncodeDigest(q.BitCount(), digest, digestLength); Integer k, r, s; do {k.Randomize(rng, 1, params.GetSubgroupOrder()-1);} while (!alg.Sign(params, key.GetPrivateExponent(), k, e, r, s)); unsigned int rLen = alg.RLen(params); r.Encode(signature, rLen); s.Encode(signature+rLen, alg.SLen(params)); } }; //! . template class DL_DigestVerifierBase : public DL_DigestSignatureSystemBase > { public: bool VerifyDigest(const byte *digest, unsigned int digestLength, const byte *signature) const { const DL_ElgamalLikeSignatureAlgorithm &alg = GetSignatureAlgorithm(); const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); const DL_PublicKey &key = GetKeyInterface(); GetMaterial().DoQuickSanityCheck(); const Integer &q = params.GetSubgroupOrder(); Integer e = alg.EncodeDigest(q.BitCount(), digest, digestLength); unsigned int rLen = alg.RLen(params); Integer r(signature, rLen); Integer s(signature+rLen, alg.SLen(params)); return alg.Verify(params, key, e, r, s); } }; //! . template class DL_CryptoSystemBase : public PK, public DL_Base { public: typedef typename DL_Base::Element Element; unsigned int MaxPlaintextLength(unsigned int cipherTextLength) const { unsigned int minLen = GetAbstractGroupParameters().GetEncodedElementSize(true); return cipherTextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(cipherTextLength - minLen); } unsigned int CiphertextLength(unsigned int plainTextLength) const { unsigned int len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plainTextLength); return len == 0 ? 0 : GetAbstractGroupParameters().GetEncodedElementSize(true) + len; } protected: virtual const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const =0; virtual const DL_KeyDerivationAlgorithm & GetKeyDerivationAlgorithm() const =0; virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0; }; //! . template class DL_DecryptorBase : public DL_CryptoSystemBase > { public: typedef T Element; DecodingResult Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const { try { const DL_KeyAgreementAlgorithm &agreeAlg = GetKeyAgreementAlgorithm(); const DL_KeyDerivationAlgorithm &derivAlg = GetKeyDerivationAlgorithm(); const DL_SymmetricEncryptionAlgorithm &encAlg = GetSymmetricEncryptionAlgorithm(); const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); const DL_PrivateKey &key = GetKeyInterface(); Element q = params.DecodeElement(cipherText, true); unsigned int elementSize = params.GetEncodedElementSize(true); cipherText += elementSize; cipherTextLength -= elementSize; Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent()); SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(cipherTextLength))); derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q); return encAlg.SymmetricDecrypt(derivedKey, cipherText, cipherTextLength, plainText); } catch (DL_BadElement &) { return DecodingResult(); } } }; //! . template class DL_EncryptorBase : public DL_CryptoSystemBase > { public: typedef T Element; void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const { const DL_KeyAgreementAlgorithm &agreeAlg = GetKeyAgreementAlgorithm(); const DL_KeyDerivationAlgorithm &derivAlg = GetKeyDerivationAlgorithm(); const DL_SymmetricEncryptionAlgorithm &encAlg = GetSymmetricEncryptionAlgorithm(); const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); const DL_PublicKey &key = GetKeyInterface(); Integer x(rng, Integer::One(), params.GetMaxExponent()); Element q = params.ExponentiateBase(x); params.EncodeElement(true, q, cipherText); unsigned int elementSize = params.GetEncodedElementSize(true); cipherText += elementSize; Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x); SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plainTextLength)); derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q); encAlg.SymmetricEncrypt(rng, derivedKey, plainText, plainTextLength, cipherText); } }; //! . template struct DL_SchemeOptionsBase { typedef T1 AlgorithmInfo; typedef T2 GroupParameters; typedef typename GroupParameters::Element Element; }; //! . template struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase { typedef T2 Keys; typedef typename Keys::PrivateKey PrivateKey; typedef typename Keys::PublicKey PublicKey; }; //! . template struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions { typedef T3 SignatureAlgorithm; }; //! . template struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions { typedef T3 KeyAgreementAlgorithm; typedef T4 KeyDerivationAlgorithm; typedef T5 SymmetricEncryptionAlgorithm; }; //! . template class DL_ObjectImplBase : public AlgorithmImpl { public: typedef SCHEME_OPTIONS SchemeOptions; typedef KEY KeyClass; typedef typename KeyClass::Element Element; PrivateKey & AccessPrivateKey() {return m_key;} PublicKey & AccessPublicKey() {return m_key;} // KeyAccessor const KeyClass & GetKey() const {return m_key;} KeyClass & AccessKey() {return m_key;} protected: typename BASE::KeyInterface & AccessKeyInterface() {return m_key;} const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;} private: KeyClass m_key; }; //! . template class DL_ObjectImpl : public DL_ObjectImplBase { public: typedef typename KEY::Element Element; protected: const DL_ElgamalLikeSignatureAlgorithm & GetSignatureAlgorithm() const {static typename SCHEME_OPTIONS::SignatureAlgorithm a; return a;} const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const {static typename SCHEME_OPTIONS::KeyAgreementAlgorithm a; return a;} const DL_KeyDerivationAlgorithm & GetKeyDerivationAlgorithm() const {static typename SCHEME_OPTIONS::KeyDerivationAlgorithm a; return a;} const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {static typename SCHEME_OPTIONS::SymmetricEncryptionAlgorithm a; return a;} }; //! . template class DL_PublicObjectImpl : public DL_ObjectImpl, public PublicKeyCopier { public: void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {key = GetKey();} }; //! . template class DL_PrivateObjectImpl : public DL_ObjectImpl, public PrivateKeyCopier { public: void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {GetKey().MakePublicKey(key);} void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const {key = GetKey();} }; //! . template class DL_DigestSignerImpl : public DL_PrivateObjectImpl, SCHEME_OPTIONS> { }; //! . template class DL_DigestVerifierImpl : public DL_PublicObjectImpl, SCHEME_OPTIONS> { }; //! . template class DL_EncryptorImpl : public DL_PublicObjectImpl, SCHEME_OPTIONS> { }; //! . template class DL_DecryptorImpl : public DL_PrivateObjectImpl, SCHEME_OPTIONS> { }; // ******************************************************** //! . template class DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain { public: typedef T Element; CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);} void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const { Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); x.Encode(privateKey, PrivateKeyLength()); } void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const { const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); Integer x(privateKey, PrivateKeyLength()); Element y = params.ExponentiateBase(x); params.EncodeElement(true, y, publicKey); } bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const { try { const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); Integer x(privateKey, PrivateKeyLength()); Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey); Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey( GetAbstractGroupParameters(), w, validateOtherPublicKey, x); params.EncodeElement(false, z, agreedValue); } catch (DL_BadElement &) { return false; } return true; } const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();} protected: virtual const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const =0; virtual DL_GroupParameters & AccessAbstractGroupParameters() =0; const DL_GroupParameters & GetAbstractGroupParameters() const {return const_cast *>(this)->AccessAbstractGroupParameters();} }; enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION}; typedef EnumToType NoCofactorMultiplication; typedef EnumToType CompatibleCofactorMultiplication; typedef EnumToType IncompatibleCofactorMultiplication; //! DH key agreement algorithm template class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm { public: typedef ELEMENT Element; static const char *StaticAlgorithmName() {return COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION ? "DH" : "DHC";} Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters ¶ms, const DL_FixedBasePrecomputation &publicPrecomputation, const Integer &privateExponent) const { return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(), COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent); } Element AgreeWithStaticPrivateKey(const DL_GroupParameters ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const { if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION) { const Integer &k = params.GetCofactor(); return params.ExponentiateElement(publicElement, ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k); } else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION) return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor()); else { assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION); if (!validateOtherPublicKey) return params.ExponentiateElement(publicElement, privateExponent); if (params.FastSubgroupCheckAvailable()) { if (!params.ValidateElement(2, publicElement, NULL)) throw DL_BadElement(); return params.ExponentiateElement(publicElement, privateExponent); } else { const Integer e[2] = {params.GetSubgroupOrder(), privateExponent}; Element r[2]; params.SimultaneousExponentiate(r, publicElement, e, 2); if (!params.IsIdentity(r[0])) throw DL_BadElement(); return r[1]; } } } }; // ******************************************************** //! A template implementing constructors for public key algorithm classes template class PK_FinalTemplate : public BASE { public: PK_FinalTemplate() {} PK_FinalTemplate(const Integer &v1) {AccessKey().Initialize(v1);} PK_FinalTemplate(const typename BASE::KeyClass &key) {AccessKey().operator=(key);} template PK_FinalTemplate(const PublicKeyCopier &key) {key.CopyKeyInto(AccessKey());} template PK_FinalTemplate(const PrivateKeyCopier &key) {key.CopyKeyInto(AccessKey());} PK_FinalTemplate(BufferedTransformation &bt) {AccessKey().BERDecode(bt);} #if (defined(_MSC_VER) && _MSC_VER < 1300) template PK_FinalTemplate(T1 &v1, T2 &v2) {AccessKey().Initialize(v1, v2);} template PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3) {AccessKey().Initialize(v1, v2, v3);} template PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4) {AccessKey().Initialize(v1, v2, v3, v4);} template PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5) {AccessKey().Initialize(v1, v2, v3, v4, v5);} template PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6) {AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} template PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7) {AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} template PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8) {AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} #else template PK_FinalTemplate(const T1 &v1, const T2 &v2) {AccessKey().Initialize(v1, v2);} template PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3) {AccessKey().Initialize(v1, v2, v3);} template PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) {AccessKey().Initialize(v1, v2, v3, v4);} template PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) {AccessKey().Initialize(v1, v2, v3, v4, v5);} template PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6) {AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} template PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7) {AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} template 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) {AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} template PK_FinalTemplate(T1 &v1, const T2 &v2) {AccessKey().Initialize(v1, v2);} template PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3) {AccessKey().Initialize(v1, v2, v3);} template PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) {AccessKey().Initialize(v1, v2, v3, v4);} template PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) {AccessKey().Initialize(v1, v2, v3, v4, v5);} template PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6) {AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} template PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7) {AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} template 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) {AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} #endif }; //! 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. struct EncryptionStandard {}; //! 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. struct SignatureStandard {}; template class TF_ES; //! Trapdoor Function Based Encryption Scheme template > class TF_ES : public KEYS { typedef typename STANDARD::EncryptionPaddingAlgorithm PaddingAlgorithm; public: //! see EncryptionStandard for a list of standards typedef STANDARD Standard; typedef TF_SchemeOptions SchemeOptions; static std::string StaticAlgorithmName() {return KEYS::StaticAlgorithmName() + "/" + PaddingAlgorithm::StaticAlgorithmName();} //! implements PK_Decryptor interface typedef PK_FinalTemplate > Decryptor; //! implements PK_Encryptor interface typedef PK_FinalTemplate > Encryptor; }; template // VC60 workaround: doesn't work if KEYS is first parameter class TF_SSA; //! Trapdoor Function Based Signature Scheme With Appendix template > // VC60 workaround: doesn't work if KEYS is first parameter class TF_SSA : public KEYS { #ifdef __GNUC__ // GCC3 workaround: can't do this typedef in one line typedef typename STANDARD::SignaturePaddingAlgorithm Type1; typedef typename Type1::type PaddingAlgorithm; typedef typename STANDARD::DecoratedHashingAlgorithm Type2; public: typedef typename Type2::type DecoratedHashAlgorithm; #else // VC60 workaround: using STANDARD directly causes internal compiler error typedef CryptoStandardTraits Traits; typedef typename Traits::SignaturePaddingAlgorithm::type PaddingAlgorithm; public: typedef typename Traits::DecoratedHashingAlgorithm::type DecoratedHashAlgorithm; #endif //! see SignatureStandard for a list of standards typedef STANDARD Standard; typedef TF_SchemeOptions SchemeOptions; static std::string StaticAlgorithmName() {return KEYS::StaticAlgorithmName() + "/" + PaddingAlgorithm::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} //! implements PK_Signer interface typedef PK_FinalTemplate, DecoratedHashAlgorithm> > Signer; //! implements PK_Verifier interface typedef PK_FinalTemplate, DecoratedHashAlgorithm> > Verifier; }; template class DL_SSA; //! Discrete Log Based Signature Scheme With Appendix template > class DL_SSA : public KEYS { typedef DL_SignatureSchemeOptions SchemeOptions; public: static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";} //! implements PK_Signer interface typedef PK_FinalTemplate, H> > Signer; //! implements PK_Verifier interface typedef PK_FinalTemplate, H> > Verifier; }; //! Discrete Log Based Encryption Scheme template class DL_ES : public KEYS { typedef DL_CryptoSchemeOptions SchemeOptions; public: //! implements PK_Decryptor interface typedef PK_FinalTemplate > Decryptor; //! implements PK_Encryptor interface typedef PK_FinalTemplate > Encryptor; }; NAMESPACE_END #endif