aboutsummaryrefslogtreecommitdiff
path: root/src/script/interpreter.cpp
AgeCommit message (Collapse)Author
2022-07-20Use HashWriter where possibleMacroFake
2022-05-25Add BIP-341 specified constraints to `ComputeTaprootMerkleRoot`David Bakin
BIP 341 specifies constraints on the size of the control block _c_ used to compute the taproot merkle root. > The last stack element is called the control block _c_, and must have > length _33 + 32m_, for a value of m that is an integer between 0 and > 128, inclusive. Fail if it does not have such a length. (See BIP-341 "Script Validation Rules" here: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#script-validation-rules)
2022-04-05Merge bitcoin/bitcoin#24147: Miniscript integrationlaanwj
2da94a4c6f55f7a3621f4a6f70902c52f735c868 fuzz: add a fuzz target for Miniscript decoding from Script (Antoine Poinsot) f8369996e76dbc41a12f7b7eea14a7e7990a81c1 Miniscript: ops limit and stack size computation (Pieter Wuille) 2e55e88f86d0dd49b35d04af3f57e863498aabae Miniscript: conversion from script (Pieter Wuille) 1ddaa66eae67b102f5e37d212d366a5dcad4aa26 Miniscript: type system, script creation, text notation, tests (Pieter Wuille) 4fe29368c0ded0e62f437cab3a7c904f7fd3ad67 script: expose getter for CScriptNum, add a BuildScript helper (Antoine Poinsot) f4e289f384efdda6c3f56e1e1c30820a91ac2612 script: move CheckMinimalPush from interpreter to script.h (Antoine Poinsot) 31ec6ae92a5d9910a26d90a6ff20bab27dee5826 script: make IsPushdataOp non-static (Antoine Poinsot) Pull request description: Miniscript is a language for writing (a subset of) Bitcoin Scripts in a structured way. Miniscript permits: - To safely extend the Output Descriptor language to many more scripting features thanks to the typing system (composition). - Statical analysis of spending conditions, maximum spending cost of each branch, security properties, third-party malleability. - General satisfaction of any correctly typed ("valid" [0]) Miniscript. The satisfaction itself is also analyzable. - To extend the possibilities of external signers, because of all of the above and since it carries enough metadata. Miniscript guarantees: - That for any statically-analyzed as "safe" [0] Script, a witness can be constructed in the bounds of the consensus and standardness rules (standardness complete). - That unless the conditions of the Miniscript are met, no witness can be created for the Script (consensus sound). - Third-party malleability protection for the satisfaction of a sane Miniscript, which is too complex to summarize here. For more details around Miniscript (including the specifications), please refer to the [website](https://bitcoin.sipa.be/miniscript/). Miniscript was designed by Pieter Wuille, Andrew Poelstra and Sanket Kanjalkar. This PR is an updated and rebased version of #16800. See [the commit history of the Miniscript repository](https://github.com/sipa/miniscript/commits/master) for details about the changes made since September 2019 (TL;DR: bugfixes, introduction of timelock conflicts in the type system, `pk()` and `pkh()` aliases, `thresh_m` renamed to `multi`, all recursive algorithms were made non-recursive). This PR is also the first in a series of 3: - The first one (here) integrates the backbone of Miniscript. - The second one (#24148) introduces support for Miniscript in Output Descriptors, allowing for watch-only support of Miniscript Descriptors in the wallet. - The third one (#24149) implements signing for these Miniscript Descriptors, using Miniscript's satisfaction algorithm. Note to reviewers: - Miniscript is currently defined only for P2WSH. No Taproot yet. - Miniscript is different from the policy language (a high-level logical representation of a spending policy). A policy->Miniscript compiler is not included here. - The fuzz target included here is more interestingly extended in the 3rd PR to check a script's satisfaction against `VerifyScript`. I think it could be further improved by having custom mutators as we now have for multisig (see https://github.com/bitcoin/bitcoin/issues/23105). A minified corpus of Miniscript Scripts is available at https://github.com/bitcoin-core/qa-assets/pull/85. [0] We call "valid" any correctly-typed Miniscript. And "safe" any sane Miniscript, ie one whose satisfaction isn't malleable, which requires a key for any spending path, etc.. ACKs for top commit: jb55: ACK 2da94a4c6f55f7a3621f4a6f70902c52f735c868 laanwj: Light code review ACK 2da94a4c6f55f7a3621f4a6f70902c52f735c868 (mostly reviewed the changes to the existing code and build system) Tree-SHA512: d3ef558436cfcc699a50ad13caf1e776f7d0addddb433ee28ef38f66ea5c3e581382d8c748ccac9b51768e4b95712ed7a6112b0e3281a6551e0f325331de9167
2022-04-04refactor: fix clang-tidy named args usagefanquake
2022-03-17script: move CheckMinimalPush from interpreter to script.hAntoine Poinsot
It is used by Miniscript.
2022-01-27Merge bitcoin/bitcoin#23438: refactor: Use spans of std::byte in serializelaanwj
fa5d2e678c809c26bd40d7e7c171529d3ffb5903 Remove unused char serialize (MarcoFalke) fa24493d6394b3a477535f480664c9596f18e3c5 Use spans of std::byte in serialize (MarcoFalke) fa65bbf217b725ada35107b4ad646d250228355c span: Add BytePtr helper (MarcoFalke) Pull request description: This changes the serialize code (`.read()` and `.write()` functions) to take a `Span` instead of a pointer and size. This is a breaking change for the serialize interface, so at no additional cost we can also switch to `std::byte` (instead of using `char`). The benefits of using `Span`: * Less verbose and less fragile code when passing an already existing `Span`(-like) object to or from serialization The benefits of using `std::byte`: * `std::byte` can't accidentally be mistaken for an integer The goal here is to only change serialize to use spans of `std::byte`. If needed, `AsBytes`, `MakeUCharSpan`, ... can be used (temporarily) to pass spans of the right type. Other changes that are included here: * [#22167](https://github.com/bitcoin/bitcoin/pull/22167) (refactor: Remove char serialize by MarcoFalke) * [#21906](https://github.com/bitcoin/bitcoin/pull/21906) (Preserve const in cast on CTransactionSignatureSerializer by promag) ACKs for top commit: laanwj: Concept and code review ACK fa5d2e678c809c26bd40d7e7c171529d3ffb5903 sipa: re-utACK fa5d2e678c809c26bd40d7e7c171529d3ffb5903 Tree-SHA512: 08ee9eced5fb777cedae593b11e33660bed9a3e1711a7451a87b835089a96c99ce0632918bb4666a4e859c4d020f88fb50f2dd734216b0c3d1a9a704967ece6f
2022-01-19Optimize CHECKSIGADD Script ValidationJeremy Rubin
2022-01-02Use spans of std::byte in serializeMarcoFalke
This switches .read() and .write() to take spans of bytes.
2021-12-30scripted-diff: Bump copyright headersHennadii Stepanov
-BEGIN VERIFY SCRIPT- ./contrib/devtools/copyright_header.py update ./ -END VERIFY SCRIPT- Commits of previous years: * 2020: fa0074e2d82928016a43ca408717154a1c70a4db * 2019: aaaaad6ac95b402fe18d019d67897ced6b316ee0
2021-11-29More Span simplificationsPieter Wuille
Based on suggestions by MarcoFalke <falke.marco@gmail.com>
2021-11-12tests: implement BIP341 test vectorsPieter Wuille
2021-08-20Avoid temporary vectors/uint256s in VerifyTaprootCommitmentPieter Wuille
As XOnlyPubKey has a Span-based constructor, that can be used directly without needing to first convert the byte sequence into a vector, only to convert that to a uint256, which only then can then be passed as a span to the constructor.
2021-07-19[Refactor] Rename scriptPubKey -> exec_scriptsanket1729
Rename misleading scriptPubKey in ExecuteWitnessScript() function to correctly relfect what is being executed.
2021-06-30Merge bitcoin/bitcoin#18096: doc: IsFinalTx comment about nSequence & OP_CLTVMarcoFalke
f9e37f33ce2d8b463a0bcbe7189c9bc5b36530b7 doc: IsFinalTx comment about nSequence & OP_CLTV (Yuval Kogman) Pull request description: It's somewhat surprising that a transaction's `nLockTime` field is ignored when all `nSequence` fields are final, so this change aims to clarify this behavior and cross reference relevant details of `OP_CHECKLOCKTIMEVERIFY`. ACKs for top commit: MarcoFalke: ACK f9e37f33ce2d8b463a0bcbe7189c9bc5b36530b7 Tree-SHA512: 88460dacbe4b8115fb1948715f09b21d4f34ba1da9e88d52f0b774a969f845e9eddc5940e7fee66eacdd3062dc40d6d44c3f282b0e5144411fd47eb2320b44f5
2021-06-18consensus refactor: extract ComputeTapleafHash, ComputeTaprootMerkleRootPieter Wuille
2021-06-12Permit full precomputation in PrecomputedTransactionDataPieter Wuille
At verification time, the to be precomputed data can be inferred from the transaction itself. For signing, the necessary witnesses don't exist yet, so just permit precomputing everything in that case.
2021-06-12Use HandleMissingData also in CheckSchnorrSignaturePieter Wuille
2021-05-24Add TaprootBuilder classPieter Wuille
This class functions as a utility for building taproot outputs, from internal key and script leaves.
2021-05-24Make consensus checking of tweaks in pubkey.* Taproot-specificPieter Wuille
That results in a much safer interface (making the tweak commit to the key implicitly using a fixed tag means it can't be used for unrelated tweaking).
2021-05-04refactor: Replace &foo[0] with foo.data()MarcoFalke
2021-04-28script: match multisigs with up to MAX_PUBKEYS_PER_MULTISIG keysAntoine Poinsot
We were previously ruling out 17-20 pubkeys multisig, while they are only invalid under P2SH context. This makes multisigs with up to 20 keys be detected as valid by the solver. This is however *not* a policy change as it would only apply to bare multisigs, which are already limited to 3 pubkeys. Note that this does not change the sigOpCount calculation (as it would break consensus). Therefore 1-16 keys multisigs are counted as 1-16 sigops and 17-20 keys multisigs are counted as 20 sigops. Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
2021-04-27doc: IsFinalTx comment about nSequence & OP_CLTVYuval Kogman
It's somewhat surprising that a transaction's nLockTime field is ignored when all nSequence fields are final, so this change aims to clarify this behavior and cross reference relevant details of OP_CHECKLOCKTIMEVERIFY.
2021-03-15Treat amount<0 also as missing data for P2WPKH/P2WSHPieter Wuille
Historically lack of amount data has been treated as amount==-1. Change this and treat it as missing data, as introduced in the previous commits. To be minimally invasive, do this at SignatureHash() call sites rather than inside SignatureHash() (which currently has no means or returning a failure code).
2021-03-15Add MissingDataBehavior and make TransactionSignatureChecker handle itPieter Wuille
This allows specifying how *TransactionSignatureChecker will behave when presented with missing transaction data such as amounts spent, BIP341 data, or spent outputs. As all call sites still (implicitly) use MissingDataBehavior::ASSERT_FAIL, this commit introduces no change in behavior.
2021-03-01Correction for VerifyTaprootCommitment commentsRussell O'Connor
According to BIP-341, 'p' is called the taproot *internal* key, not inner key.
2020-12-06Don't declare de facto const member functions as non-constpracticalswift
2020-11-26Add comments to VerifyTaprootCommitmentPieter Wuille
2020-10-12Implement Tapscript script validation rules (BIP 342)Johnson Lau
This adds a new `SigVersion::TAPSCRIPT`, makes the necessary interpreter changes to make it implement BIP342, and uses them for leaf version 0xc0 in Taproot script path spends.
2020-10-12Use ScriptExecutionData to pass through annex hashPieter Wuille
Instead of recomputing the annex hash every time a signature is verified, compute it once and cache it in a new ScriptExecutionData structure.
2020-10-12Implement Taproot validation (BIP 341)Pieter Wuille
This includes key path spending and script path spending, but not the Tapscript execution implementation (leaf 0xc0 remains unemcumbered in this commit). Includes constants for various aspects of the consensus rules suggested by Jeremy Rubin.
2020-10-12Support for Schnorr signatures and integration in SignatureCheckers (BIP 340)Pieter Wuille
This enables the schnorrsig module in libsecp256k1, adds the relevant types and functions to src/pubkey, as well as in higher-level `SignatureChecker` classes. The (verification side of the) BIP340 test vectors is also added.
2020-10-12Implement Taproot signature hashing (BIP 341)Johnson Lau
This implements the new sighashing scheme from BIP341, with all relevant whole-transaction values precomputed once and cached. Includes changes to PrecomputedTransactionData by Pieter Wuille.
2020-10-12refactor: keep spent outputs in PrecomputedTransactionDataPieter Wuille
A BIP-341 signature message may commit to the scriptPubKeys and amounts of all spent outputs (including other ones than the input being signed for spends), so keep them available to signature hashing code.
2020-10-06refactor: rename scriptPubKey in VerifyWitnessProgram to exec_scriptPieter Wuille
The old name is confusing, as it doesn't store a scriptPubKey, but the actually executed script.
2020-10-06scripted-diff: put ECDSA in name of signature functionsPieter Wuille
In preparation for adding Schnorr versions of `CheckSig`, `VerifySignature`, and `ComputeEntry`, give them an ECDSA specific name. -BEGIN VERIFY SCRIPT- sed -i 's/CheckSig(/CheckECDSASignature(/g' $(git grep -l CheckSig ./src) sed -i 's/VerifySignature(/VerifyECDSASignature(/g' $(git grep -l VerifySignature ./src) sed -i 's/ComputeEntry(/ComputeEntryECDSA(/g' $(git grep -l ComputeEntry ./src) -END VERIFY SCRIPT-
2020-09-28scripted-diff: Replace UINT256_ONE() with uint256::ONEAnthony Towns
-BEGIN VERIFY SCRIPT- sed -i '/inline.* UINT256_ONE() {/,+1d' src/uint256.h sed -i 's/UINT256_ONE()/uint256::ONE/' $(git grep -l UINT256_ONE) -END VERIFY SCRIPT-
2020-08-07Refactor Get{Prevout,Sequence,Outputs}Hash to ↵Jeremy Rubin
Get{Prevouts,Sequences,Outputs}SHA256. Several proposals (Taproot, MuHash, CTV) require access to the single hash.
2020-07-30Make CHash256/CHash160 output to SpanPieter Wuille
2020-07-30Make CHash256 and CHash160 consume SpansPieter Wuille
2020-05-12Simplify usage of Span in several placesPieter Wuille
2020-04-16scripted-diff: Bump copyright headersMarcoFalke
-BEGIN VERIFY SCRIPT- ./contrib/devtools/copyright_header.py update ./ -END VERIFY SCRIPT-
2020-04-16Merge #18401: Refactor: Initialize PrecomputedTransactionData in ↵MarcoFalke
CheckInputScripts f63dec189c3c8eee1ab2187681d5d0b2513b1b2e [REFACTOR] Initialize PrecomputedTransactionData in CheckInputScripts (Pieter Wuille) Pull request description: This is a single commit taken from the Schnorr/Taproot PR #17977. Add a default constructor to `PrecomputedTransactionData`, which doesn't initialize the struct's members. Instead they're initialized inside the `CheckInputScripts()` function. This allows a later commit to add the spent UTXOs to that structure. The spent UTXOs are required for the schnorr signature hash, since it commits to the scriptPubKeys. See https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message for details. By itself, this isn't really an improvement to the code, but I think it makes sense to separate out the refactor/moveonly commits from PR #17977 so that PR is only the logical changes needed for Schnorr/Taproot. ACKs for top commit: jonatack: Re-ACK f63dec1 `git diff 851908d f63dec1` shows no change since last ACK. sipa: utACK f63dec189c3c8eee1ab2187681d5d0b2513b1b2e theStack: re-ACK f63dec189c3c8eee1ab2187681d5d0b2513b1b2e fjahr: Re-ACK f63dec189c3c8eee1ab2187681d5d0b2513b1b2e ariard: Code Review ACK f63dec1 Tree-SHA512: ecf9154077824ae4c274b4341e985797f3648c0cb0c31cb25ce382163b923a3acbc7048683720be4ae3663501801129cd0f48c441a36f049cc304ebe9f30994e
2020-04-11[REFACTOR] Initialize PrecomputedTransactionData in CheckInputScriptsPieter Wuille
Add a default constructor to `PrecomputedTransactionData`, which doesn't initialize the struct's members. Instead they're initialized inside the `CheckInputScripts()` function. This allows a later commit to add the spent UTXOs to that structure.
2020-04-10Merge #18422: [consensus] MOVEONLY: Move single-sig checking EvalScript code ↵MarcoFalke
to EvalChecksig 14e8cf974a7a317796ef8e97e5cf9c355ceff0ee [consensus] MOVEONLY: Move single-sig checking EvalScript code to EvalChecksig (Pieter Wuille) Pull request description: This is another small refactor pulled out of the Schnorr/Taproot PR #17977. This is in preparation for adding different signature verification rules, specifically tapscript (BIP 342), which interprets opcode 0xac and 0xad as Schnorr signature verifications. ACKs for top commit: sipa: ACK 14e8cf974a7a317796ef8e97e5cf9c355ceff0ee, verified move-only. MarcoFalke: ACK 14e8cf974a7a317796ef8e97e5cf9c355ceff0ee, reviewed with "git show 14e8cf974a7a317796ef8e97e5cf9c355ceff0ee --color-moved=dimmed-zebra --color-moved-ws=ignore-all-space -W" 👆 fjahr: Code-review ACK 14e8cf974a7a317796ef8e97e5cf9c355ceff0ee, verified that it's move-only. instagibbs: code review ACK https://github.com/bitcoin/bitcoin/pull/18422/commits/14e8cf974a7a317796ef8e97e5cf9c355ceff0ee, verified move-only theStack: Code-Review ACK https://github.com/bitcoin/bitcoin/commit/14e8cf974a7a317796ef8e97e5cf9c355ceff0ee jonatack: ACK 14e8cf974a7a317796ef8e97e5cf9c355ceff0ee Tree-SHA512: af2efce9ae39d5ec01db5b9ef0ff383fe252ef5f33b3483927308ae17d91a619266cb45951f32ea1ce54807a4c0f052bcdefb47e244465d3a726393221c227b1
2020-03-24[consensus] MOVEONLY: Move single-sig checking EvalScript code to EvalChecksigPieter Wuille
This is in preparation for adding different signature verification rules, specifically tapscript (BIP 342), which interprets opcode 0xac and 0xad as Schnorr signature verifications.
2020-03-23Make VerifyWitnessProgram use a Span stackPieter Wuille
This allows for very cheap transformations on the range of elements that are to be passed to ExecuteWitnessScript.
2020-03-14Merge #16902: O(1) OP_IF/NOTIF/ELSE/ENDIF script implementationWladimir J. van der Laan
e6e622e5a0e22c2ac1b50b96af818e412d67ac54 Implement O(1) OP_IF/NOTIF/ELSE/ENDIF logic (Pieter Wuille) d0e8f4d5d8ddaccb37f98b7989fb944081e41ab8 [refactor] interpreter: define interface for vfExec (Anthony Towns) 89fb241c54fc85befacfa3703d8e21bf3b8a76eb Benchmark script verification with 100 nested IFs (Pieter Wuille) Pull request description: While investigating what mechanisms are possible to maximize the per-opcode verification cost of scripts, I noticed that the logic for determining whether a particular opcode is to be executed is O(n) in the nesting depth. This issue was also pointed out by Sergio Demian Lerner in https://bitslog.wordpress.com/2017/04/17/new-quadratic-delays-in-bitcoin-scripts/, and this PR implements a variant of the O(1) algorithm suggested there. This is not a problem currently, because even with a nesting depth of 100 (the maximum possible right now due to the 201 ops limit), the slowdown caused by this on my machine is around 70 ns per opcode (or 0.25 s per block) at worst, far lower than what is possible with other opcodes. This PR mostly serves as a proof of concept that it's possible to avoid it, which may be relevant in discussions around increasing the opcode limits in future script versions. Without it, the execution time of scripts can grow quadratically with the nesting depth, which very quickly becomes unreasonable. This improves upon #14245 by completely removing the `vfExec` vector. ACKs for top commit: jnewbery: Code review ACK e6e622e5a0e22c2ac1b50b96af818e412d67ac54 MarcoFalke: ACK e6e622e5a0e22c2ac1b50b96af818e412d67ac54 🐴 fjahr: ACK e6e622e5a0e22c2ac1b50b96af818e412d67ac54 ajtowns: ACK e6e622e5a0e22c2ac1b50b96af818e412d67ac54 laanwj: concept and code review ACK e6e622e5a0e22c2ac1b50b96af818e412d67ac54 jonatack: ACK e6e622e5a0e22c2ac1b50b96af818e412d67ac54 code review, build, benches, fuzzing Tree-SHA512: 1dcfac3411ff04773de461959298a177f951cb5f706caa2734073bcec62224d7cd103767cfeef85cd129813e70c14c74fa8f1e38e4da70ec38a0f615aab1f7f7
2020-02-12[REFACTOR] Abstract out script execution out of VerifyWitnessProgram()Pieter Wuille
This removes the unclear reliance on "falling through" to get to the script execution part. Also fix some code style issues.
2020-01-23refactor: define a UINT256_ONE global constantAndrew Chow
Instead of having a uint256 representations of one scattered throughout where it is used, define it globally in uint256.h
2019-12-30scripted-diff: Bump copyright of files changed in 2019MarcoFalke
-BEGIN VERIFY SCRIPT- ./contrib/devtools/copyright_header.py update ./ -END VERIFY SCRIPT-