Conversation
Contributor
Author
|
@achow101 as BIP174's author, could you take a look? In short: the "invalid output witnessScript typed key" vector is meant to fail on the key length alone, but the pushed key in its witnessScript is not a point on secp256k1, so an implementation that validates the key and skips the length check rejects the case for the wrong reason and the missing check goes unnoticed. This swaps in a valid point; nothing else changes and CI is green. |
The "PSBT with invalid output witnessScript typed key" case tests one
condition: a PSBT_OUT_WITNESS_SCRIPT key longer than the one octet the
type is. Its last record, key length included, is
21 010025512103b7ce...51309d 06 d57f8a8751ae
Read as a stream, the witnessScript is
OP_1 <03b7ce23...51309d06d57f8a87> OP_1 OP_CHECKMULTISIG
and x^3 + 7 is not a square mod p for that x: the pushed key is not a
point of secp256k1.
An implementation that checks the pushed key but not the key length
refuses the case for the wrong reason and the missing check goes
undetected.
65f0b3d replaced 2b with 06 to make the value length consistent:
with 2b it is 43 where 7 octets remain, and a reader that takes the
whole key-value pair before judging the key hits a short read. That
octet is the 29th of the pushed key.
The case commits to the key with 2b. sha256 of that script is
876bad83...2b278a65, the P2WSH the output's redeemScript pushes, and
hash160 of that redeemScript is b921b1ba...6a42ec83, the P2SH
scriptPubKey of the unsigned transaction's second output. The script as
it reads today hashes to bcea4f01...fbb21dc8, which nothing in the case
commits to. Another point in its place would mean recomputing both
hashes and the unsigned transaction; keeping it means moving the value
length off it.
The record below does that, carrying the extra octet in the key and the
whole script in the value, as the "invalid output redeemScript typed
key" case does.
02 0100 25 512103b7ce...2bd57f8a8751ae
Same length as now, same failure, and the first 222 of the 264 octets
unchanged.
fametrano
force-pushed
the
bip174-witnessscript-vector-pubkey
branch
from
September 12, 2026 12:34
e0d51f1 to
d389ceb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The "PSBT with invalid output witnessScript typed key" case should fail on the key length — a
PSBT_OUT_WITNESS_SCRIPTkey longer than one octet — but as written it can also fail on an off-curve pubkey: the witnessScript pushes03b7ce…9d06d5…, andx**3 + 7is not a square mod p for that x. An implementation that validates pushed keys but never checks the key length rejects the case anyway, for the wrong reason, and the missing check goes undetected.The off-curve key is an artifact: 65f0b3d changed one octet of it (
2b→06) to fix a short read on the value length, but the case's hashes (P2WSH876bad83…, P2SHb921b1ba…) still commit to the script with2b.This re-encodes the record as
02 0100 25 <script with 2b>— the extra octet in the key, the whole on-curve script in the value, as the "invalid output redeemScript typed key" case already does. Same total length, same intended failure, hashes match again; bitcoin/bitcoin'srpc_psbt.jsonstill carries the pre-65f0b3dd octets (a short read), so this encoding serves both.