From 346f93844f9b7dc1df184edd7383f5cca5e0c02e Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Tue, 12 May 2026 07:06:15 -0400 Subject: [PATCH 1/6] bip-0054: spell out in more places that 64 bytes is for witness-stripped size --- bip-0054.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bip-0054.md b/bip-0054.md index c2ce09f383..3df8b44135 100644 --- a/bip-0054.md +++ b/bip-0054.md @@ -38,10 +38,10 @@ users, increasing the cost to independently fully validate the consensus rules. be used by miners to attack their competition, creating perverse incentives, centralization pressures and leading to reduced network security. -In computing a block's Merkle root, a 64-byte transaction can be interpreted both as an intermediate -node in the tree and as a leaf in the tree. This makes it possible to fake inclusion proofs by -pretending a 64-byte block transaction is an inner node, as well as to pretend the inner nodes on -one level of the tree are the actual block transactions. +In computing a block's Merkle root, a transaction with exactly 64 bytes of non-witness data can be +interpreted both as an intermediate node in the tree and as a leaf in the tree. This makes it +possible to fake inclusion proofs by pretending a 64-byte block transaction is an inner node, as +well as to pretend the inner nodes on one level of the tree are the actual block transactions. Since [bip-0034][BIP34] activation, explicit [bip-0030][BIP30] validation is not necessary until block height 1,983,702[^0]. Mandating new coinbase transactions be different from the early @@ -146,7 +146,7 @@ Bitcoin Core version [30.0][Core 30.0] and later will not generate a block templ transaction that violates the signature operations limit introduced in this BIP. Bitcoin Core version [0.16.1][Core 0.16.1] and later will neither relay nor create block templates -that include 64-byte transactions. +that include transactions whose witness-stripped serialized size is exactly 64 bytes. The coinbase transaction is usually crafted by mining pool software. To the best of the authors' knowledge, there does not exist an open source reference broadly in use today for such software. From 5c67f90fa81cdf4ab4a955b2a11f54a4727fef88 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Thu, 14 May 2026 09:04:36 -0400 Subject: [PATCH 2/6] bip-0054: clarify rationale for invalidating 64-byte txs As Eric points out on the mailing list: 1. the rationale section should mention and address the "seam" objection directly rather than burying it in a footnote; 2. the full node consensus split issue should not be used as sole rationale for invalidating 64-byte txs (but it's fair to point out it's fixed as a nice to have byproduct). ML thread: https://gnusha.org/pi/bitcoindev/43996cb3-9133-4627-8944-5fe08427be68n@googlegroups.com/T/#md66e252f0748f4ef7569d5e15d42631e12b66c0b, --- bip-0054.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/bip-0054.md b/bip-0054.md index 3df8b44135..0b856ab5f8 100644 --- a/bip-0054.md +++ b/bip-0054.md @@ -104,15 +104,18 @@ invalid[^7]. In the presence of 64-byte transactions a block header's Merkle root may be valid for different sets of transactions. This is because, in the Merkle tree construction, a 64-byte value may be -interpreted either as a transaction or as the concatenation of two 32-byte hashes. The former allows faking a block inclusion proof and the latter makes -it such that for a valid block the Merkle root in the block header is not a unique identifier for -the corresponding list of valid transactions[^8]. 64-byte transactions can only contain a -scriptPubKey that lets anyone spend the funds, or one that burns them. 64-byte transactions have -also been non-standard since 2019. It was suggested that the known vulnerabilities could instead be -mitigated by committing to the Merkle tree depth in the header's version field[^9]. The authors -believe it is preferable to address the root cause by invalidating 64-byte transactions. This -approach also fixes the vulnerability without developers of SPV verifiers having to implement the -mitigation or to know it is necessary in the first place. +interpreted either as a transaction or as the concatenation of two 32-byte hashes. Reinterpreting a +transaction as a node allows creating a valid Merkle proof for a transaction not included in a +block. 64-byte transactions can only contain a scriptPubKey that lets anyone spend the funds, or one +that burns them. 64-byte transactions have also been non-standard since 2019 and unused since 2016. +It was suggested that the known vulnerabilities could instead be mitigated by committing to the +Merkle tree depth in the header's version field[^8], to avoid introducing a "seam". The authors +believe it is preferable to address the root cause by invalidating 64-byte transactions, fixing the +vulnerability without developers of SPV verifiers having to implement the mitigation or to know it +is necessary in the first place. See [this post][64 bytes debate] for an attempt at summarizing the +arguments for both sides of this debate. Reinterpreting Merkle tree nodes as transactions could be +used to cause a vulnerable node to fall out of consensus[^9]. There are better ways to mitigate this +issue on its own, but it is also addressed as a byproduct of invalidating 64-byte transactions. Several blocks prior to [bip-0034][BIP34] activation contain a coinbase transaction whose scriptSig contains a valid [bip-0034][BIP34] commitment to a future block height. This offers an opportunity @@ -207,11 +210,10 @@ standard transaction size before running into the newly introduced limit. To run introduced limit but not the transaction size a transaction would need to spend P2SH inputs with a redeem script similar to `CHECKSIG DROP CHECKSIG DROP ...`. This type of redeem script serves no purpose beyond increasing its validation cost, which is exactly what this proposal aims to mitigate. -[^8]: See [this writeup][Suhas Merkle] by Suhas Daftuar for an explanation as well as a discussion -of the consequences. -[^9]: By Sergio Demian Lerner in a [blog post][Sergio post] surfaced [by Eric Voskuil][Eric -version]. Eric also pushed back against the importance of fixing this issue. See [this post][64 -bytes debate] for an attempt at summarizing the arguments for both sides of this debate. +[^8]: By Sergio Demian Lerner in a [blog post][Sergio post] surfaced [by Eric Voskuil][Eric +version]. +[^9]: Bitcoin Core versions between 0.13.0 and 0.13.2 implemented caching that made it vulnerable to +this attack. See [this writeup][Suhas Merkle] by Suhas Daftuar for a detailed explanation. [^10]: See [here][BIP34 list] for a full list of the heights of historical blocks including a valid bip-0034 height commitment and the corresponding future block height. [^11]: Technically it could be argued a duplicate could in principle always be possible before block From 8ae3af58e0503c8f0dd5ac2be924c6a4dcb7fbdd Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Fri, 15 May 2026 10:50:34 -0400 Subject: [PATCH 3/6] bip-0054: state explicitly fake inclusion proofs only concern SPV verifier --- bip-0054.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bip-0054.md b/bip-0054.md index 0b856ab5f8..5734da1427 100644 --- a/bip-0054.md +++ b/bip-0054.md @@ -40,8 +40,10 @@ pressures and leading to reduced network security. In computing a block's Merkle root, a transaction with exactly 64 bytes of non-witness data can be interpreted both as an intermediate node in the tree and as a leaf in the tree. This makes it -possible to fake inclusion proofs by pretending a 64-byte block transaction is an inner node, as -well as to pretend the inner nodes on one level of the tree are the actual block transactions. +possible to trick an SPV verifier into accepting an inclusion proof for a transaction that is not +part of a block, by pretending a 64-byte block transaction is actually an inner node. Invalidating +64-byte transactions addresses this vulnerability without requiring users of SPV verifiers to deploy +one of the available mitigations, or even to know one is necessary in the first place. Since [bip-0034][BIP34] activation, explicit [bip-0030][BIP30] validation is not necessary until block height 1,983,702[^0]. Mandating new coinbase transactions be different from the early From 47a2d725390a28d8fee0132bbba28e6ad7f6986f Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Fri, 15 May 2026 11:09:46 -0400 Subject: [PATCH 4/6] bip-0054: less redundancy in 64-byte rationale, move caching risk to footnote --- bip-0054.md | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/bip-0054.md b/bip-0054.md index 5734da1427..2ac74c8d6d 100644 --- a/bip-0054.md +++ b/bip-0054.md @@ -41,7 +41,7 @@ pressures and leading to reduced network security. In computing a block's Merkle root, a transaction with exactly 64 bytes of non-witness data can be interpreted both as an intermediate node in the tree and as a leaf in the tree. This makes it possible to trick an SPV verifier into accepting an inclusion proof for a transaction that is not -part of a block, by pretending a 64-byte block transaction is actually an inner node. Invalidating +part of a block, by pretending a 64-byte block transaction is actually an inner node[^9]. Invalidating 64-byte transactions addresses this vulnerability without requiring users of SPV verifiers to deploy one of the available mitigations, or even to know one is necessary in the first place. @@ -104,20 +104,16 @@ increases the preparation cost of an attack, making it uneconomical for a miner[ 2500 was chosen as the tightest value that did not make any non-pathological standard transaction invalid[^7]. -In the presence of 64-byte transactions a block header's Merkle root may be valid for different sets -of transactions. This is because, in the Merkle tree construction, a 64-byte value may be -interpreted either as a transaction or as the concatenation of two 32-byte hashes. Reinterpreting a -transaction as a node allows creating a valid Merkle proof for a transaction not included in a -block. 64-byte transactions can only contain a scriptPubKey that lets anyone spend the funds, or one -that burns them. 64-byte transactions have also been non-standard since 2019 and unused since 2016. -It was suggested that the known vulnerabilities could instead be mitigated by committing to the -Merkle tree depth in the header's version field[^8], to avoid introducing a "seam". The authors -believe it is preferable to address the root cause by invalidating 64-byte transactions, fixing the -vulnerability without developers of SPV verifiers having to implement the mitigation or to know it -is necessary in the first place. See [this post][64 bytes debate] for an attempt at summarizing the -arguments for both sides of this debate. Reinterpreting Merkle tree nodes as transactions could be -used to cause a vulnerable node to fall out of consensus[^9]. There are better ways to mitigate this -issue on its own, but it is also addressed as a byproduct of invalidating 64-byte transactions. +64-byte transactions can only contain a scriptPubKey that lets anyone spend the funds, or one that +burns them. They have also been non-standard since 2019 and never been used since 2016. Several +alternatives to invalidating them were previously proposed. Some believe the improvements for users +of Merkle proofs are too marginal to be worth introducing a discontinuity in the set of valid +witness-stripped transaction sizes. Others have suggested that the known vulnerabilities could +instead be mitigated by committing to the Merkle tree depth in the header's version field[^8]. The +authors believe it is preferable to address the root cause by invalidating 64-byte transactions, +fixing the vulnerability without developers of SPV verifiers having to implement the mitigation or +to know it is necessary in the first place. See [this post][64 bytes debate] for an attempt at +summarizing the arguments for both sides of this debate. Several blocks prior to [bip-0034][BIP34] activation contain a coinbase transaction whose scriptSig contains a valid [bip-0034][BIP34] commitment to a future block height. This offers an opportunity @@ -212,10 +208,14 @@ standard transaction size before running into the newly introduced limit. To run introduced limit but not the transaction size a transaction would need to spend P2SH inputs with a redeem script similar to `CHECKSIG DROP CHECKSIG DROP ...`. This type of redeem script serves no purpose beyond increasing its validation cost, which is exactly what this proposal aims to mitigate. -[^8]: By Sergio Demian Lerner in a [blog post][Sergio post] surfaced [by Eric Voskuil][Eric -version]. -[^9]: Bitcoin Core versions between 0.13.0 and 0.13.2 implemented caching that made it vulnerable to -this attack. See [this writeup][Suhas Merkle] by Suhas Daftuar for a detailed explanation. +[^8]: By Sergio Demian Lerner in a [blog post][Sergio post]. +[^9]: Conversely, pretending that the inner nodes on one level of the tree are the actual block +transactions is another source of complexity for full node implementations, which previously +resulted in consensus bugs. For instance, Bitcoin Core versions between 0.13.0 and 0.13.2 +implemented caching that made it vulnerable to this attack. See [this writeup][Suhas Merkle] by +Suhas Daftuar for a detailed explanation. Invalidating 64-byte transactions may avoid this risk, but +the issue is largely orthogonal to this proposal: it is fundamentally about caching validation +status for malleable blocks. [^10]: See [here][BIP34 list] for a full list of the heights of historical blocks including a valid bip-0034 height commitment and the corresponding future block height. [^11]: Technically it could be argued a duplicate could in principle always be possible before block @@ -242,7 +242,6 @@ have to be perpetuated for the Consensus Cleanup. [ML thread validation time]: https://gnusha.org/pi/bitcoindev/VsltJ2PHqWfzG4BU9YETTXjL7fYBbJhjVXKZQyItemySIA1okvNee9kf0zAOyLMeJ4Nqv1VOrYbWns5nP4TANCWvPJYu1ew_yxQSaudizzk=@protonmail.com [Suhas Merkle]: https://gnusha.org/pi/bitcoindev/CAFp6fsGtEm9p-ZQF_XqfqyQGzZK7BS2SNp2z680QBsJiFDraEA@mail.gmail.com [Sergio post]: https://bitslog.com/2018/06/09/leaf-node-weakness-in-bitcoin-merkle-tree-design -[Eric version]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/37 [64 bytes debate]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/41 [BIP34 list]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/4 [Harding nLockTime]: https://bitcoin.stackexchange.com/questions/90229/nlocktime-in-bitcoin-core From 9e8e357b0388d532e277e03b0bf372b39fedcc44 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Sun, 17 May 2026 17:09:11 -0400 Subject: [PATCH 5/6] bip-0054: disambiguate use of "mitigation" Jon pointed that i use "mitigation" to refer both to the items of this BIP, and for the existing workarounds to make SPV verifiers safe in the presence of 64-byte txs. This commit rephrases the latter usage. --- bip-0054.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/bip-0054.md b/bip-0054.md index 2ac74c8d6d..3f6dcd95d7 100644 --- a/bip-0054.md +++ b/bip-0054.md @@ -42,8 +42,9 @@ In computing a block's Merkle root, a transaction with exactly 64 bytes of non-w interpreted both as an intermediate node in the tree and as a leaf in the tree. This makes it possible to trick an SPV verifier into accepting an inclusion proof for a transaction that is not part of a block, by pretending a 64-byte block transaction is actually an inner node[^9]. Invalidating -64-byte transactions addresses this vulnerability without requiring users of SPV verifiers to deploy -one of the available mitigations, or even to know one is necessary in the first place. +64-byte transactions addresses this vulnerability without requiring users of SPV verifiers, or +any other user of Merkle proofs, to rely on one of the available workarounds or even to know one is +necessary in the first place. Since [bip-0034][BIP34] activation, explicit [bip-0030][BIP30] validation is not necessary until block height 1,983,702[^0]. Mandating new coinbase transactions be different from the early @@ -108,12 +109,12 @@ invalid[^7]. burns them. They have also been non-standard since 2019 and never been used since 2016. Several alternatives to invalidating them were previously proposed. Some believe the improvements for users of Merkle proofs are too marginal to be worth introducing a discontinuity in the set of valid -witness-stripped transaction sizes. Others have suggested that the known vulnerabilities could -instead be mitigated by committing to the Merkle tree depth in the header's version field[^8]. The -authors believe it is preferable to address the root cause by invalidating 64-byte transactions, -fixing the vulnerability without developers of SPV verifiers having to implement the mitigation or -to know it is necessary in the first place. See [this post][64 bytes debate] for an attempt at -summarizing the arguments for both sides of this debate. +witness-stripped transaction sizes. Others have suggested instead committing to the Merkle +tree depth in the header's version field[^8], which would make one workaround for a known +vulnerability easier to deploy. The authors believe it is preferable to address the root cause by +invalidating 64-byte transactions, fixing the vulnerability without Merkle proof users having to +rely on any workaround or even know one is necessary in the first place. See [this post][64 bytes +debate] for an attempt at summarizing the arguments for both sides of this debate. Several blocks prior to [bip-0034][BIP34] activation contain a coinbase transaction whose scriptSig contains a valid [bip-0034][BIP34] commitment to a future block height. This offers an opportunity From f1f1c36ff24157c6c7de698a90fa3fff4ab8b337 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Sun, 17 May 2026 17:43:21 -0400 Subject: [PATCH 6/6] bip-0054: add a footnote with known workarounds for SPV verifiers --- bip-0054.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/bip-0054.md b/bip-0054.md index 3f6dcd95d7..7eb277f02f 100644 --- a/bip-0054.md +++ b/bip-0054.md @@ -43,7 +43,7 @@ interpreted both as an intermediate node in the tree and as a leaf in the tree. possible to trick an SPV verifier into accepting an inclusion proof for a transaction that is not part of a block, by pretending a 64-byte block transaction is actually an inner node[^9]. Invalidating 64-byte transactions addresses this vulnerability without requiring users of SPV verifiers, or -any other user of Merkle proofs, to rely on one of the available workarounds or even to know one is +any other user of Merkle proofs, to rely on one of the available workarounds[^13] or even to know one is necessary in the first place. Since [bip-0034][BIP34] activation, explicit [bip-0030][BIP30] validation is not necessary until @@ -228,6 +228,13 @@ notably of Bitcoin Core but also of all other implementations the authors are aw where [bip-0034][BIP34] violations have been manually inspected (see [here][Core validation.cpp BIP34]). Without the guarantee given by enforcing the timelock on coinbase transactions, this would have to be perpetuated for the Consensus Cleanup. +[^13]: The authors are aware of three workarounds for SPV verifiers. The first is to request a +Merkle proof for the coinbase transaction in addition to the transaction of interest, to infer the +depth of the Merkle tree. The second is to reject Merkle proofs in which any inner node is also a +valid serialisation of a Bitcoin transaction. More details about these are available [here][Sergio +post]. A third workaround is to change the Merkle proof structure by requiring inner nodes to be +provided as the single-SHA256 of their preimage, instead of the double-SHA256. See [here][Sergio +MERKLEBLOCK] for a full description. [BIP30]: https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki [BIP-XXXX]: https://github.com/TheBlueMatt/bips/blob/7f9670b643b7c943a0cc6d2197d3eabe661050c2/bip-XXXX.mediawiki @@ -243,6 +250,7 @@ have to be perpetuated for the Consensus Cleanup. [ML thread validation time]: https://gnusha.org/pi/bitcoindev/VsltJ2PHqWfzG4BU9YETTXjL7fYBbJhjVXKZQyItemySIA1okvNee9kf0zAOyLMeJ4Nqv1VOrYbWns5nP4TANCWvPJYu1ew_yxQSaudizzk=@protonmail.com [Suhas Merkle]: https://gnusha.org/pi/bitcoindev/CAFp6fsGtEm9p-ZQF_XqfqyQGzZK7BS2SNp2z680QBsJiFDraEA@mail.gmail.com [Sergio post]: https://bitslog.com/2018/06/09/leaf-node-weakness-in-bitcoin-merkle-tree-design +[Sergio MERKLEBLOCK]: https://bitslog.com/2018/08/21/simple-change-to-the-bitcoin-merkleblock-command-to-protect-from-leaf-node-weakness-in-transaction-merkle-tree/ [64 bytes debate]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/41 [BIP34 list]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/4 [Harding nLockTime]: https://bitcoin.stackexchange.com/questions/90229/nlocktime-in-bitcoin-core