diff --git a/src/pubkey.h b/src/pubkey.h --- a/src/pubkey.h +++ b/src/pubkey.h @@ -10,6 +10,8 @@ #include "serialize.h" #include "uint256.h" +#include + #include #include @@ -140,7 +142,11 @@ /** * Check whether a signature is normalized (lower-S). */ - static bool CheckLowS(const std::vector &vchSig); + static bool + CheckLowS(const boost::sliced_range> &vchSig); + static bool CheckLowS(const std::vector &vchSig) { + return CheckLowS(vchSig | boost::adaptors::sliced(0, vchSig.size())); + } //! Recover a public key from a compact signature. bool RecoverCompact(const uint256 &hash, diff --git a/src/pubkey.cpp b/src/pubkey.cpp --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -291,7 +291,8 @@ return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode); } -/* static */ bool CPubKey::CheckLowS(const std::vector &vchSig) { +bool CPubKey::CheckLowS( + const boost::sliced_range> &vchSig) { secp256k1_ecdsa_signature sig; if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size())) { diff --git a/src/script/sigencoding.cpp b/src/script/sigencoding.cpp --- a/src/script/sigencoding.cpp +++ b/src/script/sigencoding.cpp @@ -9,6 +9,8 @@ #include "pubkey.h" #include "script_flags.h" +#include + /** * A canonical signature exists of: <30> <02> <02> , where R and S are not negative (their first byte has its @@ -90,15 +92,12 @@ } static bool IsLowDERSignature(const valtype &vchSig, ScriptError *serror) { - if (!IsValidSignatureEncoding(vchSig)) { - return set_error(serror, SCRIPT_ERR_SIG_DER); - } - std::vector vchSigCopy(vchSig.begin(), - vchSig.begin() + vchSig.size() - 1); - if (!CPubKey::CheckLowS(vchSigCopy)) { - return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); + assert(vchSig.size() > 0); + if (CPubKey::CheckLowS(vchSig | + boost::adaptors::sliced(0, vchSig.size() - 1))) { + return true; } - return true; + return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); } bool CheckSignatureEncoding(const valtype &vchSig, uint32_t flags,