diff --git a/stepmania/src/crypto51/pubkey.h b/stepmania/src/crypto51/pubkey.h index ee7ce2a1e0..2d38cba960 100644 --- a/stepmania/src/crypto51/pubkey.h +++ b/stepmania/src/crypto51/pubkey.h @@ -536,973 +536,6 @@ public: // ******************************************************** -// 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 GetValueHelper(this, name, valueType, pValue, &GetAbstractGroupParameters()) - 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 GetValueHelper(this, name, valueType, pValue, &GetAbstractGroupParameters()) - 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); - } -}; - -//! . -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 void 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 Integer RecoverPresignature(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &r, const Integer &s) const - {throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");} - 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_SignatureSchemeBase : public INTERFACE, public DL_Base -{ -public: - unsigned int SignatureLength() const - { - return GetSignatureAlgorithm().RLen(GetAbstractGroupParameters()) - + GetSignatureAlgorithm().SLen(GetAbstractGroupParameters()); - } - unsigned int MaxRecoverableLength() const - {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());} - unsigned int MaxRecoverableLengthFromSignatureLength(unsigned int signatureLength) const - {assert(false); return 0;} // TODO - - bool IsProbabilistic() const - {return true;} - bool AllowNonrecoverablePart() const - {return GetMessageEncodingInterface().AllowNonrecoverablePart();} - bool RecoverablePartFirst() const - {return GetMessageEncodingInterface().RecoverablePartFirst();} - -protected: - unsigned int MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());} - unsigned int MessageRepresentativeBitLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().BitCount();} - - virtual const DL_ElgamalLikeSignatureAlgorithm & GetSignatureAlgorithm() const =0; - virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0; - virtual HashIdentifier GetHashIdentifier() const =0; - virtual unsigned int GetDigestSize() const =0; -}; - -//! . -template -class DL_SignerBase : public DL_SignatureSchemeBase > -{ -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(); - - r = params.ConvertElementToInteger(params.ExponentiateBase(k)); - alg.Sign(params, key.GetPrivateExponent(), k, e, r, s); - } - - void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, unsigned int recoverableMessageLength) const - { - PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); - ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength); - GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(), - recoverableMessage, recoverableMessageLength, - ma.m_presignature, ma.m_presignature.size(), - ma.m_semisignature); - } - - unsigned int SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const - { - GetMaterial().DoQuickSanityCheck(); - - PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); - const DL_ElgamalLikeSignatureAlgorithm &alg = GetSignatureAlgorithm(); - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - const DL_PrivateKey &key = GetKeyInterface(); - - SecByteBlock representative(MessageRepresentativeLength()); - GetMessageEncodingInterface().ComputeMessageRepresentative( - rng, - ma.m_recoverableMessage, ma.m_recoverableMessage.size(), - ma.AccessHash(), GetHashIdentifier(), ma.m_empty, - representative, MessageRepresentativeBitLength()); - ma.m_empty = true; - Integer e(representative, representative.size()); - - Integer r; - if (MaxRecoverableLength() > 0) - r.Decode(ma.m_semisignature, ma.m_semisignature.size()); - else - r.Decode(ma.m_presignature, ma.m_presignature.size()); - Integer s; - alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s); - - unsigned int rLen = alg.RLen(params); - r.Encode(signature, rLen); - s.Encode(signature+rLen, alg.SLen(params)); - - if (restart) - RestartMessageAccumulator(rng, ma); - - return SignatureLength(); - } - -protected: - void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const - { - const DL_ElgamalLikeSignatureAlgorithm &alg = GetSignatureAlgorithm(); - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1); - ma.m_presignature.New(params.GetEncodedElementSize(false)); - params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size()); - } -}; - -//! . -template -class DL_VerifierBase : public DL_SignatureSchemeBase > -{ -public: - void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const - { - PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); - const DL_ElgamalLikeSignatureAlgorithm &alg = GetSignatureAlgorithm(); - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - - unsigned int rLen = alg.RLen(params); - ma.m_semisignature.Assign(signature, rLen); - ma.m_s.Decode(signature+rLen, alg.SLen(params)); - - GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size()); - } - - bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const - { - GetMaterial().DoQuickSanityCheck(); - - PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); - const DL_ElgamalLikeSignatureAlgorithm &alg = GetSignatureAlgorithm(); - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - const DL_PublicKey &key = GetKeyInterface(); - - SecByteBlock representative(MessageRepresentativeLength()); - GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(), - ma.AccessHash(), GetHashIdentifier(), ma.m_empty, - representative, MessageRepresentativeBitLength()); - ma.m_empty = true; - Integer e(representative, representative.size()); - - Integer r(ma.m_semisignature, ma.m_semisignature.size()); - return alg.Verify(params, key, e, r, ma.m_s); - } - - DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const - { - GetMaterial().DoQuickSanityCheck(); - - PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); - const DL_ElgamalLikeSignatureAlgorithm &alg = GetSignatureAlgorithm(); - const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); - const DL_PublicKey &key = GetKeyInterface(); - - SecByteBlock representative(MessageRepresentativeLength()); - GetMessageEncodingInterface().ComputeMessageRepresentative( - NullRNG(), - ma.m_recoverableMessage, ma.m_recoverableMessage.size(), - ma.AccessHash(), GetHashIdentifier(), ma.m_empty, - representative, MessageRepresentativeBitLength()); - ma.m_empty = true; - Integer e(representative, representative.size()); - - ma.m_presignature.New(params.GetEncodedElementSize(false)); - Integer r(ma.m_semisignature, ma.m_semisignature.size()); - alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size()); - - return GetMessageEncodingInterface().RecoverMessageFromSemisignature( - ma.AccessHash(), GetHashIdentifier(), - ma.m_presignature, ma.m_presignature.size(), - ma.m_semisignature, ma.m_semisignature.size(), - recoveredMessage); - } -}; - -//! . -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(RandomNumberGenerator &rng, 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; - typedef T4 MessageEncodingMethod; - typedef T5 HashFunction; -}; - -//! . -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;} - - // for signature scheme - HashIdentifier GetHashIdentifier() const - { - typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::HashIdentifierLookup2 L; - return L::Lookup(); - } - unsigned int GetDigestSize() const - { - typedef CPP_TYPENAME SchemeOptions::HashFunction H; - return H::DIGESTSIZE; - } - -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;} - HashIdentifier GetHashIdentifier() const - {return HashIdentifier();} - const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const - {static typename SCHEME_OPTIONS::MessageEncodingMethod 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_SignerImpl : public DL_PrivateObjectImpl, SCHEME_OPTIONS> -{ - PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng = NullRNG()) const - { - std::auto_ptr p(new PK_MessageAccumulatorImpl); - RestartMessageAccumulator(rng, *p); - return p.release(); - } -}; - -//! . -template -class DL_VerifierImpl : public DL_PublicObjectImpl, SCHEME_OPTIONS> -{ - PK_MessageAccumulator * NewVerificationAccumulator() const - { - return new PK_MessageAccumulatorImpl; - } -}; - -//! . -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 { @@ -1664,37 +697,6 @@ public: typedef PK_FinalTemplate > Verifier; }; -template -class DL_SS; - -//! Discrete Log Based Signature Scheme -template > -class DL_SS : 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 > Signer; - //! implements PK_Verifier interface - typedef PK_FinalTemplate > 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