Changeset View
Changeset View
Standalone View
Standalone View
src/script/sigencoding.cpp
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Copyright (c) 2017-2018 The Bitcoin developers | // Copyright (c) 2017-2018 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "sigencoding.h" | #include "sigencoding.h" | ||||
#include "pubkey.h" | #include "pubkey.h" | ||||
#include "script_flags.h" | #include "script_flags.h" | ||||
#include <boost/range/adaptor/sliced.hpp> | |||||
/** | /** | ||||
* A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len | * A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len | ||||
* S> <S> <hashtype>, where R and S are not negative (their first byte has its | * S> <S> <hashtype>, where R and S are not negative (their first byte has its | ||||
* highest bit not set), and not excessively padded (do not start with a 0 byte, | * highest bit not set), and not excessively padded (do not start with a 0 byte, | ||||
* unless an otherwise negative number follows, in which case a single 0 byte is | * unless an otherwise negative number follows, in which case a single 0 byte is | ||||
* necessary and even required). | * necessary and even required). | ||||
* | * | ||||
* See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 | * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | static bool IsValidSignatureEncoding(const valtype &sig) { | ||||
if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) { | if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) { | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
static bool IsLowDERSignature(const valtype &vchSig, ScriptError *serror) { | static bool IsLowDERSignature(const valtype &vchSig, ScriptError *serror) { | ||||
if (!IsValidSignatureEncoding(vchSig)) { | assert(vchSig.size() > 0); | ||||
return set_error(serror, SCRIPT_ERR_SIG_DER); | if (CPubKey::CheckLowS(vchSig | | ||||
boost::adaptors::sliced(0, vchSig.size() - 1))) { | |||||
return true; | |||||
} | } | ||||
std::vector<uint8_t> vchSigCopy(vchSig.begin(), | |||||
vchSig.begin() + vchSig.size() - 1); | |||||
if (!CPubKey::CheckLowS(vchSigCopy)) { | |||||
return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); | return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); | ||||
} | } | ||||
return true; | |||||
} | |||||
bool CheckSignatureEncoding(const valtype &vchSig, uint32_t flags, | bool CheckSignatureEncoding(const valtype &vchSig, uint32_t flags, | ||||
ScriptError *serror) { | ScriptError *serror) { | ||||
// Empty signature. Not strictly DER encoded, but allowed to provide a | // Empty signature. Not strictly DER encoded, but allowed to provide a | ||||
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG | // compact way to provide an invalid signature for use with CHECK(MULTI)SIG | ||||
if (vchSig.size() == 0) { | if (vchSig.size() == 0) { | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 68 Lines • Show Last 20 Lines |