diff --git a/gfpcrypt.h b/gfpcrypt.h index f21363f5..d159edc3 100644 --- a/gfpcrypt.h +++ b/gfpcrypt.h @@ -1,5 +1,6 @@ // gfpcrypt.h - written and placed in the public domain by Wei Dai -// deterministic signatures added by by Douglas Roark +// RFC6979 deterministic signatures (DL_Algorithm_DSA_RFC6979) added by by Douglas Roark +// ECGDSA (DL_Algorithm_GDSA_ISO15946) added by Jeffrey Walton //! \file gfpcrypt.h //! \brief Classes and functions for schemes based on Discrete Logs (DL) over GF(p) @@ -33,83 +34,83 @@ CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters; //! \brief Integer-based GroupParameters specialization class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial > { - typedef DL_GroupParameters_IntegerBased ThisClass; + typedef DL_GroupParameters_IntegerBased ThisClass; public: - virtual ~DL_GroupParameters_IntegerBased() {} + virtual ~DL_GroupParameters_IntegerBased() {} - //! \brief Initialize a group parameters over integers - //! \param params the group parameters - void Initialize(const DL_GroupParameters_IntegerBased ¶ms) - {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());} + //! \brief Initialize a group parameters over integers + //! \param params the group parameters + void Initialize(const DL_GroupParameters_IntegerBased ¶ms) + {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());} - //! \brief Create a group parameters over integers - //! \param rng a RandomNumberGenerator derived class - //! \param pbits the size of p, in bits - //! \details This function overload of Initialize() creates a new private key because it - //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, - //! then use one of the other Initialize() overloads. - void Initialize(RandomNumberGenerator &rng, unsigned int pbits) - {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));} + //! \brief Create a group parameters over integers + //! \param rng a RandomNumberGenerator derived class + //! \param pbits the size of p, in bits + //! \details This function overload of Initialize() creates a new private key because it + //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + //! then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, unsigned int pbits) + {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));} - //! \brief Initialize a group parameters over integers - //! \param p the modulus - //! \param g the generator - void Initialize(const Integer &p, const Integer &g) - {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);} + //! \brief Initialize a group parameters over integers + //! \param p the modulus + //! \param g the generator + void Initialize(const Integer &p, const Integer &g) + {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);} - //! \brief Initialize a group parameters over integers - //! \param p the modulus - //! \param q the subgroup order - //! \param g the generator - void Initialize(const Integer &p, const Integer &q, const Integer &g) - {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);} + //! \brief Initialize a group parameters over integers + //! \param p the modulus + //! \param q the subgroup order + //! \param g the generator + void Initialize(const Integer &p, const Integer &q, const Integer &g) + {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);} - // ASN1Object interface - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; + // ASN1Object interface + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; - // GeneratibleCryptoMaterial interface - /*! parameters: (ModulusSize, SubgroupOrderSize (optional)) */ - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); + // GeneratibleCryptoMaterial interface + /*! parameters: (ModulusSize, SubgroupOrderSize (optional)) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); - // DL_GroupParameters - const Integer & GetSubgroupOrder() const {return m_q;} - Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();} - bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; - bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation *precomp) const; - bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;} + // DL_GroupParameters + const Integer & GetSubgroupOrder() const {return m_q;} + Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();} + bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; + bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation *precomp) const; + bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;} - // Cygwin i386 crash at -O3; see http://github.com/weidai11/cryptopp/issues/40. - void EncodeElement(bool reversible, const Element &element, byte *encoded) const; - unsigned int GetEncodedElementSize(bool reversible) const; + // Cygwin i386 crash at -O3; see http://github.com/weidai11/cryptopp/issues/40. + void EncodeElement(bool reversible, const Element &element, byte *encoded) const; + unsigned int GetEncodedElementSize(bool reversible) const; - Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const; - Integer ConvertElementToInteger(const Element &element) const - {return element;} - Integer GetMaxExponent() const; - static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";} + Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const; + Integer ConvertElementToInteger(const Element &element) const + {return element;} + Integer GetMaxExponent() const; + static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";} - OID GetAlgorithmID() const; + OID GetAlgorithmID() const; - virtual const Integer & GetModulus() const =0; - virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0; + virtual const Integer & GetModulus() const =0; + virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0; - void SetSubgroupOrder(const Integer &q) - {m_q = q; ParametersChanged();} + void SetSubgroupOrder(const Integer &q) + {m_q = q; ParametersChanged();} protected: - Integer ComputeGroupOrder(const Integer &modulus) const - {return modulus-(GetFieldType() == 1 ? 1 : -1);} + Integer ComputeGroupOrder(const Integer &modulus) const + {return modulus-(GetFieldType() == 1 ? 1 : -1);} - // GF(p) = 1, GF(p^2) = 2 - virtual int GetFieldType() const =0; - virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const; + // GF(p) = 1, GF(p^2) = 2 + virtual int GetFieldType() const =0; + virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const; private: - Integer m_q; + Integer m_q; }; //! \class DL_GroupParameters_IntegerBasedImpl @@ -119,36 +120,36 @@ private: template > class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl { - typedef DL_GroupParameters_IntegerBasedImpl ThisClass; + typedef DL_GroupParameters_IntegerBasedImpl ThisClass; public: - typedef typename GROUP_PRECOMP::Element Element; + typedef typename GROUP_PRECOMP::Element Element; - virtual ~DL_GroupParameters_IntegerBasedImpl() {} + virtual ~DL_GroupParameters_IntegerBasedImpl() {} - // GeneratibleCryptoMaterial interface - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const - {return GetValueHelper(this, name, valueType, pValue).Assignable();} + // GeneratibleCryptoMaterial interface + 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 AssignFrom(const NameValuePairs &source) + {AssignFromHelper(this, source);} - // DL_GroupParameters - const DL_FixedBasePrecomputation & GetBasePrecomputation() const {return this->m_gpc;} - DL_FixedBasePrecomputation & AccessBasePrecomputation() {return this->m_gpc;} + // DL_GroupParameters + const DL_FixedBasePrecomputation & GetBasePrecomputation() const {return this->m_gpc;} + DL_FixedBasePrecomputation & AccessBasePrecomputation() {return this->m_gpc;} - // IntegerGroupParameters - const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();} + // IntegerGroupParameters + const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();} const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());} - void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together - {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();} + void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together + {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();} - // non-inherited - bool operator==(const DL_GroupParameters_IntegerBasedImpl &rhs) const - {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();} - bool operator!=(const DL_GroupParameters_IntegerBasedImpl &rhs) const - {return !operator==(rhs);} + // non-inherited + bool operator==(const DL_GroupParameters_IntegerBasedImpl &rhs) const + {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();} + bool operator!=(const DL_GroupParameters_IntegerBasedImpl &rhs) const + {return !operator==(rhs);} }; CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_IntegerBasedImpl; @@ -158,24 +159,24 @@ CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_IntegerBasedImpl { public: - virtual ~DL_GroupParameters_GFP() {} + virtual ~DL_GroupParameters_GFP() {} - // DL_GroupParameters - bool IsIdentity(const Integer &element) const {return element == Integer::One();} - void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + // DL_GroupParameters + bool IsIdentity(const Integer &element) const {return element == Integer::One();} + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; - // NameValuePairs interface - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const - { - return GetValueHelper(this, name, valueType, pValue).Assignable(); - } + // NameValuePairs interface + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue).Assignable(); + } - // used by MQV - Element MultiplyElements(const Element &a, const Element &b) const; - Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; + // used by MQV + Element MultiplyElements(const Element &a, const Element &b) const; + Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; protected: - int GetFieldType() const {return 1;} + int GetFieldType() const {return 1;} }; //! \class DL_GroupParameters_GFP @@ -183,12 +184,12 @@ protected: class CRYPTOPP_DLL DL_GroupParameters_GFP_DefaultSafePrime : public DL_GroupParameters_GFP { public: - typedef NoCofactorMultiplication DefaultCofactorOption; + typedef NoCofactorMultiplication DefaultCofactorOption; - virtual ~DL_GroupParameters_GFP_DefaultSafePrime() {} + virtual ~DL_GroupParameters_GFP_DefaultSafePrime() {} protected: - unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;} + unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;} }; //! \class DL_Algorithm_GDSA @@ -198,31 +199,31 @@ template class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm { public: - CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";} + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";} - virtual ~DL_Algorithm_GDSA() {} + virtual ~DL_Algorithm_GDSA() {} - void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const - { - const Integer &q = params.GetSubgroupOrder(); - r %= q; - Integer kInv = k.InverseMod(q); - s = (kInv * (x*r + e)) % q; - CRYPTOPP_ASSERT(!!r && !!s); - } + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + r %= q; + Integer kInv = k.InverseMod(q); + s = (kInv * (x*r + e)) % q; + CRYPTOPP_ASSERT(!!r && !!s); + } - bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const - { - const Integer &q = params.GetSubgroupOrder(); - if (r>=q || r<1 || s>=q || s<1) - return false; + bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + if (r>=q || r<1 || s>=q || s<1) + return false; - Integer w = s.InverseMod(q); - Integer u1 = (e * w) % q; - Integer u2 = (r * w) % q; - // verify r == (g^u1 * y^u2 mod p) mod q - return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q; - } + Integer w = s.InverseMod(q); + Integer u1 = (e * w) % q; + Integer u2 = (r * w) % q; + // verify r == (g^u1 * y^u2 mod p) mod q + return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q; + } }; //! \class DL_Algorithm_DSA_RFC6979 @@ -236,198 +237,201 @@ template class DL_Algorithm_DSA_RFC6979 : public DL_Algorithm_GDSA, public DeterministicSignatureAlgorithm { public: - CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-RFC6979";} + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-RFC6979";} - virtual ~DL_Algorithm_DSA_RFC6979() {} + virtual ~DL_Algorithm_DSA_RFC6979() {} - bool IsProbabilistic() const - {return false;} - bool IsDeterministic() const - {return true;} + bool IsProbabilistic() const + {return false;} + bool IsDeterministic() const + {return true;} - // Deterministic K - Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const - { - static const byte zero = 0, one = 1; - const size_t qlen = q.BitCount(); - const size_t rlen = BitsToBytes(qlen); + // Deterministic K + Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const + { + static const byte zero = 0, one = 1; + const size_t qlen = q.BitCount(); + const size_t rlen = BitsToBytes(qlen); - // Step (a) - formatted E(m) - SecByteBlock BH(e.MinEncodedSize()); - e.Encode(BH, BH.size()); - BH = bits2octets(BH, q); + // Step (a) - formatted E(m) + SecByteBlock BH(e.MinEncodedSize()); + e.Encode(BH, BH.size()); + BH = bits2octets(BH, q); - // Step (a) - private key to byte array - SecByteBlock BX(STDMAX(rlen, x.MinEncodedSize())); - x.Encode(BX, BX.size()); + // Step (a) - private key to byte array + SecByteBlock BX(STDMAX(rlen, x.MinEncodedSize())); + x.Encode(BX, BX.size()); - // Step (b) - SecByteBlock V(H::DIGESTSIZE); - std::fill(V.begin(), V.begin()+H::DIGESTSIZE, one); + // Step (b) + SecByteBlock V(H::DIGESTSIZE); + std::fill(V.begin(), V.begin()+H::DIGESTSIZE, one); - // Step (c) - SecByteBlock K(H::DIGESTSIZE); - std::fill(K.begin(), K.begin()+H::DIGESTSIZE, zero); + // Step (c) + SecByteBlock K(H::DIGESTSIZE); + std::fill(K.begin(), K.begin()+H::DIGESTSIZE, zero); - // Step (d) - m_hmac.SetKey(K, K.size()); - m_hmac.Update(V, V.size()); - m_hmac.Update(&zero, 1); - m_hmac.Update(BX, BX.size()); - m_hmac.Update(BH, BH.size()); - m_hmac.TruncatedFinal(K, K.size()); + // Step (d) + m_hmac.SetKey(K, K.size()); + m_hmac.Update(V, V.size()); + m_hmac.Update(&zero, 1); + m_hmac.Update(BX, BX.size()); + m_hmac.Update(BH, BH.size()); + m_hmac.TruncatedFinal(K, K.size()); - // Step (e) - m_hmac.SetKey(K, K.size()); - m_hmac.Update(V, V.size()); - m_hmac.TruncatedFinal(V, V.size()); + // Step (e) + m_hmac.SetKey(K, K.size()); + m_hmac.Update(V, V.size()); + m_hmac.TruncatedFinal(V, V.size()); - // Step (f) - m_hmac.SetKey(K, K.size()); - m_hmac.Update(V, V.size()); - m_hmac.Update(&one, 1); - m_hmac.Update(BX, BX.size()); - m_hmac.Update(BH, BH.size()); - m_hmac.TruncatedFinal(K, K.size()); + // Step (f) + m_hmac.SetKey(K, K.size()); + m_hmac.Update(V, V.size()); + m_hmac.Update(&one, 1); + m_hmac.Update(BX, BX.size()); + m_hmac.Update(BH, BH.size()); + m_hmac.TruncatedFinal(K, K.size()); - // Step (g) - m_hmac.SetKey(K, K.size()); - m_hmac.Update(V, V.size()); - m_hmac.TruncatedFinal(V, V.size()); + // Step (g) + m_hmac.SetKey(K, K.size()); + m_hmac.Update(V, V.size()); + m_hmac.TruncatedFinal(V, V.size()); - Integer k; - SecByteBlock temp(rlen); - for (;;) - { - // We want qlen bits, but we support only hash functions with an output length - // multiple of 8; hence, we will gather rlen bits, i.e., rolen octets. - size_t toff = 0; - while (toff < rlen) - { - m_hmac.Update(V, V.size()); - m_hmac.TruncatedFinal(V, V.size()); + Integer k; + SecByteBlock temp(rlen); + for (;;) + { + // We want qlen bits, but we support only hash functions with an output length + // multiple of 8; hence, we will gather rlen bits, i.e., rolen octets. + size_t toff = 0; + while (toff < rlen) + { + m_hmac.Update(V, V.size()); + m_hmac.TruncatedFinal(V, V.size()); - size_t cc = STDMIN(V.size(), temp.size() - toff); - memcpy_s(temp+toff, temp.size() - toff, V, cc); - toff += cc; - } + size_t cc = STDMIN(V.size(), temp.size() - toff); + memcpy_s(temp+toff, temp.size() - toff, V, cc); + toff += cc; + } - k = bits2int(temp, qlen); - if (k > 0 && k < q) - break; + k = bits2int(temp, qlen); + if (k > 0 && k < q) + break; - // k is not in the proper range; update K and V, and loop. - m_hmac.Update(V, V.size()); - m_hmac.Update(&zero, 1); - m_hmac.TruncatedFinal(K, K.size()); + // k is not in the proper range; update K and V, and loop. + m_hmac.Update(V, V.size()); + m_hmac.Update(&zero, 1); + m_hmac.TruncatedFinal(K, K.size()); - m_hmac.SetKey(K, K.size()); - m_hmac.Update(V, V.size()); - m_hmac.TruncatedFinal(V, V.size()); - } + m_hmac.SetKey(K, K.size()); + m_hmac.Update(V, V.size()); + m_hmac.TruncatedFinal(V, V.size()); + } - return k; - } + return k; + } protected: #if 0 - // Determine bits without converting to an Integer - inline unsigned int BitCount(const byte* buffer, size_t size) const - { - unsigned int idx = 0; - while (idx < size && buffer[idx] == 0) { idx++; } - return (size-idx)*8 - (8-BitPrecision(buffer[idx])); - } + // Determine bits without converting to an Integer + inline unsigned int BitCount(const byte* buffer, size_t size) const + { + unsigned int idx = 0; + while (idx < size && buffer[idx] == 0) { idx++; } + return (size-idx)*8 - (8-BitPrecision(buffer[idx])); + } #endif - Integer bits2int(const SecByteBlock& bits, size_t qlen) const - { - Integer ret(bits, bits.size()); - size_t blen = bits.size()*8; + Integer bits2int(const SecByteBlock& bits, size_t qlen) const + { + Integer ret(bits, bits.size()); + size_t blen = bits.size()*8; - if (blen > qlen) - ret >>= blen - qlen; + if (blen > qlen) + ret >>= blen - qlen; - return ret; - } + return ret; + } - // RFC 6979 support function. Takes an integer and converts it into bytes that - // are the same length as an elliptic curve's order. - SecByteBlock int2octets(const Integer& val, size_t rlen) const - { - SecByteBlock block(val.MinEncodedSize()); - val.Encode(block, val.MinEncodedSize()); + // RFC 6979 support function. Takes an integer and converts it into bytes that + // are the same length as an elliptic curve's order. + SecByteBlock int2octets(const Integer& val, size_t rlen) const + { + SecByteBlock block(val.MinEncodedSize()); + val.Encode(block, val.MinEncodedSize()); - if (block.size() == rlen) - return block; + if (block.size() == rlen) + return block; - // The least significant bytes are the ones we need to preserve. - SecByteBlock t(rlen); - if (block.size() > rlen) - { - size_t offset = block.size() - rlen; - memcpy(t, block + offset, rlen); - } - else // block.size() < rlen - { - size_t offset = rlen - block.size(); - memset(t, '\x00', offset); - memcpy(t + offset, block, rlen - offset); - } + // The least significant bytes are the ones we need to preserve. + SecByteBlock t(rlen); + if (block.size() > rlen) + { + size_t offset = block.size() - rlen; + memcpy(t, block + offset, rlen); + } + else // block.size() < rlen + { + size_t offset = rlen - block.size(); + memset(t, '\x00', offset); + memcpy(t + offset, block, rlen - offset); + } - return t; - } + return t; + } - // Turn a stream of bits into a set of bytes with the same length as an elliptic - // curve's order. - SecByteBlock bits2octets(const SecByteBlock& in, const Integer& q) const - { - Integer b2 = bits2int(in, in.size()*8); - Integer b1 = b2 - q; - return int2octets(b1.IsNegative() ? b2 : b1, q.ByteCount()); - } + // Turn a stream of bits into a set of bytes with the same length as an elliptic + // curve's order. + SecByteBlock bits2octets(const SecByteBlock& in, const Integer& q) const + { + Integer b2 = bits2int(in, in.size()*8); + Integer b1 = b2 - q; + return int2octets(b1.IsNegative() ? b2 : b1, q.ByteCount()); + } private: - mutable H m_hash; - mutable HMAC m_hmac; + mutable H m_hash; + mutable HMAC m_hmac; }; //! \class DL_Algorithm_GDSA_ISO15946 //! \brief German Digital Signature Algorithm //! \tparam T FieldElement type or class -//! \sa Erwin Hess, Marcus Schafheutle, and Pascale Serf The -//! Digital Signature Scheme ECGDSA (October 24, 2006) +//! \details The Digital Signature Scheme ECGDSA does not define the algorithm over integers. Rather, the +//! signature algorithm is only defined over elliptic curves. However, The library design is such that the +//! generic algorithm reside in \header gfpcrypt.h. +//! \sa Erwin Hess, Marcus Schafheutle, and Pascale Serf +//! The Digital Signature Scheme ECGDSA (October 24, 2006) template class DL_Algorithm_GDSA_ISO15946 : public DL_ElgamalLikeSignatureAlgorithm { public: - CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "GDSA-ISO15946";} + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "GDSA-ISO15946";} - virtual ~DL_Algorithm_GDSA_ISO15946() {} + virtual ~DL_Algorithm_GDSA_ISO15946() {} - void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const - { - const Integer &q = params.GetSubgroupOrder(); - // r = x(k * G) mod q - r = params.ConvertElementToInteger(params.ExponentiateBase(k)) % q; - // s = (k * r − h(m)) * d_A mod q - s = (k * r - e) * x % q; - CRYPTOPP_ASSERT(!!r && !!s); - } + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + // r = x(k * G) mod q + r = params.ConvertElementToInteger(params.ExponentiateBase(k)) % q; + // s = (k * r − h(m)) * d_A mod q + s = (k * r - e) * x % q; + CRYPTOPP_ASSERT(!!r && !!s); + } - bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const - { - const Integer &q = params.GetSubgroupOrder(); - if (r>=q || r<1 || s>=q || s<1) - return false; + bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + if (r>=q || r<1 || s>=q || s<1) + return false; - const Integer& rInv = r.InverseMod(q); - Integer u1 = (rInv * e) % q; - Integer u2 = (rInv * s) % q; - // verify x(G^u1 + P_A^u2) mod q - return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q; - } + const Integer& rInv = r.InverseMod(q); + const Integer u1 = (rInv * e) % q; + const Integer u2 = (rInv * s) % q; + // verify x(G^u1 + P_A^u2) mod q + return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q; + } }; CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA; @@ -444,65 +448,65 @@ template class DL_Algorithm_NR : public DL_ElgamalLikeSignatureAlgorithm { public: - CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "NR";} + CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "NR";} - virtual ~DL_Algorithm_NR() {} + virtual ~DL_Algorithm_NR() {} - void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const - { - const Integer &q = params.GetSubgroupOrder(); - r = (r + e) % q; - s = (k - x*r) % q; - CRYPTOPP_ASSERT(!!r); - } + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + r = (r + e) % q; + s = (k - x*r) % q; + CRYPTOPP_ASSERT(!!r); + } - bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const - { - const Integer &q = params.GetSubgroupOrder(); - if (r>=q || r<1 || s>=q) - return false; + bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + if (r>=q || r<1 || s>=q) + return false; - // check r == (m_g^s * m_y^r + m) mod m_q - return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q; - } + // check r == (m_g^s * m_y^r + m) mod m_q + return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q; + } }; //! \class DL_PublicKey_GFP //! \brief Discrete Log (DL) public key in GF(p) groups //! \tparam GP GroupParameters derived class -//! \details DSA public key format is defined in 7.3.3 of RFC 2459. The private key format is defined in 12.9 of PKCS #11 v2.10. +//! \details DSA public key format is defined in 7.3.3 of RFC 2459. The private key format is defined in 12.9 of PKCS #11 v2.10. template class DL_PublicKey_GFP : public DL_PublicKeyImpl { public: - virtual ~DL_PublicKey_GFP() {} + virtual ~DL_PublicKey_GFP() {} - //! \brief Initialize a public key over GF(p) - //! \param params the group parameters - //! \param y the public element - void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &y) - {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);} + //! \brief Initialize a public key over GF(p) + //! \param params the group parameters + //! \param y the public element + void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &y) + {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);} - //! \brief Initialize a public key over GF(p) - //! \param p the modulus - //! \param g the generator - //! \param y the public element - void Initialize(const Integer &p, const Integer &g, const Integer &y) - {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);} + //! \brief Initialize a public key over GF(p) + //! \param p the modulus + //! \param g the generator + //! \param y the public element + void Initialize(const Integer &p, const Integer &g, const Integer &y) + {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);} - //! \brief Initialize a public key over GF(p) - //! \param p the modulus - //! \param q the subgroup order - //! \param g the generator - //! \param y the public element - void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y) - {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);} + //! \brief Initialize a public key over GF(p) + //! \param p the modulus + //! \param q the subgroup order + //! \param g the generator + //! \param y the public element + void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y) + {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);} - // X509PublicKey - void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t) - {this->SetPublicElement(Integer(bt));} - void DEREncodePublicKey(BufferedTransformation &bt) const - {this->GetPublicElement().DEREncode(bt);} + // X509PublicKey + void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t) + {this->SetPublicElement(Integer(bt));} + void DEREncodePublicKey(BufferedTransformation &bt) const + {this->GetPublicElement().DEREncode(bt);} }; //! \class DL_PrivateKey_GFP @@ -512,76 +516,76 @@ template class DL_PrivateKey_GFP : public DL_PrivateKeyImpl { public: - virtual ~DL_PrivateKey_GFP() {} + virtual ~DL_PrivateKey_GFP() {} - //! \brief Create a private key - //! \param rng a RandomNumberGenerator derived class - //! \param modulusBits the size of the modulus, in bits - //! \details This function overload of Initialize() creates a new private key because it - //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, - //! then use one of the other Initialize() overloads. - void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) - {this->GenerateRandomWithKeySize(rng, modulusBits);} + //! \brief Create a private key + //! \param rng a RandomNumberGenerator derived class + //! \param modulusBits the size of the modulus, in bits + //! \details This function overload of Initialize() creates a new private key because it + //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + //! then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) + {this->GenerateRandomWithKeySize(rng, modulusBits);} - //! \brief Create a private key - //! \param rng a RandomNumberGenerator derived class - //! \param p the modulus - //! \param g the generator - //! \details This function overload of Initialize() creates a new private key because it - //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, - //! then use one of the other Initialize() overloads. - void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g) - {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));} + //! \brief Create a private key + //! \param rng a RandomNumberGenerator derived class + //! \param p the modulus + //! \param g the generator + //! \details This function overload of Initialize() creates a new private key because it + //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + //! then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g) + {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));} - //! \brief Create a private key - //! \param rng a RandomNumberGenerator derived class - //! \param p the modulus - //! \param q the subgroup order - //! \param g the generator - //! \details This function overload of Initialize() creates a new private key because it - //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, - //! then use one of the other Initialize() overloads. - void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g) - {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));} + //! \brief Create a private key + //! \param rng a RandomNumberGenerator derived class + //! \param p the modulus + //! \param q the subgroup order + //! \param g the generator + //! \details This function overload of Initialize() creates a new private key because it + //! takes a RandomNumberGenerator() as a parameter. If you have an existing keypair, + //! then use one of the other Initialize() overloads. + void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g) + {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));} - //! \brief Initialize a private key over GF(p) - //! \param params the group parameters - //! \param x the private exponent - void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &x) - {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);} + //! \brief Initialize a private key over GF(p) + //! \param params the group parameters + //! \param x the private exponent + void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &x) + {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);} - //! \brief Initialize a private key over GF(p) - //! \param p the modulus - //! \param g the generator - //! \param x the private exponent - void Initialize(const Integer &p, const Integer &g, const Integer &x) - {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);} + //! \brief Initialize a private key over GF(p) + //! \param p the modulus + //! \param g the generator + //! \param x the private exponent + void Initialize(const Integer &p, const Integer &g, const Integer &x) + {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);} - //! \brief Initialize a private key over GF(p) - //! \param p the modulus - //! \param q the subgroup order - //! \param g the generator - //! \param x the private exponent - void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x) - {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);} + //! \brief Initialize a private key over GF(p) + //! \param p the modulus + //! \param q the subgroup order + //! \param g the generator + //! \param x the private exponent + void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x) + {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);} }; //! \class DL_SignatureKeys_GFP //! \brief Discrete Log (DL) signing/verification keys in GF(p) groups struct DL_SignatureKeys_GFP { - typedef DL_GroupParameters_GFP GroupParameters; - typedef DL_PublicKey_GFP PublicKey; - typedef DL_PrivateKey_GFP PrivateKey; + typedef DL_GroupParameters_GFP GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; }; //! \class DL_CryptoKeys_GFP //! \brief Discrete Log (DL) encryption/decryption keys in GF(p) groups struct DL_CryptoKeys_GFP { - typedef DL_GroupParameters_GFP_DefaultSafePrime GroupParameters; - typedef DL_PublicKey_GFP PublicKey; - typedef DL_PrivateKey_GFP PrivateKey; + typedef DL_GroupParameters_GFP_DefaultSafePrime GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; }; //! \class DL_PublicKey_GFP_OldFormat @@ -593,40 +597,40 @@ template class DL_PublicKey_GFP_OldFormat : public BASE { public: - virtual ~DL_PublicKey_GFP_OldFormat() {} + virtual ~DL_PublicKey_GFP_OldFormat() {} - void BERDecode(BufferedTransformation &bt) - { - BERSequenceDecoder seq(bt); - Integer v1(seq); - Integer v2(seq); - Integer v3(seq); + void BERDecode(BufferedTransformation &bt) + { + BERSequenceDecoder seq(bt); + Integer v1(seq); + Integer v2(seq); + Integer v3(seq); - if (seq.EndReached()) - { - this->AccessGroupParameters().Initialize(v1, v1/2, v2); - this->SetPublicElement(v3); - } - else - { - Integer v4(seq); - this->AccessGroupParameters().Initialize(v1, v2, v3); - this->SetPublicElement(v4); - } + if (seq.EndReached()) + { + this->AccessGroupParameters().Initialize(v1, v1/2, v2); + this->SetPublicElement(v3); + } + else + { + Integer v4(seq); + this->AccessGroupParameters().Initialize(v1, v2, v3); + this->SetPublicElement(v4); + } - seq.MessageEnd(); - } + seq.MessageEnd(); + } - void DEREncode(BufferedTransformation &bt) const - { - DERSequenceEncoder seq(bt); - this->GetGroupParameters().GetModulus().DEREncode(seq); - if (this->GetGroupParameters().GetCofactor() != 2) - this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq); - this->GetGroupParameters().GetGenerator().DEREncode(seq); - this->GetPublicElement().DEREncode(seq); - seq.MessageEnd(); - } + void DEREncode(BufferedTransformation &bt) const + { + DERSequenceEncoder seq(bt); + this->GetGroupParameters().GetModulus().DEREncode(seq); + if (this->GetGroupParameters().GetCofactor() != 2) + this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq); + this->GetGroupParameters().GetGenerator().DEREncode(seq); + this->GetPublicElement().DEREncode(seq); + seq.MessageEnd(); + } }; //! \class DL_PrivateKey_GFP_OldFormat @@ -638,42 +642,42 @@ template class DL_PrivateKey_GFP_OldFormat : public BASE { public: - virtual ~DL_PrivateKey_GFP_OldFormat() {} + virtual ~DL_PrivateKey_GFP_OldFormat() {} - void BERDecode(BufferedTransformation &bt) - { - BERSequenceDecoder seq(bt); - Integer v1(seq); - Integer v2(seq); - Integer v3(seq); - Integer v4(seq); + void BERDecode(BufferedTransformation &bt) + { + BERSequenceDecoder seq(bt); + Integer v1(seq); + Integer v2(seq); + Integer v3(seq); + Integer v4(seq); - if (seq.EndReached()) - { - this->AccessGroupParameters().Initialize(v1, v1/2, v2); - this->SetPrivateExponent(v4 % (v1/2)); // some old keys may have x >= q - } - else - { - Integer v5(seq); - this->AccessGroupParameters().Initialize(v1, v2, v3); - this->SetPrivateExponent(v5); - } + if (seq.EndReached()) + { + this->AccessGroupParameters().Initialize(v1, v1/2, v2); + this->SetPrivateExponent(v4 % (v1/2)); // some old keys may have x >= q + } + else + { + Integer v5(seq); + this->AccessGroupParameters().Initialize(v1, v2, v3); + this->SetPrivateExponent(v5); + } - seq.MessageEnd(); - } + seq.MessageEnd(); + } - void DEREncode(BufferedTransformation &bt) const - { - DERSequenceEncoder seq(bt); - this->GetGroupParameters().GetModulus().DEREncode(seq); - if (this->GetGroupParameters().GetCofactor() != 2) - this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq); - this->GetGroupParameters().GetGenerator().DEREncode(seq); - this->GetGroupParameters().ExponentiateBase(this->GetPrivateExponent()).DEREncode(seq); - this->GetPrivateExponent().DEREncode(seq); - seq.MessageEnd(); - } + void DEREncode(BufferedTransformation &bt) const + { + DERSequenceEncoder seq(bt); + this->GetGroupParameters().GetModulus().DEREncode(seq); + if (this->GetGroupParameters().GetCofactor() != 2) + this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq); + this->GetGroupParameters().GetGenerator().DEREncode(seq); + this->GetGroupParameters().ExponentiateBase(this->GetPrivateExponent()).DEREncode(seq); + this->GetPrivateExponent().DEREncode(seq); + seq.MessageEnd(); + } }; //! \class GDSA @@ -683,10 +687,10 @@ public: //! \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2 template struct GDSA : public DL_SS< - DL_SignatureKeys_GFP, - DL_Algorithm_GDSA, - DL_SignatureMessageEncodingMethod_DSA, - H> + DL_SignatureKeys_GFP, + DL_Algorithm_GDSA, + DL_SignatureMessageEncodingMethod_DSA, + H> { }; @@ -696,10 +700,10 @@ struct GDSA : public DL_SS< //! \sa NR template struct NR : public DL_SS< - DL_SignatureKeys_GFP, - DL_Algorithm_NR, - DL_SignatureMessageEncodingMethod_NR, - H> + DL_SignatureKeys_GFP, + DL_Algorithm_NR, + DL_SignatureMessageEncodingMethod_NR, + H> { }; @@ -710,18 +714,18 @@ struct NR : public DL_SS< class CRYPTOPP_DLL DL_GroupParameters_DSA : public DL_GroupParameters_GFP { public: - virtual ~DL_GroupParameters_DSA() {} + virtual ~DL_GroupParameters_DSA() {} - /*! also checks that the lengths of p and q are allowed by the DSA standard */ - bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; - /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */ - /*! ModulusSize must be between DSA::MIN_PRIME_LENGTH and DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE */ - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + /*! also checks that the lengths of p and q are allowed by the DSA standard */ + bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; + /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */ + /*! ModulusSize must be between DSA::MIN_PRIME_LENGTH and DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); - static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits) - {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} + static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits) + {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} - enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024}; + enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024}; }; template @@ -732,8 +736,8 @@ class DSA2; //! \sa DL_GroupParameters_DSA struct DL_Keys_DSA { - typedef DL_PublicKey_GFP PublicKey; - typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA2 > PrivateKey; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA2 > PrivateKey; }; //! \class DSA2 @@ -744,14 +748,14 @@ struct DL_Keys_DSA //! \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2 template class DSA2 : public DL_SS< - DL_Keys_DSA, - DL_Algorithm_GDSA, - DL_SignatureMessageEncodingMethod_DSA, - H, - DSA2 > + DL_Keys_DSA, + DL_Algorithm_GDSA, + DL_SignatureMessageEncodingMethod_DSA, + H, + DSA2 > { public: - static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();} + static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();} }; //! \class DSA_RFC6979 @@ -761,13 +765,13 @@ public: //! \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2 template struct DSA_RFC6979 : public DL_SS< - DL_SignatureKeys_GFP, - DL_Algorithm_DSA_RFC6979, - DL_SignatureMessageEncodingMethod_DSA, - H, - DSA_RFC6979 > + DL_SignatureKeys_GFP, + DL_Algorithm_DSA_RFC6979, + DL_SignatureMessageEncodingMethod_DSA, + H, + DSA_RFC6979 > { - static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("DSA-RFC6979/") + H::StaticAlgorithmName();} + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("DSA-RFC6979/") + H::StaticAlgorithmName();} }; //! DSA with SHA-1, typedef'd for backwards compatibility @@ -795,82 +799,82 @@ template class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm { public: - virtual ~DL_EncryptionAlgorithm_Xor() {} + virtual ~DL_EncryptionAlgorithm_Xor() {} - bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} - size_t GetSymmetricKeyLength(size_t plaintextLength) const - {return plaintextLength + static_cast(MAC::DIGESTSIZE);} - size_t GetSymmetricCiphertextLength(size_t plaintextLength) const - {return plaintextLength + static_cast(MAC::DIGESTSIZE);} - size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const - {return SaturatingSubtract(ciphertextLength, static_cast(MAC::DIGESTSIZE));} - void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const - { - CRYPTOPP_UNUSED(rng); - const byte *cipherKey = NULL, *macKey = NULL; - if (DHAES_MODE) - { - macKey = key; - cipherKey = key + MAC::DEFAULT_KEYLENGTH; - } - else - { - cipherKey = key; - macKey = key + plaintextLength; - } + bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} + size_t GetSymmetricKeyLength(size_t plaintextLength) const + {return plaintextLength + static_cast(MAC::DIGESTSIZE);} + size_t GetSymmetricCiphertextLength(size_t plaintextLength) const + {return plaintextLength + static_cast(MAC::DIGESTSIZE);} + size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const + {return SaturatingSubtract(ciphertextLength, static_cast(MAC::DIGESTSIZE));} + void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const + { + CRYPTOPP_UNUSED(rng); + const byte *cipherKey = NULL, *macKey = NULL; + if (DHAES_MODE) + { + macKey = key; + cipherKey = key + MAC::DEFAULT_KEYLENGTH; + } + else + { + cipherKey = key; + macKey = key + plaintextLength; + } - ConstByteArrayParameter encodingParameters; - parameters.GetValue(Name::EncodingParameters(), encodingParameters); + ConstByteArrayParameter encodingParameters; + parameters.GetValue(Name::EncodingParameters(), encodingParameters); - if (plaintextLength) // Coverity finding - xorbuf(ciphertext, plaintext, cipherKey, plaintextLength); + if (plaintextLength) // Coverity finding + xorbuf(ciphertext, plaintext, cipherKey, plaintextLength); - MAC mac(macKey); - mac.Update(ciphertext, plaintextLength); - mac.Update(encodingParameters.begin(), encodingParameters.size()); - if (DHAES_MODE) - { - byte L[8]; - PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size()))); - mac.Update(L, 8); - } - mac.Final(ciphertext + plaintextLength); - } - DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const - { - size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength); - const byte *cipherKey, *macKey; - if (DHAES_MODE) - { - macKey = key; - cipherKey = key + MAC::DEFAULT_KEYLENGTH; - } - else - { - cipherKey = key; - macKey = key + plaintextLength; - } + MAC mac(macKey); + mac.Update(ciphertext, plaintextLength); + mac.Update(encodingParameters.begin(), encodingParameters.size()); + if (DHAES_MODE) + { + byte L[8]; + PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size()))); + mac.Update(L, 8); + } + mac.Final(ciphertext + plaintextLength); + } + DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const + { + size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength); + const byte *cipherKey, *macKey; + if (DHAES_MODE) + { + macKey = key; + cipherKey = key + MAC::DEFAULT_KEYLENGTH; + } + else + { + cipherKey = key; + macKey = key + plaintextLength; + } - ConstByteArrayParameter encodingParameters; - parameters.GetValue(Name::EncodingParameters(), encodingParameters); + ConstByteArrayParameter encodingParameters; + parameters.GetValue(Name::EncodingParameters(), encodingParameters); - MAC mac(macKey); - mac.Update(ciphertext, plaintextLength); - mac.Update(encodingParameters.begin(), encodingParameters.size()); - if (DHAES_MODE) - { - byte L[8]; - PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size()))); - mac.Update(L, 8); - } - if (!mac.Verify(ciphertext + plaintextLength)) - return DecodingResult(); + MAC mac(macKey); + mac.Update(ciphertext, plaintextLength); + mac.Update(encodingParameters.begin(), encodingParameters.size()); + if (DHAES_MODE) + { + byte L[8]; + PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size()))); + mac.Update(L, 8); + } + if (!mac.Verify(ciphertext + plaintextLength)) + return DecodingResult(); - if (plaintextLength) // Coverity finding - xorbuf(plaintext, ciphertext, cipherKey, plaintextLength); + if (plaintextLength) // Coverity finding + xorbuf(plaintext, ciphertext, cipherKey, plaintextLength); - return DecodingResult(plaintextLength); - } + return DecodingResult(plaintextLength); + } }; //! _ @@ -878,28 +882,28 @@ template class DL_KeyDerivationAlgorithm_P1363 : public DL_KeyDerivationAlgorithm { public: - virtual ~DL_KeyDerivationAlgorithm_P1363() {} + virtual ~DL_KeyDerivationAlgorithm_P1363() {} - bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;} - void Derive(const DL_GroupParameters ¶ms, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs ¶meters) const - { - SecByteBlock agreedSecret; - if (DHAES_MODE) - { - agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false)); - params.EncodeElement(true, ephemeralPublicKey, agreedSecret); - params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true)); - } - else - { - agreedSecret.New(params.GetEncodedElementSize(false)); - params.EncodeElement(false, agreedElement, agreedSecret); - } + bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;} + void Derive(const DL_GroupParameters ¶ms, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs ¶meters) const + { + SecByteBlock agreedSecret; + if (DHAES_MODE) + { + agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false)); + params.EncodeElement(true, ephemeralPublicKey, agreedSecret); + params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true)); + } + else + { + agreedSecret.New(params.GetEncodedElementSize(false)); + params.EncodeElement(false, agreedElement, agreedSecret); + } - ConstByteArrayParameter derivationParameters; - parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters); - KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size()); - } + ConstByteArrayParameter derivationParameters; + parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters); + KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size()); + } }; //! \class DLIES @@ -938,14 +942,14 @@ public: //! \since Crypto++ 4.0, Crypto++ 5.7 for Bouncy Castle and Botan compatibility template struct DLIES - : public DL_ES< - DL_CryptoKeys_GFP, - DL_KeyAgreementAlgorithm_DH, - DL_KeyDerivationAlgorithm_P1363 >, - DL_EncryptionAlgorithm_Xor, DHAES_MODE, LABEL_OCTETS>, - DLIES<> > + : public DL_ES< + DL_CryptoKeys_GFP, + DL_KeyAgreementAlgorithm_DH, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE, LABEL_OCTETS>, + DLIES<> > { - static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized + static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized }; NAMESPACE_END