diff options
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/bitcoinconsensus.cpp | 19 | ||||
-rw-r--r-- | src/script/bitcoinconsensus.h | 2 | ||||
-rw-r--r-- | src/script/descriptor.cpp | 4 | ||||
-rw-r--r-- | src/script/descriptor.h | 2 | ||||
-rw-r--r-- | src/script/interpreter.cpp | 19 | ||||
-rw-r--r-- | src/script/interpreter.h | 14 | ||||
-rw-r--r-- | src/script/keyorigin.h | 19 | ||||
-rw-r--r-- | src/script/script.h | 2 | ||||
-rw-r--r-- | src/script/sigcache.cpp | 2 | ||||
-rw-r--r-- | src/script/sigcache.h | 2 | ||||
-rw-r--r-- | src/script/sign.cpp | 5 | ||||
-rw-r--r-- | src/script/sign.h | 78 | ||||
-rw-r--r-- | src/script/signingprovider.cpp | 2 | ||||
-rw-r--r-- | src/script/signingprovider.h | 5 | ||||
-rw-r--r-- | src/script/standard.cpp | 2 | ||||
-rw-r--r-- | src/script/standard.h | 2 |
16 files changed, 66 insertions, 113 deletions
diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index a9aa6a0060..f7f9dfc262 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2018 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -22,20 +22,23 @@ public: m_remaining(txToLen) {} - void read(char* pch, size_t nSize) + void read(Span<std::byte> dst) { - if (nSize > m_remaining) + if (dst.size() > m_remaining) { throw std::ios_base::failure(std::string(__func__) + ": end of data"); + } - if (pch == nullptr) + if (dst.data() == nullptr) { throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer"); + } - if (m_data == nullptr) + if (m_data == nullptr) { throw std::ios_base::failure(std::string(__func__) + ": bad source buffer"); + } - memcpy(pch, m_data, nSize); - m_remaining -= nSize; - m_data += nSize; + memcpy(dst.data(), m_data, dst.size()); + m_remaining -= dst.size(); + m_data += dst.size(); } template<typename T> diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index b6939127e1..8fea42e4b9 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2018 The Bitcoin Core developers +// Copyright (c) 2009-2020 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 30f929664f..84040bf847 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2020 The Bitcoin Core developers +// Copyright (c) 2018-2022 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1222,7 +1222,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const error = "A function is needed within P2WSH"; return nullptr; } - error = strprintf("%s is not a valid descriptor function", std::string(expr.begin(), expr.end())); + error = strprintf("'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end())); return nullptr; } diff --git a/src/script/descriptor.h b/src/script/descriptor.h index ecd7c4eea5..16ee2f6d97 100644 --- a/src/script/descriptor.h +++ b/src/script/descriptor.h @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2020 The Bitcoin Core developers +// Copyright (c) 2018-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 6433ba1b58..11b1a1c887 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1303,12 +1303,12 @@ public: it = itBegin; while (scriptCode.GetOp(it, opcode)) { if (opcode == OP_CODESEPARATOR) { - s.write((char*)&itBegin[0], it-itBegin-1); + s.write(AsBytes(Span{&itBegin[0], size_t(it - itBegin - 1)})); itBegin = it; } } if (itBegin != scriptCode.end()) - s.write((char*)&itBegin[0], it-itBegin); + s.write(AsBytes(Span{&itBegin[0], size_t(it - itBegin)})); } /** Serialize an input of txTo */ @@ -1500,7 +1500,7 @@ static bool HandleMissingData(MissingDataBehavior mdb) } template<typename T> -bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb) +bool SignatureHashSchnorr(uint256& hash_out, ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb) { uint8_t ext_flag, key_version; switch (sigversion) { @@ -1568,9 +1568,12 @@ bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata // Data about the output (if only one). if (output_type == SIGHASH_SINGLE) { if (in_pos >= tx_to.vout.size()) return false; - CHashWriter sha_single_output(SER_GETHASH, 0); - sha_single_output << tx_to.vout[in_pos]; - ss << sha_single_output.GetSHA256(); + if (!execdata.m_output_hash) { + CHashWriter sha_single_output(SER_GETHASH, 0); + sha_single_output << tx_to.vout[in_pos]; + execdata.m_output_hash = sha_single_output.GetSHA256(); + } + ss << execdata.m_output_hash.value(); } // Additional data for BIP 342 signatures @@ -1692,7 +1695,7 @@ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vecto } template <class T> -bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey_in, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror) const +bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey_in, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const { assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT); // Schnorr signatures have 32-byte public keys. The caller is responsible for enforcing this. diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 513eaaf94c..cf1953ad22 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -11,6 +11,7 @@ #include <span.h> #include <primitives/transaction.h> +#include <optional> #include <vector> #include <stdint.h> @@ -215,6 +216,9 @@ struct ScriptExecutionData bool m_validation_weight_left_init = false; //! How much validation weight is left (decremented for every successful non-empty signature check). int64_t m_validation_weight_left; + + //! The hash of the corresponding output + std::optional<uint256> m_output_hash; }; /** Signature hash sizes */ @@ -244,7 +248,7 @@ public: return false; } - virtual bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const + virtual bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const { return false; } @@ -272,7 +276,7 @@ enum class MissingDataBehavior }; template<typename T> -bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb); +bool SignatureHashSchnorr(uint256& hash_out, ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb); template <class T> class GenericTransactionSignatureChecker : public BaseSignatureChecker @@ -292,7 +296,7 @@ public: GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(nullptr) {} GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override; - bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override; + bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override; bool CheckLockTime(const CScriptNum& nLockTime) const override; bool CheckSequence(const CScriptNum& nSequence) const override; }; @@ -313,7 +317,7 @@ public: return m_checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion); } - bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override + bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override { return m_checker.CheckSchnorrSignature(sig, pubkey, sigversion, execdata, serror); } diff --git a/src/script/keyorigin.h b/src/script/keyorigin.h index 210395d177..c779872be2 100644 --- a/src/script/keyorigin.h +++ b/src/script/keyorigin.h @@ -18,6 +18,25 @@ struct KeyOriginInfo return std::equal(std::begin(a.fingerprint), std::end(a.fingerprint), std::begin(b.fingerprint)) && a.path == b.path; } + friend bool operator<(const KeyOriginInfo& a, const KeyOriginInfo& b) + { + // Compare the fingerprints lexicographically + int fpr_cmp = memcmp(a.fingerprint, b.fingerprint, 4); + if (fpr_cmp < 0) { + return true; + } else if (fpr_cmp > 0) { + return false; + } + // Compare the sizes of the paths, shorter is "less than" + if (a.path.size() < b.path.size()) { + return true; + } else if (a.path.size() > b.path.size()) { + return false; + } + // Paths same length, compare them lexicographically + return a.path < b.path; + } + SERIALIZE_METHODS(KeyOriginInfo, obj) { READWRITE(obj.fingerprint, obj.path); } void clear() diff --git a/src/script/script.h b/src/script/script.h index 8cd1cc3855..3425bf8102 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 6f911f4fe7..4e2acc463a 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sigcache.h b/src/script/sigcache.h index 7b6b91c963..1e21d6f340 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 3f7060879c..371a937bc8 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,6 +9,7 @@ #include <key.h> #include <policy/policy.h> #include <primitives/transaction.h> +#include <script/keyorigin.h> #include <script/signingprovider.h> #include <script/standard.h> #include <uint256.h> @@ -541,7 +542,7 @@ class DummySignatureChecker final : public BaseSignatureChecker public: DummySignatureChecker() {} bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return true; } - bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror) const override { return true; } + bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const override { return true; } }; const DummySignatureChecker DUMMY_CHECKER; diff --git a/src/script/sign.h b/src/script/sign.h index 50525af332..7301826ba5 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,8 +12,6 @@ #include <script/interpreter.h> #include <script/keyorigin.h> #include <script/standard.h> -#include <span.h> -#include <streams.h> class CKey; class CKeyID; @@ -84,80 +82,6 @@ struct SignatureData { void MergeSignatureData(SignatureData sigdata); }; -// Takes a stream and multiple arguments and serializes them as if first serialized into a vector and then into the stream -// The resulting output into the stream has the total serialized length of all of the objects followed by all objects concatenated with each other. -template<typename Stream, typename... X> -void SerializeToVector(Stream& s, const X&... args) -{ - WriteCompactSize(s, GetSerializeSizeMany(s.GetVersion(), args...)); - SerializeMany(s, args...); -} - -// Takes a stream and multiple arguments and unserializes them first as a vector then each object individually in the order provided in the arguments -template<typename Stream, typename... X> -void UnserializeFromVector(Stream& s, X&... args) -{ - size_t expected_size = ReadCompactSize(s); - size_t remaining_before = s.size(); - UnserializeMany(s, args...); - size_t remaining_after = s.size(); - if (remaining_after + expected_size != remaining_before) { - throw std::ios_base::failure("Size of value was not the stated size"); - } -} - -// Deserialize HD keypaths into a map -template<typename Stream> -void DeserializeHDKeypaths(Stream& s, const std::vector<unsigned char>& key, std::map<CPubKey, KeyOriginInfo>& hd_keypaths) -{ - // Make sure that the key is the size of pubkey + 1 - if (key.size() != CPubKey::SIZE + 1 && key.size() != CPubKey::COMPRESSED_SIZE + 1) { - throw std::ios_base::failure("Size of key was not the expected size for the type BIP32 keypath"); - } - // Read in the pubkey from key - CPubKey pubkey(key.begin() + 1, key.end()); - if (!pubkey.IsFullyValid()) { - throw std::ios_base::failure("Invalid pubkey"); - } - if (hd_keypaths.count(pubkey) > 0) { - throw std::ios_base::failure("Duplicate Key, pubkey derivation path already provided"); - } - - // Read in key path - uint64_t value_len = ReadCompactSize(s); - if (value_len % 4 || value_len == 0) { - throw std::ios_base::failure("Invalid length for HD key path"); - } - - KeyOriginInfo keypath; - s >> keypath.fingerprint; - for (unsigned int i = 4; i < value_len; i += sizeof(uint32_t)) { - uint32_t index; - s >> index; - keypath.path.push_back(index); - } - - // Add to map - hd_keypaths.emplace(pubkey, std::move(keypath)); -} - -// Serialize HD keypaths to a stream from a map -template<typename Stream> -void SerializeHDKeypaths(Stream& s, const std::map<CPubKey, KeyOriginInfo>& hd_keypaths, uint8_t type) -{ - for (auto keypath_pair : hd_keypaths) { - if (!keypath_pair.first.IsValid()) { - throw std::ios_base::failure("Invalid CPubKey being serialized"); - } - SerializeToVector(s, type, Span{keypath_pair.first}); - WriteCompactSize(s, (keypath_pair.second.path.size() + 1) * sizeof(uint32_t)); - s << keypath_pair.second.fingerprint; - for (const auto& path : keypath_pair.second.path) { - s << path; - } - } -} - /** Produce a script signature using a generic signature creator. */ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata); diff --git a/src/script/signingprovider.cpp b/src/script/signingprovider.cpp index 17f97fa30c..552934e0eb 100644 --- a/src/script/signingprovider.cpp +++ b/src/script/signingprovider.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/signingprovider.h b/src/script/signingprovider.h index fbce61c6a9..f1bded1a8c 100644 --- a/src/script/signingprovider.h +++ b/src/script/signingprovider.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -8,12 +8,11 @@ #include <key.h> #include <pubkey.h> +#include <script/keyorigin.h> #include <script/script.h> #include <script/standard.h> #include <sync.h> -struct KeyOriginInfo; - /** An interface to be implemented by keystores that support signing. */ class SigningProvider { diff --git a/src/script/standard.cpp b/src/script/standard.cpp index d9656c781d..5fb98cc307 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/standard.h b/src/script/standard.h index a8e57231bf..eb50421768 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2020 The Bitcoin Core developers +// Copyright (c) 2009-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. |