Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2009-2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#include <script/interpreter.h>8#include <crypto/ripemd160.h>9#include <crypto/sha1.h>10#include <crypto/sha256.h>11#include <prevector.h>12#include <pubkey.h>13#include <script/script.h>14#include <serialize.h>15#include <span.h>16#include <tinyformat.h>17#include <uint256.h>19#include <algorithm>20#include <cassert>21#include <compare>22#include <cstring>23#include <limits>24#include <stdexcept>26typedef std::vector<unsigned char> valtype;28namespace {30inline bool set_success(ScriptError* ret)31{32if (ret)33*ret = SCRIPT_ERR_OK;34return true;35}37inline bool set_error(ScriptError* ret, const ScriptError serror)38{39if (ret)40*ret = serror;41return false;42}44} // namespace46bool CastToBool(const valtype& vch)47{48for (unsigned int i = 0; i < vch.size(); i++)49{50if (vch[i] != 0)51{52// Can be negative zero53if (i == vch.size()-1 && vch[i] == 0x80)54return false;55return true;56}57}58return false;59}61/**62* Script is a stack machine (like Forth) that evaluates a predicate63* returning a bool indicating valid or not. There are no loops.64*/65#define stacktop(i) (stack.at(size_t(int64_t(stack.size()) + int64_t{i})))66#define altstacktop(i) (altstack.at(size_t(int64_t(altstack.size()) + int64_t{i})))67static inline void popstack(std::vector<valtype>& stack)68{69if (stack.empty())70throw std::runtime_error("popstack(): stack empty");71stack.pop_back();72}74bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {75if (vchPubKey.size() < CPubKey::COMPRESSED_SIZE) {76// Non-canonical public key: too short77return false;78}79if (vchPubKey[0] == 0x04) {80if (vchPubKey.size() != CPubKey::SIZE) {81// Non-canonical public key: invalid length for uncompressed key82return false;83}84} else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) {85if (vchPubKey.size() != CPubKey::COMPRESSED_SIZE) {86// Non-canonical public key: invalid length for compressed key87return false;88}89} else {90// Non-canonical public key: neither compressed nor uncompressed91return false;92}93return true;94}96bool static IsCompressedPubKey(const valtype &vchPubKey) {97if (vchPubKey.size() != CPubKey::COMPRESSED_SIZE) {98// Non-canonical public key: invalid length for compressed key99return false;100}101if (vchPubKey[0] != 0x02 && vchPubKey[0] != 0x03) {102// Non-canonical public key: invalid prefix for compressed key103return false;104}105return true;106}108/**109* A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>110* Where R and S are not negative (their first byte has its highest bit not set), and not111* excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,112* in which case a single 0 byte is necessary and even required).113*114* See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623115*116* This function is consensus-critical since BIP66.117*/118bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {119// Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash]120// * total-length: 1-byte length descriptor of everything that follows,121// excluding the sighash byte.122// * R-length: 1-byte length descriptor of the R value that follows.123// * R: arbitrary-length big-endian encoded R value. It must use the shortest124// possible encoding for a positive integer (which means no null bytes at125// the start, except a single one when the next byte has its highest bit set).126// * S-length: 1-byte length descriptor of the S value that follows.127// * S: arbitrary-length big-endian encoded S value. The same rules apply.128// * sighash: 1-byte value indicating what data is hashed (not part of the DER129// signature)131// Minimum and maximum size constraints.132if (sig.size() < 9) return false;133if (sig.size() > 73) return false;135// A signature is of type 0x30 (compound).136if (sig[0] != 0x30) return false;138// Make sure the length covers the entire signature.139if (sig[1] != sig.size() - 3) return false;141// Extract the length of the R element.142unsigned int lenR = sig[3];144// Make sure the length of the S element is still inside the signature.145if (5 + lenR >= sig.size()) return false;147// Extract the length of the S element.148unsigned int lenS = sig[5 + lenR];150// Verify that the length of the signature matches the sum of the length151// of the elements.152if ((size_t)(lenR + lenS + 7) != sig.size()) return false;154// Check whether the R element is an integer.155if (sig[2] != 0x02) return false;157// Zero-length integers are not allowed for R.158if (lenR == 0) return false;160// Negative numbers are not allowed for R.161if (sig[4] & 0x80) return false;163// Null bytes at the start of R are not allowed, unless R would164// otherwise be interpreted as a negative number.165if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false;167// Check whether the S element is an integer.168if (sig[lenR + 4] != 0x02) return false;170// Zero-length integers are not allowed for S.171if (lenS == 0) return false;173// Negative numbers are not allowed for S.174if (sig[lenR + 6] & 0x80) return false;176// Null bytes at the start of S are not allowed, unless S would otherwise be177// interpreted as a negative number.178if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false;180return true;181}183bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {184if (!IsValidSignatureEncoding(vchSig)) {185return set_error(serror, SCRIPT_ERR_SIG_DER);186}187// https://bitcoin.stackexchange.com/a/12556:188// Also note that inside transaction signatures, an extra hashtype byte189// follows the actual signature data.190std::vector<unsigned char> vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1);191// If the S value is above the order of the curve divided by two, its192// complement modulo the order could have been used instead, which is193// one byte shorter when encoded correctly.194if (!CPubKey::CheckLowS(vchSigCopy)) {195return set_error(serror, SCRIPT_ERR_SIG_HIGH_S);196}197return true;198}200bool static IsDefinedHashtypeSignature(const valtype &vchSig) {201if (vchSig.size() == 0) {202return false;203}204unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY));205if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)206return false;208return true;209}211bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, script_verify_flags flags, ScriptError* serror) {212// Empty signature. Not strictly DER encoded, but allowed to provide a213// compact way to provide an invalid signature for use with CHECK(MULTI)SIG214if (vchSig.size() == 0) {215return true;216}217if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) {218return set_error(serror, SCRIPT_ERR_SIG_DER);219} else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) {220// serror is set221return false;222} else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) {223return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);224}225return true;226}228bool static CheckPubKeyEncoding(const valtype &vchPubKey, script_verify_flags flags, const SigVersion &sigversion, ScriptError* serror) {229if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchPubKey)) {230return set_error(serror, SCRIPT_ERR_PUBKEYTYPE);231}232// Only compressed keys are accepted in segwit233if ((flags & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE) != 0 && sigversion == SigVersion::WITNESS_V0 && !IsCompressedPubKey(vchPubKey)) {234return set_error(serror, SCRIPT_ERR_WITNESS_PUBKEYTYPE);235}236return true;237}239int FindAndDelete(CScript& script, const CScript& b)240{241int nFound = 0;242if (b.empty())243return nFound;244CScript result;245CScript::const_iterator pc = script.begin(), pc2 = script.begin(), end = script.end();246opcodetype opcode;247do248{249result.insert(result.end(), pc2, pc);250while (static_cast<size_t>(end - pc) >= b.size() && std::equal(b.begin(), b.end(), pc))