Jump to conversation
Unresolved conversations (23)
@ariard ariard Sep 3, 2020
I don't get `feature_taproot.py` failure for this : ``` diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 053df47a2..eb3847250 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1528,7 +1528,7 @@ bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata // Data about the output(s) if (output_type == SIGHASH_SINGLE) { - if (in_pos >= tx_to.vout.size()) return false; + if (in_pos >= tx_to.vout.size()) return true; CHashWriter sha_single_output(SER_GETHASH, 0); sha_single_output << tx_to.vout[in_pos]; ss << sha_single_output.GetSHA256(); ``` Also I think this is check can be moved above at `hash_type` validation as every predicate is already known and we would save on hashing by failing faster ?
src/script/interpreter.cpp
sipa
@ariard ariard Sep 3, 2020
I think melting a consensus check with a policy one in the same conditional is likely source to confusion for future reviewers. I'm quite sure that's already something done elsewhere but maybe we could do better by adding a `GetScriptVersionFlags(SigVersion)` called at the top of `EvalScript`. This new function should set each consensus-compliant interpreter flags per-type of script evaluated thus avoiding setting flags for old scripts types if we would do this in `GetBlockScriptFlags` while easily overloading flag setting for future types.
src/script/interpreter.cpp
sipa ariard
@ariard ariard Sep 3, 2020
Why can't we outlaw witness-with-annex from our policy ? EDIT: This is part of it as 7548827. Maybe add a reference that's is outlawed in `IsWitnessStandard`. A side-question, why OP_SUCESSx and unknown public key types aren't rejected there too to gather all witness sanitization check in one place ?
src/script/interpreter.cpp
sipa ariard
@Kixunil Kixunil Sep 2, 2020
Would moving the `control.size()` check here be less of a footgun?
Outdated
src/script/interpreter.cpp
Kixunil sipa
@fjahr fjahr Sep 2, 2020
```suggestion bool XOnlyPubKey::CheckPayToContract(const XOnlyPubKey& base, const uint256& hash, const bool negated) const ```
Outdated
src/pubkey.cpp
@luke-jr luke-jr Aug 25, 2020
All existing disabled opcodes trigger `SCRIPT_ERR_DISABLED_OPCODE` unconditionally, even if their branch isn't taken. Do we want to preserve that for CHECKMULTISIG? If not, do we still want to use the same error code?
Outdated
src/script/interpreter.cpp
sipa
@luke-jr luke-jr Aug 25, 2020
Prefer `assert(false);` for unreachable conditions
src/script/interpreter.cpp
sipa
@luke-jr luke-jr Aug 25, 2020
Should this be non-experimental before merging?
configure.ac
sipa gmaxwell
@luke-jr luke-jr Aug 24, 2020
(Review TODO: Check that this is actually true, even when no signature checking occurs.)
src/script/interpreter.cpp
sipa
@luke-jr luke-jr Aug 24, 2020
I think we should probably require `spent_outputs` in the constructor. That gets us a compile-time error rather than a runtime surprise, if any code is missing an update. Aside from tests (which have a mere 4 uses), it's only used in libbitcoinconsensus, where the omission is arguably a bug (impossible to use existing APIs for Taproot verification).
src/script/interpreter.cpp
sipa
@kallewoof kallewoof Aug 20, 2020
If I want to taproot-sign a transaction, it will not have any ScriptWitness data when I try to obtain the signature hash, which means `m_bip341_ready` will not be set after the `PrecomputedTransactionData::Init()` call has been made. This means I have to put in junk data in the vin's scriptwitness in order to obtain the sighash, which seems off.
Outdated
src/script/interpreter.cpp
instagibbs kallewoof
sipa
@instagibbs instagibbs Aug 10, 2020
I'm getting some strange mutation results: ``` --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1497,7 +1497,7 @@ bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata // Hash type const uint8_t output_type = (hash_type == SIGHASH_DEFAULT) ? SIGHASH_ALL : (hash_type & SIGHASH_OUTPUT_MASK); // Default (no sighash byte) is equivalent to SIGHASH_ALL const uint8_t input_type = hash_type & SIGHASH_INPUT_MASK; - if (!(hash_type <= 0x03 || (hash_type >= 0x80 && hash_type <= 0x83))) return false; + if (!(hash_type <= 0x04 || (hash_type >= 0x80 && hash_type <= 0x84))) return false; ss << hash_type; ``` passes even though it's definitely running the 0x04/0x84 cases. Anything beyond that seems to fail.
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 4, 2020
I'd kind of prefer to just use `IsWitnessProgram` to grab the values for here since I know that works already. What about erring on the side of bip341 precomputing instead? Could just say: ``` if (m_spent_outputs_ready && m_spent_outputs[inpos].scriptPubKey.IsWitnessProgram(version, witness_program) && version > 0) { ``` then we can delete the "unknown witness verison" comment below.
src/script/interpreter.cpp
sipa
@instagibbs instagibbs Jul 28, 2020
nice, you may get 1 to 3 sigops weight left over by chance, but tests will blow that out regularly.
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Jul 28, 2020
Last sentence here is outdated.
test/functional/feature_taproot.py
instagibbs sipa
@Sjors Sjors Jul 23, 2020
41d08f5d77f52bec0e31bb081d85fff2d67d0467: `EPOCH` is explained in BIP-341, but missing from "the message is the concatenation of the following data, in order"
src/script/interpreter.cpp
sipa
@instagibbs instagibbs Jul 20, 2020
Wondering if you could un-magic this constant a bit. I was going to attempt to write another case for unknown pubkey using this template, but ran out of motivation to reverse engineer it.
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Jul 14, 2020
Could mention the key could be busted too.
src/script/script_error.cpp
sipa
@instagibbs instagibbs Jul 14, 2020
Is this ever expected to not hit?
Outdated
src/script/interpreter.cpp
sipa Sjors
@theuni theuni Jul 1, 2020
Any reason not to put the cheap policy check before VerifyTaprootCommitment() ?
src/script/interpreter.cpp
JeremyRubin sipa
@michaelfolkson michaelfolkson Apr 11, 2020
Optional nit (feel free to ignore): Refer to the BIP (341) explaining why single hashes are added. https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-15
Outdated
src/script/interpreter.h
@jnewbery jnewbery Mar 9, 2020
Adding the `!is_p2sh` here means that any transaction input spending a P2SH-wrapped segwit v1 output will be valid, but will fail standardness with`SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM` ("Witness version reserved for soft-fork upgrades") which seems like the wrong error message. We're not expecting P2SH-wrapped segwit v1 outputs to reinterpreted by a future soft-fork, we're simply leaving them unencumbered for safety reasons. I think for correctness we should return a new error type in that case.
Outdated
src/script/interpreter.cpp
sipa
@kallewoof kallewoof Jan 27, 2020
It would be nice if there was an `IsValid()` function to check if the pubkey is actually valid, as opposed to the signature being invalid.
Outdated
src/pubkey.h
sipa StEvUgnIn
kallewoof
Resolved conversations (130)
@ariard ariard Sep 3, 2020
Maybe precise that's invalid with regards to consensus. Or at least we enforce this as a policy rule without any tightening with regards to consensus rule.
Outdated
src/policy/policy.cpp
sipa
@ariard ariard Sep 3, 2020
I don't get `feature_taproot.py` failure for : ``` diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 111f9c10e..0163f61a2 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -174,7 +174,7 @@ XOnlyPubKey::XOnlyPubKey(Span<const unsigned char> in) } bool XOnlyPubKey::VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const { - if (sigbytes.size() != 64) return false; + if (sigbytes.size() != 64) return true; if (msg.size() != 32) return false; secp256k1_xonly_pubkey pubkey; if (!secp256k1_xonly_pubkey_parse(secp256k1_context_verify, & ``` And same for next check on message size.
Outdated
src/pubkey.cpp
sipa
@ariard ariard Sep 3, 2020
Does this key version is actually the one of defined 32-byte public key or it is an independent versioning ? If it is the first option I think we should add a `m_key_version` to `ScriptExecutionData` and ensure we set it at key type detection in `ExecuteWitnessScript` to avoid hashing and public key validation going out of sync ?
Outdated
src/script/interpreter.cpp
sipa
@ariard ariard Sep 3, 2020
I think BIP341 footnote mentions that TAPSCRIPT's `ext_flag=1` but I don't find where it mandates that TAPROOT's one is actually `ext_flag=0`
src/script/interpreter.cpp
sipa
@ariard ariard Sep 3, 2020
Is MINIMALDATA consensus-mandatory for `OP_CHECKSIGADD` or only part of our relay-policy like for other `CScriptNum` operators ? The spec only mentions `All CScriptNum-related behaviours of `OP_ADD` are also applicable to `OP_CHECKSIGADD", it's a bit unclear. In either case flipping it to `true/false` doesn't give me back any test failure.
src/script/interpreter.cpp
sipa
@ariard ariard Sep 3, 2020
I think this comment is ambiguous with regards to `EvalChecksigTapscript` and BIP342 requirement. Successful could be interpreted as : * if signature verification is successful * if signature is non-empty AFAICT, the second alternative is actually what is referred by `signature check`. Maybe add `successful non-empty signature check`
Outdated
src/script/interpreter.h
sipa
@ariard ariard Sep 3, 2020
Should we assert exclusion of scriptless (?) script versions at a higher-level like `EvalScript` or `ExecuteWitnessScript` to catch witness parsing bug where such a script wouldn't call a sig operation ?
src/script/interpreter.cpp
sipa
@ariard ariard Sep 3, 2020
Assert altstack empty ?
src/script/interpreter.cpp
sipa
@ariard ariard Sep 3, 2020
Computation of tweaked_pubkey `Q` is guarantee to be non-malleable by a third-party such that any intentional flip of the parity bit of the control block would fail here ? Is this test somewhere, when I try to test it I got some `opsuccess/return` error ?
src/script/interpreter.cpp
sipa
@ariard ariard Sep 3, 2020
I tried to tweak serializers to test that `compact_size(size of s)` is well-committed in tapleaf hash. Of course I got failure far earlier, so I was wondering if there is a way to test this in isolation ? I guess that's useless as our script ser is already used at anytime, so any error would be more than obvious.
src/script/interpreter.cpp
ariard sipa
@ariard ariard Sep 2, 2020
Technically this should be called `witnessScript` (BIP141) or just `script` (BIP341) ? `scriptPubKey` is a bit confusing as this is fed from the witness?
Outdated
src/script/interpreter.cpp
sipa
@ariard ariard Sep 2, 2020
Again don't get failure in `feature_taproot.py` ? What should be the prefix something like `sighash/keypath_*` ? ``` diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 053df47a2..24ba2ac41 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1662,7 +1662,7 @@ bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const uns hashtype = SpanPopBack(sig); if (hashtype == SIGHASH_DEFAULT) return false; } - if (sig.size() != 64) return false; + if (sig.size() != 64) return true; uint256 sighash; if (!SignatureHashSchnorr(sighash, execdata, *txTo, nIn, hashtype, sigversion, this->txdata)) return false; return VerifySchnorrSignature(sig, pubkey, sighash); ```
Outdated
src/script/interpreter.cpp
sipa
@ariard ariard Sep 2, 2020
Idem, is this part of the code tested non-deterministically ? ``` diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 053df47a2..fcaacc152 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1653,7 +1653,7 @@ template <class T> bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey_in, SigVersion sigversion, const ScriptExecutionData& execdata) const { if (sig.empty()) return false; - if (pubkey_in.size() != 32) return false; + if (pubkey_in.size() != 32) return true; XOnlyPubKey pubkey{pubkey_in}; ```
Outdated
src/script/interpreter.cpp
sipa
@ariard ariard Sep 2, 2020
I don't get a `feature_taproot.py` failure for this ? ``` diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 053df47a2..02de07bc5 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1652,7 +1652,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) const { - if (sig.empty()) return false; + if (sig.empty()) return true; if (pubkey_in.size() != 32) return false; XOnlyPubKey pubkey{pubkey_in}; ```
Outdated
src/script/interpreter.cpp
sipa instagibbs
@ariard ariard Sep 2, 2020
Should be referenced in `CTxDestination` typedef.
src/script/standard.h
sipa
@Kixunil Kixunil Sep 2, 2020
Why not BIP8?
test/functional/rpc_blockchain.py
sipa
@Kixunil Kixunil Sep 2, 2020
This is different from BIP114 which says the max size of path must be below 1024, however `32 * 128 == 4096` Is this correct? I suppose BIP114 limit is superseded by BIP341 (which I find reasonable) but asking to be sure. (Perhaps BIP114 should be updated?)
src/script/interpreter.h
sipa
@fjahr fjahr Sep 2, 2020
(renaming suggested to be consistent with the name in the implementation) ```suggestion bool CheckPayToContract(const XOnlyPubKey& base, const uint256& hash, const bool negated) const; ```
Outdated
src/pubkey.h
sipa
@fjahr fjahr Sep 2, 2020
nit if you retouch ```suggestion const int path_len = (control.size() - TAPROOT_CONTROL_BASE_SIZE) / TAPROOT_CONTROL_NODE_SIZE; const XOnlyPubKey p{uint256(std::vector<unsigned char>(control.begin() + 1, control.begin() + TAPROOT_CONTROL_BASE_SIZE))}; const XOnlyPubKey q{uint256(program)}; uint256 k = (CHashWriter(HASHER_TAPLEAF) << uint8_t(control[0] & TAPROOT_LEAF_MASK) << script).GetSHA256(); for (int i = 0; i < path_len; ++i) { CHashWriter ss_branch{HASHER_TAPBRANCH}; ```
Outdated
src/script/interpreter.cpp
sipa
@Kixunil Kixunil Sep 2, 2020
Since these names look so similar (made me confused), maybe use names without numbers to distinguish them better? Or something like `uses_bip341_taproot`?
Outdated
src/script/interpreter.cpp
sipa
@instagibbs instagibbs Aug 29, 2020
`for k in range(len(pubs)):` ?
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 29, 2020
`r = random.randrange(len(pubs))` ?
Outdated
test/functional/feature_taproot.py
sipa
@luke-jr luke-jr Aug 25, 2020
We should probably policy-reject annex here for now?
Outdated
src/policy/policy.cpp
sipa luke-jr
@luke-jr luke-jr Aug 25, 2020
If we ever had a `continue`, this would get skipped. Seems like a code footgun. We could replace `while (pc < pend)` with `for ( ; pc < pend; ++opcode_pos)` perhaps?
Outdated
src/script/interpreter.cpp
sipa
@luke-jr luke-jr Aug 25, 2020
Probable premature optimisation: Copy `m_salted_hasher_ecdsa` before adding the padding?
src/script/sigcache.cpp
sipa JeremyRubin
@luke-jr luke-jr Aug 25, 2020
Inaccuracy in previous comment aside, seems like it would be best to correct the new one (with 31 null bytes after E/S)
Outdated
src/script/sigcache.cpp
sipa JeremyRubin
@luke-jr luke-jr Aug 25, 2020
Suggest moving the size check and uint256 cast into `XOnlyPubKey` construction & `IsValid`, like `CheckECDSASignature` does
Outdated
src/script/interpreter.cpp
sipa
@luke-jr luke-jr Aug 25, 2020
nit: "is not *exactly* 64 bytes"
Outdated
src/pubkey.h
sipa
@luke-jr luke-jr Aug 25, 2020
Suggest moving `CheckSig` -> `CheckECDSASignature` rename to a dedicated commit
src/script/interpreter.h
sipa
@luke-jr luke-jr Aug 24, 2020
Technically, Tapscript itself is a form of P2SH, just not BIP16 P2SH. The comment here confused me. Perhaps "non-BIP16-wrapped"?
Outdated
src/script/interpreter.h
sipa
@luke-jr luke-jr Aug 24, 2020
Please rename things that change meaning. eg, `GetPrevoutSHA256`
Outdated
src/script/interpreter.cpp
sipa JeremyRubin
@instagibbs instagibbs Aug 10, 2020
nice script for this check
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 10, 2020
take-or-leave-nit: just do `[b''] * 1001`
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 10, 2020
take-or-leave-nit: just do `[b''] * 1001`
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 10, 2020
suggestion: `"sighash/scriptpath_unk_hashtype_{}".format(invalid_hashtype)`
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 10, 2020
suggestion: `"sighash/keypath_unk_hashtype_{}".format(invalid_hashtype)`
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 10, 2020
suggestion: `"sighash/scriptpath_{}".format(hashtype)`
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 10, 2020
suggestion: `"sighash/keypath_{}".format(hashtype)`
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 10, 2020
`s/followed by a dummy/followed by a dummy push of bytes that are to be dropped/`
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 10, 2020
for `leafversion` anything other than `0xc0` should fail it, maybe just flip a bit of this too
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Aug 7, 2020
expression
Outdated
test/functional/feature_taproot.py
sipa
@jnewbery jnewbery Aug 7, 2020
Is there any disadvantage to combining these two lines and eliminating the temporary return value: ```suggestion if !(SignatureHashSchnorr(sighash, execdata, *txTo, nIn, hashtype, sigversion, this->txdata) return false; ```
Outdated
src/script/interpreter.cpp
sipa
@jnewbery jnewbery Aug 7, 2020
There's a naming inconsistency here. `VerifySignature` changed to `VerifyECDSASignature`/`VerifySchnorrSignature`, but `CheckSig` has changed to `CheckSigSchnorr`/`CheckSig`. Would it be better to name them `CheckSchnorrSig`/`CheckECDSASig`?
Outdated
src/script/interpreter.h
sipa
@jnewbery jnewbery Aug 7, 2020
Any reason not to do a range-based for loop here? ```suggestion for (const CTxIn& txin : tx.vin) { const COutPoint &prevout = txin.prevout; ```
Outdated
src/validation.cpp
sipa
@JeremyRubin JeremyRubin Aug 4, 2020
don't we use these caches for any non taproot signature? Not just segwit?
Outdated
src/script/interpreter.cpp
sipa
@gmaxwell gmaxwell Jul 29, 2020
//! Entries are SHA256(nonce || 'E' or 'S' || 0x00 * 32 || signature hash || public key || signature)
Outdated
src/script/sigcache.cpp
sipa
@Sjors Sjors Jul 24, 2020
But only if `OP_SUCCESSx` occurred earlier? Is it worth the effort to check the whole script for `OP_SUCCESSx` before and then do second pass for other conditions?
src/script/interpreter.cpp
Sjors sipa
JeremyRubin
@Sjors Sjors Jul 24, 2020
``` /** Helper for OP_CHECKSIG, OP_CHECKSIGVERIFY and OP_CHECKSIGADD ```
Outdated
src/script/interpreter.cpp
sipa
@Sjors Sjors Jul 24, 2020
I would find it marginally more readable to use `!sig.empty()` in the `if` statements below and move `success = !sig.empty();` all the way to the bottom.
src/script/interpreter.cpp
sipa
@fjahr fjahr Jul 24, 2020
styleguide nit: ```suggestion for (unsigned int i = 0; i < tx.vin.size(); ++i) { ```
Outdated
src/validation.cpp
sipa
@fjahr fjahr Jul 24, 2020
I think these runtime constants tend to be formatted like normal variables in the rest of the code base, i.e. snake case. But there does not seem to be a particular rule on these in the style guide.
Outdated
src/script/interpreter.cpp
sipa Sjors
@Sjors Sjors Jul 24, 2020
cbcaab9a66f82fa5bcc2711a5fee2adc47004cc8 nit: `m_annex_hash` is only initialized if `m_annex_present` is `true`, though I doubt it will confuse anyone. Alternate wordings: ```cpp //! Whether m_annex_present is initialized ``` Or: ```cpp //! Whether m_annex_present and (when needed) m_annex_hash are initialized. ```
Outdated
src/script/interpreter.h
sipa JeremyRubin
@Sjors Sjors Jul 24, 2020
b7a7f6ab2ccc30e323a5396c27cb82ffd613550b nit: these comments could be introduced in 41d08f5d77f52bec0e31bb081d85fff2d67d0467 (which adds `TAPROOT = 2`)
Outdated
src/script/interpreter.h
sipa
@fjahr fjahr Jul 24, 2020
nit: I would prefer the `execdata` before `serror`. Would also be more consistent with `ExecuteWitnessScript`.
src/script/interpreter.cpp
sipa
@jnewbery jnewbery Jul 24, 2020
nit: sort :)
test/functional/test_framework/key.py
sipa
@jnewbery jnewbery Jul 24, 2020
I agree with @Sjors (https://github.com/bitcoin/bitcoin/pull/17977#discussion_r459527853) that these should be renamed. `m_prevouts_hash` and `hashPrevouts` doesn't communicate that one of these members is the SHA256 digest and the other is the dSHA256 digest. I'd propose `m_prevouts_sha256` and `m_prevouts_double_sha256`, but anything that communicates what these are would be an improvement.
src/script/interpreter.h
sipa
@jnewbery jnewbery Jul 24, 2020
`hash` is the wrong name for this param. It should be `input` to match the header declaration (although I think `preimage` would be better still).
Outdated
src/hash.cpp
sipa
@brmdbr brmdbr Jul 23, 2020
Hate to do this: capitalisation. Tagged hash
Outdated
...p256k1/src/modules/schnorrsig/main_impl.h
sipa
@Sjors Sjors Jul 23, 2020
41d08f5d77f52bec0e31bb081d85fff2d67d0467 : isn't this missing a `compact_size(size of annex)` prefix?
Outdated
src/script/interpreter.cpp
Sjors sipa
instagibbs
@Sjors Sjors Jul 23, 2020
41d08f5: The BIP (still?) says `0x50` (I see this completely changes in a later commit, so will revisit then)
Outdated
src/script/interpreter.cpp
sipa
@Sjors Sjors Jul 23, 2020
41d08f5: this could lead to confusion if a later upgrade adds and permits a new SIGHASH type, given that the BIP specifies this as a negative: "If `hash_type & 3` does not equal `SIGHASH_NONE` or `SIGHASH_SINGLE`".
src/script/interpreter.cpp
sipa
@Sjors Sjors Jul 23, 2020
41d08f5d77f52bec0e31bb081d85fff2d67d0467 : `TapSighash` is written in camel case (`TapSigHash`) most of the time in BIP 341 (which would be my preference too).
Outdated
src/script/interpreter.cpp
sipa
@Sjors Sjors Jul 23, 2020
41d08f5d77f52bec0e31bb081d85fff2d67d0467: maybe rename to `m_prevouts_hash_v0` or `m_prevouts_double_hash`? In addition, shouldn't we skip calculating hashes we don't need depending on the witness version? Or is that negligible for validation performance (sorry, too lazy to bench this myself)?
Outdated
src/script/interpreter.cpp
JeremyRubin sipa
Sjors
@Sjors Sjors Jul 23, 2020
41d08f5d77f52bec0e31bb081d85fff2d67d0467: let's document that `uint256 GetPrevoutHash` and `GetSequenceHash` (now) return a single SHA256 hash. Perhaps we should rename them to GetPrevout**s**Hash and GetSequence**s**Hash, consistent with `GetSpentAmountsHash` and `GetSpentScriptsHash`. In BIP-341 the phrasing is slightly ambiguous: "sha_prevouts (32): the SHA256 of the serialization of all input outpoints." It could be more clear that this means concatenate all previous and then hash them, rather than to concatenate the hashes. Changing the variable name helps with that clarity too.
Outdated
src/script/interpreter.cpp
sipa JeremyRubin
@instagibbs instagibbs Jul 17, 2020
FYI nonstandard txns are rejected by default in regtest now ( I don't mind explicit args in tests so meh)
Outdated
test/functional/feature_taproot.py
sipa
@instagibbs instagibbs Jul 15, 2020
Should mention/rename it to show it's "add" not "mult"
Outdated
test/functional/test_framework/key.py
sipa instagibbs
jnewbery
@instagibbs instagibbs Jul 15, 2020
Should mention/rename it to show it's "add" not "mult"
Outdated
test/functional/test_framework/key.py
sipa
@instagibbs instagibbs Jul 15, 2020
Currently this only enforces `MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE` on top of consensus checks, yes?
Outdated
src/policy/policy.cpp
sipa
@instagibbs instagibbs Jul 15, 2020
I think it'd be cleaner to just make the `Span` here, then use it for next 4 lines?
Outdated
src/script/interpreter.cpp
sipa
@instagibbs instagibbs Jul 15, 2020
this would be easy/nice to split out for unit tests
Outdated
src/script/interpreter.cpp
instagibbs sipa
@instagibbs instagibbs Jul 14, 2020
The various peppering of `sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0` and `sigversion != SigVersion::TAPSCRIPT` makes me a little uneasy. Synchronize these checks?
src/script/interpreter.cpp
sipa
@instagibbs instagibbs Jul 14, 2020
N.B.: Let's make sure there's a test that catches the >4 bytes rule for addition
src/script/interpreter.cpp
sipa instagibbs
@instagibbs instagibbs Jul 14, 2020
> The following validation sequence is consensus critical. You don't say
src/script/interpreter.cpp
Sjors sipa
@instagibbs instagibbs Jul 14, 2020
did I miss why the const is dropped here?
Outdated
src/script/interpreter.cpp
sipa
@instagibbs instagibbs Jul 14, 2020
please annotate `/* is_p2sh */`
Outdated
src/script/interpreter.cpp
sipa
@instagibbs instagibbs Jul 14, 2020
please annotate `/* is_p2sh */`
Outdated
src/script/interpreter.cpp
sipa
@instagibbs instagibbs Jul 14, 2020
`s/32/m_keydata.size()/`
Outdated
src/pubkey.h
sipa
@instagibbs instagibbs Jul 14, 2020
Is this for simply catching assertion condition?
Outdated
src/script/interpreter.cpp
sipa
@instagibbs instagibbs Jul 14, 2020
`s/32/hash.size()/` if you don't mind
Outdated
src/hash.cpp
sipa
@maflcko maflcko May 2, 2020
``` test/functional/test_framework/address.py:10:1: F401 '.script.hash256' imported but unused
Outdated
test/functional/test_framework/address.py
sipa
@jnewbery jnewbery Mar 28, 2020
Is this just a duplicate of `WITNESS_V1_TAPROOT_SIZE`? It's only used once in `VerifyWitnessProgram()`. Can we replace that usage with `WITNESS_V1_TAPROOT_SIZE`?
Outdated
src/script/interpreter.h
sipa jnewbery
@jnewbery jnewbery Mar 28, 2020
nit: could these two bools be replaced with an `Optional<bool>`? Optional is std from c++17 but currently implemented using boost::optional. Do we prefer to keep that out of consensus code?
src/script/interpreter.h
instagibbs sipa
@jnewbery jnewbery Mar 24, 2020
should `stack.front()` be preferred over `stack[0]`?
Outdated
src/script/interpreter.cpp
sipa
@Empact Empact Mar 21, 2020
nit: I'm not 100% clear on our`include` guidelines - `string` is included via `hash.h`, so if that's sufficient this line is unnecessary, if that's not sufficient, then we should also include `uint256.h`, etc here.
src/hash.cpp
kallewoof
@pinheadmz pinheadmz Feb 26, 2020
Is the P2SH check necessary here? There is a test for `prevScript.IsWitnessProgram()` a few lines up, is there anyway the script could still be P2SH at this point? Or should this actually test `prev.scriptPubKey.IsPayToScriptHash()` which is the actual previous TX output script, defined before `prevScript` is updated to the redeem script.
Outdated
src/policy/policy.cpp
sipa
@kallewoof kallewoof Jan 30, 2020
I believe this should be called `SignatureHashSchnorr` and be `<typename T>` to match `interpreter.cpp` v.
Outdated
src/script/interpreter.h
sipa
@kallewoof kallewoof Jan 28, 2020
If someone does `txdata = PrecomputedTransactionData(tx);` and then later tries to do `txdata.Init(tx, spent_outputs);` this line will terminate, despite `m_amounts_spent_ready` not being updated based on the new spent_outputs. Perhaps ```C++ if (ready && spent_outputs.empty()) return; ``` Edit: maybe even split into `if !ready, make hashes` and `if !m_amounts_spend_ready`, do spent stuff. (also fixed description; m_spent_outputs is updated, but the bool is not)
Outdated
src/script/interpreter.cpp
sipa
@kallewoof kallewoof Jan 28, 2020
This assertion will be hit, because `cache` is null when using the below constructor: https://github.com/bitcoin/bitcoin/blob/b8048b814821913b1f4c1c2070ec68b0c9001ec8/src/script/interpreter.h#L258 Maybe checking if txdata is non-null and complain if it isn't, at https://github.com/bitcoin/bitcoin/blob/b8048b814821913b1f4c1c2070ec68b0c9001ec8/src/script/interpreter.cpp#L1638
Outdated
src/script/interpreter.cpp
sipa kallewoof
@constcast-glitch constcast-glitch Jan 26, 2020
I believe "If the this nonce function ..." should be "If this nonce function ...".
Outdated
src/secp256k1/src/secp256k1.c
constcast-glitch gmaxwell
@JeremyRubin JeremyRubin Jan 25, 2020
I'm generally not a fan of these Data interfaces which have all the bool x_init fields. As an alternative, we could use an optional type wrapper. However, optional types depend on boost until c++17, which we shouldn't introduce consensus dependencies on. My proposal would be to copy the definition of c++17 optional into https://github.com/bitcoin/bitcoin/blob/99813a9745fe10a58bedd7a4cb721faf14f907a4/src/optional.h and drop the boost dependency, and then use this here. This can be done as a PR separate from Taproot so as not to further burden this PR. Here, optionals express both the nothing set and not initialized state (hence dual-wrapped options) but perhaps we'd be OK in collapsing the wrapped ones to represent (not initialized or not set) OR value. ```c++ struct ScriptExecutionData { //! The tapleaf hash. Option<uint256> m_tapleaf_hash; Option<Option<uint32_t>> m_codeseparator_pos; //! Hash of the annex data, if any Option<Option<uint256>> m_annex_hash; /** How much validation weight is left (decremented for every successful signature check). */ Option<int64_t> m_validation_weight_left; }; ``` This would seem, to me, to make the interface quite a bit safer and eliminates a bunch of initialization logic & prevents UB from cropping up. It would also be, in my opinion, a larger project (perhaps worthwhile) to generally rethink this state object to be accessed through an interface that guarantees the fields are accessed correctly -- e.g., once a m_validation_weight_left is set it can only be read or decreased, and the function to decrease can set error if the condition isn't met on underflow. Maybe not worth that large of a refactor though, I think optionals would already be an improvement.
src/script/interpreter.h
sipa elichai
StEvUgnIn
@JeremyRubin JeremyRubin Jan 25, 2020
UB nit: while this is safe, I believe, as it is used, it would be better to initialize this to either true or false should there be a bug, it would at least not invoke UB.
src/script/interpreter.h
JeremyRubin sipa
@JeremyRubin JeremyRubin Jan 25, 2020
documentation nit: preference to not use -1 to indicate a sentinel for a unsigned type.
Outdated
src/script/interpreter.h
sipa
@kallewoof kallewoof Jan 25, 2020
Nit: indentation (here and L1781).
Outdated
src/script/interpreter.cpp
sipa
@kallewoof kallewoof Jan 25, 2020
```suggestion from test_framework.script import ( ANNEX_TAG, CScript, CScriptOp, LEAF_VERSION_TAPSCRIPT, LOCKTIME_THRESHOLD, MAX_SCRIPT_ELEMENT_SIZE, OP_0, OP_1, OP_1SUB, OP_1NEGATE, OP_2DROP, OP_2DUP, OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY, OP_CHECKSIG, OP_CHECKSIGADD, OP_CHECKSIGVERIFY, OP_CODESEPARATOR, OP_DROP, OP_DUP, OP_ELSE, OP_ENDIF, OP_EQUAL, OP_IF, OP_NOT, OP_NOTIF, OP_RETURN, OP_SWAP, OP_VERIF, SIGHASH_SINGLE, TaprootSignatureHash, is_op_success, taproot_construct, ) ```
Outdated
test/functional/feature_taproot.py
sipa kallewoof
@constcast-glitch constcast-glitch Jan 23, 2020
nit: This function (VerifyECDSASignature) is formatted different than VerifySchnorrSignature which have the single line if-statements on one line. Maybe use same formatting for consistency since the functions are very similar in layout. I guess it's because this function already existed and don't want to make unrelated formatting changes. New here so not sure if this is a valid remark. Please excuse me if so.
src/script/sigcache.cpp
sipa
@jnewbery jnewbery Jan 23, 2020
Should these be updated to be BIP schnorr pubkeys (32-byte arrays)?
Outdated
test/functional/feature_taproot.py
sipa
@v1048576 v1048576 Jan 23, 2020
Why not check against opcode defines?
src/script/script.cpp
v1048576 sipa
gmaxwell
@v1048576 v1048576 Jan 23, 2020
Use taproot instead of tap? SIGHASH_TAPROOT_DEFAULT TAPROOT like other instances, e.g. TAPROOT_PROGRAM_SIZE. Also, SignatureHashTap() renamed to SignatureHashTaproot()? Similar to VerifyTaprootCommitment.
Outdated
src/script/interpreter.h
sipa
@jnewbery jnewbery Jan 22, 2020
This seems weird to me. How can we verify a signature for a point which does not have a square Y? Such public keys are not defined in bip-schnorr. I think it'd be clearer to assert that the pubkey has a square Y before verifying. I'd also suggest adding a `get_xonly_pubkey()` method to `ECKey` so we can directly get the valid bip-schnorr pubkey.
Outdated
test/functional/test_framework/key.py
sipa jnewbery
real-or-random
@Empact Empact Jan 22, 2020
nit: a `NONE_EXECUTED` constant would be expressive
src/script/interpreter.cpp
sipa Empact
gmaxwell
@Empact Empact Jan 22, 2020
nit: how about `!= sizeof(((secp256k1_schnorrsig){0}).data)`, a `static_assert`, or similar?
Outdated
src/pubkey.cpp
sipa gmaxwell
Empact
@Empact Empact Jan 22, 2020
~~nit: `stack.back()`~~ Neglected to examine the full context.
Outdated
src/policy/policy.cpp
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion # Tapscript ```
Outdated
test/functional/test_framework/script.py
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion // How much weight budget is added to the witness size (Tapscript only). ```
Outdated
src/script/script.h
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion // Validation weight per passing signature (Tapscript only). ```
Outdated
src/script/script.h
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion // Making unknown public key versions in Tapscript non-standard ```
Outdated
src/script/interpreter.h
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion /** The maximum size of each witness stack item in a standard Tapscript */ ```
Outdated
src/policy/policy.h
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion // Leaf version 0xc0 (aka Tapscript, see BIP 342) ```
Outdated
src/policy/policy.cpp
sipa
@Empact Empact Jan 22, 2020
nit: is it clearer to use or comment e.g. `WITNESS_V0`, and `TAPROOT` below?
Outdated
src/script/interpreter.cpp
sipa
@Empact Empact Jan 22, 2020
nit: Perhaps more readable if we avoid magic numbers with something like: ```c++ static_assert(SIGHASH_TAPOUTPUTMASK < SIGHASH_TAPINPUTMASK); if ((hash_type > SIGHASH_TAPOUTPUTMASK) && (hash_type <= SIGHASH_TAPINPUTMASK || hash_type > (SIGHASH_TAPINPUTMASK | SIGHASH_TAPOUTPUTMASK))) return false; ``` Alternatively, a comment could be helpful.
Outdated
src/script/interpreter.cpp
sipa gmaxwell
@nopara73 nopara73 Jan 22, 2020
Unify Taproot capitalization in comments. ```suggestion # Test Taproot softfork. ```
Outdated
test/functional/feature_taproot.py
sipa
@nopara73 nopara73 Jan 22, 2020
Unify Taproot capitalization in comments. ```suggestion # Don't use 32-byte v1 witness (used by Taproot) ```
Outdated
test/functional/p2p_segwit.py
sipa
@nopara73 nopara73 Jan 22, 2020
Unify Taproot capitalization in comments. ```suggestion // Taproot ```
Outdated
src/script/script.h
sipa
@nopara73 nopara73 Jan 22, 2020
Unify Taproot capitalization in comments. ```suggestion // Taproot ```
Outdated
src/script/script.cpp
sipa
@nopara73 nopara73 Jan 22, 2020
Unify Taproot capitalization in comments. ```suggestion // Making unknown Taproot leaf versions non-standard ```
Outdated
src/script/interpreter.h
sipa
@nopara73 nopara73 Jan 22, 2020
Unify Taproot capitalization in comments. ```suggestion DEPLOYMENT_TAPROOT, // Deployment of Taproot (BIPs 340-342) ```
Outdated
src/consensus/params.h
nopara73 sipa
@Empact Empact Jan 22, 2020
nit: `reinterpret_cast<unsigned char*>(const_cast<char*>(`? The `const_cast` could be removed with C++17 and a switch to rvalue references.
Outdated
src/hash.cpp
sipa
@constcast-glitch constcast-glitch Jan 22, 2020
taghash is written twice. Is this intentional?
src/hash.cpp
sipa
@skwp skwp Jan 22, 2020
why nested conditional here, but not nested above (line 240)? both branches have "stack_size >= 2" as well. without understanding what any of this means, would it be clearer to write like this, removing the duplication and nesting? ``` // precondition for taproot (?) if (stack_size < 2) { return } if (!stack[stack_size - 1].empty() && stack[stack_size - 1][0] == ANNEX_TAG) { // whatever this is } else if ((stack[stack_size - 1][0] & 0xfe) == 0xc0)) { // script path spend } ```
Outdated
src/policy/policy.cpp
sipa skwp
@skwp skwp Jan 22, 2020
Is there a name for this condition that can be explained with a function name or at least a comment?
Outdated
src/policy/policy.cpp
sipa skwp
kallewoof
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion if (!noncefp(buf, msg32, seckey_tmp, (unsigned char *) "BIP340Derive", (void*)ndata, 0)) { ``` Not sure if this breaks anything :confused:
Outdated
...p256k1/src/modules/schnorrsig/main_impl.h
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion noncefp = secp256k1_nonce_function_bip-340; ``` Not sure if this breaks anything :confused:
Outdated
...p256k1/src/modules/schnorrsig/main_impl.h
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion * noncefp: pointer to a nonce generation function. If NULL, secp256k1_nonce_function_bip340 is used ``` Not sure if this breaks anything? :confused:
Outdated
src/secp256k1/include/secp256k1_schnorrsig.h
MaxHillebrand sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion * (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). ``` This link is broken until the [BIP PR](https://github.com/bitcoin/bips/pull/876/) is merged.
Outdated
src/secp256k1/include/secp256k1_schnorrsig.h
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion """Construct a BIP-340 compatible Schnorr signature with this key.""" ```
Outdated
test/functional/test_framework/key.py
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion * BIP-340 ```
Outdated
src/secp256k1/include/secp256k1_schnorrsig.h
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion /** Return a CHashWriter primed for computing BIP-340 compatible tagged hashes. ```
Outdated
src/hash.h
sipa
@MaxHillebrand MaxHillebrand Jan 22, 2020
```suggestion DEPLOYMENT_TAPROOT, // Deployment of BIP-340/BIP-341/BIP-342 ```
Outdated
src/consensus/params.h
sipa
@kallewoof kallewoof Jan 22, 2020
`s/TESTDUMMY/TAPROOT/` here and in testnet (regtest is fine). Also think you want to set timeout to something less expired.
Outdated
src/chainparams.cpp
sipa kallewoof
@junderw junderw Jan 22, 2020
Slightly confusing name... `HashAgainSHA256`? I understand why it exists, and I can't think of a much better name... but having something in the name to denote we're hashing with SHA256 might make it a tiny bit more readable.
Outdated
src/script/interpreter.cpp
sipa