Skip to content

Conversation

@cryptoquick
Copy link

This spent several months gathering feedback from the mailing list and from other advisors. This is hopefully polished enough to submit upstream.

Let me know if you have any questions or feedback, and of course feel free to submit suggestions.

Thank you for your time.

@cryptoquick cryptoquick marked this pull request as draft September 27, 2024 18:18
Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting (the question of resistance to quantum computing may have resurged lately with the publication of https://scottaaronson.blog/?p=8329, see also https://x.com/n1ckler/status/1839215426091249778).

@cryptoquick cryptoquick force-pushed the p2qrh branch 2 times, most recently from b6ed2c3 to d6d15ad Compare September 28, 2024 18:01
@jonatack
Copy link
Member

jonatack commented Oct 1, 2024

@cryptoquick Can you begin to write up the sections currently marked as TBD, along with a backwards compatibility section (to describe incompatibilities, severity, and suggest mitigations, where applicable/relevant)? We've begun to reserve a range of BIP numbers for this topic, pending continued progress here.

@jonatack jonatack added the PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author label Oct 9, 2024
@jonatack
Copy link
Member

@cryptoquick ping for an update here. Have you seen https://groups.google.com/g/bitcoindev/c/p8xz08YTvkw / https://github.com/chucrut/bips/blob/master/bip-xxxx.md? It may be interesting to review each other and possibly collaborate.

Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the efforts on this proposal, answered back most of my previous comments, of which most can be resolved (still see long vs short exposure attack wonder) and added more. I’m in the “Design” section so far.


Seeing that the idea is to have CRYSTALS-Dilithium and SPHINCS++ proposed as the concrete signature algorithms. I might start to hack on an implementation for FALCON, of which the sigs size are smaller than Dilithium while being also lattice-based cryptography. It’s an interesting thing to hack on. Libbitcoinpqc is in C, so perfect.


This document is licensed under the 3-clause BSD license.

=== Motivation ===
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By comparison BIP340 is reasonably wordily on the security properties of the standardized signature scheme:
https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki

See the arguments on provable security, non-malleability and linearity.

I’m not sure if you’re really familiar with post-quantum cryptography (e.g https://arxiv.org/pdf/1710.10377 is a good starter), though there are really few papers doing cryptanalysis of quantum signature scheme in the Bitcoin setting. While of course one can object why it matters to do cryptanalysis i_n the Bitcoin setting_, one should remind itself that some argued property in ECC literature (e.g signature non-malleability) might have tremendous downsides if not well understood (e.g breaking BIP141 “trust-free unconfirmed transaction dependency chain”).

That’s the “motivation” section is for now very drafty and over-verbose, sure but that why it’s still a draft.

Comment on lines 134 to 138
* P2PK outputs (Satoshi's coins, CPU miners, starts with 04)
* Reused addresses (any type, except P2QRH)
* Taproot addresses (starts with bc1p)
* Extended public keys, commonly known as "xpubs"
* Wallet descriptors
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments there on trying to define “long exposure” vs “short exposure” attacks:
https://github.com/bitcoin/bips/pull/1670/files#r1966885340


It's for the above reason that, for those who wish to be prepared for quantum emergency, it is recommended that no more
than 50 bitcoin are kept under a single, distinct, unused Native SegWit (P2WPKH, "bc1q") address at a time. This is
assuming that the attacker is financially motivated instead of, for example, a nation state looking to break confidence
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a small side-note, SWIFT network also uses asymmetric cryptography for its operations:
https://www.swift.com/myswift/services/training/swift-training-catalogue/browse-swift-training-catalogue/swiftnet-public-key-infrastructure-pki

So in case of CRQC becoming a reality, it’s not only Bitcoin who is in shit, neither also central banks, but also the worldwide traditional payment system.

Mostly, it’s just making the observations that analyzing the economic impact and attacker (economical) rational is far from straightforward, as soon as we get out of our Bitcoin bubble.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SWIFT network itself typically lives on top of a VPN secured by symmetric keys (and some alrdy using PQC). So a bad actor needs to be one of the SWIFT whitelisted participants.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most banking and national computer networks are now starting projects to move to quantum resistant algorithms for KE and later for signing. They know it will take them a long time, but they are taking it seriously and inch by inch moving to mitigate it.

Taproot internal key, as it is not needed. Instead, a P2QRH output is just the 32-byte root of the tapleaf Merkle tree as defined
in [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP 341] and hashed with the tag "QuantumRoot" as shown below.

[[File:bip-0360/merkletree.png|center|550px|thumb|]]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The P2QRH scriptPubkey is saying SegWit version 3 ?

Shouldn’t be this SegWit version 2, given that BIP141 is SegWit version 0 and BIP341 is SegWit version 1.

Unless there is a social community convention somewhere, that we reserve SegWit version 2 for other purpose.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have already switched this to SegWit version 2, the updated BIP is just waiting on other revisions and hasn't been pushed yet. Sorry about that.

key in P2QRH the root is hashed by itself using the tag "QuantumRoot".

<source>
D = tagged_hash("TapLeaf", bytes([leaf_version]) + ser_script(script))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be tagged with “QuantumLeaf” or “QuantumBranch”.

Domain separation is a good thing.

Even in the case where a tapleaf validation is — all others things equal - the same between a P2TR and a P2QRH, preventing accidental misuage of a tapleaf by wallets or other bitcoin softwares among SegWit versions would be a good thing IMHO.

This is debatable, but somehow I think it’s good practice (— you wish to avoid a P2QRH spends being accidentally replayed on a P2TR and note the same signature digest than for BIP341/342 sounds to be proposed).

Copy link
Contributor

@EthanHeilman EthanHeilman Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate this question, let me give you my take and see if you agree.

If we could completely get away without domain separation I would do it, since P2QRH is tapscript and Tapleaf composed with a different output type. Ideally they should be swappable and the output type should not influence internal details like this. The intent of SegWit version should be specified in the SegWit version, having multiple places it needs to be specified does not enhance security but makes it more likely that someone will make a mistake since they need to get two things right rather than just one. A mistake here doesn't mean the user gets an error message, a mistake in mixing the Merkle tree domain separator with the wrong SegWit version means the output is probably unspendable.

Unfortunately P2QRH and P2TR are functionality different at the Merkle root and thus already we have domain separation there with "TapRoot" vs "QuantumRoot".

you wish to avoid a P2QRH spends being accidentally replayed on a P2TR and note the same signature digest than for BIP341/342 sounds to be proposed

I don't think such replays are possible with BIP-360 as currently written because the signature covers the domain separator at the root. Even if the Merkle trees were exactly the same, doesn't the signature cover the SegWit version as well?

can be used in a quantum resistant manner. In a future BIP, we enable tapscript programs to verify two Post-Quantum (PQ) signature
algorithms, ML-DSA (CRYSTALS-Dilithium) and SLH-DSA (SPHINCS+). It is important to consider these two changes together because P2QRH must
be designed to support the addition of these PQ signature algorithms. The full description of these signatures will be provided in a future BIP.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rational footnotes at the end of the document sounds good, like done for BIP340 or BIP341.

prudence dictates we take such risks seriously and ensure that Bitcoin always has at least two secure signature algorithms built
on orthogonal cryptographic assumptions. In the event one algorithm is broken, an alternative will be available. An added benefit
is that parties seeking to securely store Bitcoin over decades can lock their coins under multiple algorithms,
ensuring their coins will not be stolen even in the face of a catastrophic break in one of those signature algorithms.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A contrario, this is more cryptographic consensus code that have to be integrated, where any implementation bug might be fatal….

Personally, I think it’s worth the risk to have multiple signature schemes in case of advances in post-quantum cryptanalysis (it’s all quite unchartered paths here…), but I believe it might be more debatable among the community and the industry…

Copy link
Contributor

@EthanHeilman EthanHeilman Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for asking this @ariard It made me write up some ideas that have been motivating my work on BIP-360.

Which is worse for Bitcoin:

  • Accidental hardfork due to bug in consensus critical code,
  • Inability to authenticate ownership of the UTXO set due to signature forgery attack (maybe via a Quantum Computer, maybe because of a new development in number theory or maybe something else entirely)

I'd argue that Bitcoin can recover from an accidental hardfork, while some funds might be lost due to double spending on the different forks, there is a clear path to recovery: deploy a patch and reestablish consensus. However if there is break in ECC whereby anyone can forge Bitcoin signatures a large chunk of the UTXO set can not be authenticated as being owned by anyone. This is really really bad. How do you recover from this? Sure you can do proof of knowledge of public keys in P2SH outputs as long as those public keys haven't been used before, but an enormous chunk of the UTXO set is rendered unauthenticatable and we will never be able to cryptographically determine who owns those UTXOs. This includes outputs that reuse a public key or have otherwise leaked a public, all P2TR outputs, all P2PK outputs. This problem gets worse the more people adopt P2TR. As far as I can tell, this is the only security vulnerability that if discovered could actually destroy Bitcoin. The only defense is to implement a failover signature algorithm before the attack happens.

Bitcoin could survive SHA256 collisions or PoW being broken, simply port the UTXO set to a new protocol via a softfork that enforces a new PoW/additional hash function by rejecting blocks that doesn't include this additional data. A break in the signature scheme currently provides no easy recovery mechanism.

If we want to maximize the probability Bitcoin survives the next 50 or 100 years, providing a built in mechanism whereby Bitcoin can recover from a break in a single signature algorithm is the most effective security upgrade on the table. We need multiple signature algorithms to do this.

We already have two signature algorithms, ECDSA and ECC Schorr, but they are similar enough that break in one is likely to result in a break in the other as is the case for quantum attacks.

@moonsettler
Copy link

When can we review the updated version of BIP-360? As I understand, this is very outdated as is.

Any plans to allow for some form of "Post-Quantum cross-input signature aggregation"?

@EthanHeilman
Copy link
Contributor

EthanHeilman commented Nov 21, 2025

@moonsettler Working on it, should have updates soon

Any plans to allow for some form of "Post-Quantum cross-input signature aggregation"?

This BIP just describes a PQ output type, so this BIP should neither allow nor disallow cross-input signature aggregation. It is an important topic to consider for BIPs specifying the PQ CHECKSIG opcodes, but I'm not sure how exactly to handle it. More thought is needed.

@moonsettler
Copy link

Same script (address) aggregation could be handled on this level more efficiently instead of in script.

  • Somehow the address could encode that same script signature aggregation is enabled (skips execution with an empty witness if there is an other instance of the same script that executes?)
  • In which case we assume (or enforce?) that the PQ sig is of 'SIGHASH_ALL' type

|-
| [[bip-0360.mediawiki|360]]
| Consensus (soft fork)
| Pay-to-Tapscript-Hash (P2TSH)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the new title (that is also different from the PR title)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've completely rewritten the BIP and added another co-author

Those changes will be coming soon

@murchandamus
Copy link
Contributor

Given that you say that the content of this BIP is still in flux and will be completely overhauled soon, I’ll convert this PR to Draft for the time being. Please set it back to Ready for Review after pushing the changes.

* Start with NotMike contributions from #31

* Integrate changes and updates from the collaborative Google Doc for the rewrite.

* Mediawiki formatting updates.

* Grammar fixes

* Update bip-0360.mediawiki

Co-authored-by: Ethan Heilman <ethan.r.heilman@gmail.com>

* Remove links from header preformatted text.

* Apply suggestions from code review

Co-authored-by: Ethan Heilman <ethan.r.heilman@gmail.com>

* merkletree.svg: correct size of Merkle path in control block

Updates the vector file merkletree.svg.

* Render SVG to update merkletree PNG

* Apply suggestions from code review

Co-authored-by: Ethan Heilman <ethan.r.heilman@gmail.com>
Co-authored-by: notmike <notmike-5@users.noreply.github.com>

* Consistency on ellipses and hyphenation.

* Remove redeem script language.

* Address @notmike-5 feedback.

* Formatting and consistency fixes for Script Validation

* Language, consistency, and formatting fixes.

* Standardize terminology around taptree vs tapleaf Merkle tree.

* Add clarity to P2TSH Trade-Offs section.

* Update with more accurate language

---------

Co-authored-by: Ethan Heilman <ethan.r.heilman@gmail.com>
Co-authored-by: notmike <notmike-5@users.noreply.github.com>
@cryptoquick
Copy link
Author

The BIP 360 team is excited to share the following revisions aimed at enhancing clarity, readability and defining new terminology related to Bitcoin Quantum Resistance.

Key changes include:

  • Renaming for better alignment: Pay-to-Quantum-Resistant-Hash (P2QRH) has been renamed to Pay-to-Tapscript-Hash (P2TSH). This reflects the evolved design, which builds directly on Taproot mechanics by removing the quantum-vulnerable key-spend path while enabling flexible script commitments.
  • Substantial re-writes and edits: We've made extensive revisions throughout the document to improve readability, improve precision, and more clearly convey the authors' intent. These language revisions have largely been crafted by our new co-author, @Isabelfoxenduke.
  • Updated visuals: Added a new, improved diagram illustrating the Tapscript tree/Merkle root and scriptPubKey construction for better understanding of the output structure.
  • New glossary section: Introduced a brief glossary of key terms to make the BIP more accessible to reviewers and implementers.
  • Test vectors in Python and Rust
  • These refinements bring us closer to a robust, community-aligned proposal for addressing Bitcoin's long-term quantum resilience.

We'd love your feedback! Please review the latest version of the BIP:
https://github.com/cryptoquick/bips/blob/56be885cc9ba67b047e257df6692ab0c4290b294/bip-0360.mediawiki

Rendered view and details: https://bip360.org/ (will be updated soon!)

Please share your thoughts, suggestions, or concerns. Your input is invaluable in shaping this proposal.
Thank you to the community for your time and attention!
- The BIP 360 Team

@cryptoquick cryptoquick marked this pull request as ready for review December 19, 2025 18:35
@cryptoquick cryptoquick changed the title BIP-360: QuBit - Pay to Quantum Resistant Hash BIP 360 - Pay to Tapscript Hash (P2TSH) Dec 19, 2025
@cryptoquick
Copy link
Author

cryptoquick commented Dec 23, 2025

Just noticed that the test vectors have not yet been updated with the new P2TSH nomenclature. Most of us are taking time off this week but @jbride can get to it next week. Contributions welcome, as always.

The BIP itself however should be final and is ready for review.

@billymcbip
Copy link

billymcbip commented Dec 23, 2025

ACK, this is great work! I would highlight it earlier in the BIP that P2TSH is useful outside of the quantum-security context for script-only outputs.

* bip360: p2qrh -> p2tsh

* bip360: updating p2tsh end-to-end doc for signet

* bip360:  more updates to p2tsh end-to-end doc for signet

* bip360: signet miner utility

* bip360: introducing libbitcoinpqc

* bip360: extending p2tsh construction example to use SLH-DSA keypair

* bip360:

1.  change use of OP_SUCCESSx code from 80 -> 127
2.  now able to spend from a P2TSH utxo locked with a PQC enabled
    tapleaf script

* Using crates from self-hosted registry

* bip360: clarifications to p2tsh-end-to-end documentation

* bip360: introducing pqc enabled bdk_wallet dependencies

* bip360: workshop related utils

* bip360: workshop related documentation and Dockerfiles

* bip360:  updates to merkletree svg and png

* rust ref-impl:  now allowing for tap leaf scripts locked by both SCHNORR and SLH-DSA crypto

* bip360: first draft of typescript reference implementation

* bip360 / p2tsh:

1. Adding wasm based libbitcoinpqc example
2. Changing examples to use Schnorr
@cryptoquick
Copy link
Author

Test vectors have been updated. Let us know if you try them out!

Copy link
Contributor

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good read, it’s been a while since I read the prior version, but this feels like a big clean-up. I appreciate the brevity and clear focus.

I notice that the proposal introduces several idiosyncratic terms for established concepts. E.g., it uses “tapleaf”, “tapscript tree”, and “tapscript output” for the concepts introduced as “script leaf”, “script tree”, and “taproot output” in BIP 341. It would be preferable if the proposal were to use the established terms for established concepts instead of introducing new terminology.


The primary threat to Bitcoin from Cryptographically Relevant Quantum Computers (CRQCs) is their potential to break the key cryptographic assumption which secures the digital signatures used in Bitcoin.<ref>A Cryptographically Relevant Quantum Computer is an ''object'' which is only loosely defined by ''characteristics'' in quantum physics as of today. It could be understood in the context of this BIP and in Bitcoin that it's a ''hardware-agnostic'' computer supposed to have the architecture to keep ''coherent'' a sufficient number of logical qubits to be able to run Shor's algorithm in an efficient fashion.</ref> More specifically, [https://arxiv.org/pdf/quant-ph/0301141 Shor's algorithm] enables a CRQC to solve the Discrete Logarithm Problem (DLP) exponentially faster than classical methods.<ref>Shor's algorithm is believed to need 10^8 operations to break a 256-bit elliptic curve public key.</ref> This allows the derivation of private keys from public keys - a process referred to here as quantum key recovery.<ref>Meaning, deriving private keys from public keys via Shor's algorithm</ref> While it is unclear when or if CRQCs will become viable in the future, we propose the addition of a quantum-resistant, tapscript-native output type for those interested in this level of protection.

While some may balk at the potential threat of quantum computers to Bitcoin given their limited functionality to date, some others - including governments, corporations and some existing and potential Bitcoin users - are concerned about their potential for advancement. The Commercial National Security Algorithm Suite (CNSA) 2.0, for instance, has mandated software and networking equipment to be upgraded to post-quantum schemes by 2030, with browsers and operating systems fully upgraded by 2033. Additionally, according to NIST IR 8547, Elliptic Curve Cryptography (ECC) is planned to be disallowed within the US federal government after 2035 (with an exception made for hybrid cryptography, or the use of ECC and post-quantum algorithms together). These kinds of mandates have triggered concern by some ECC users, including some Bitcoin users who prefer to be prepared out of an abundance of caution.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you’re gonna make sub sentence constructions with em dashes, maybe use them em dashes. ;)

Suggested change
While some may balk at the potential threat of quantum computers to Bitcoin given their limited functionality to date, some others - including governments, corporations and some existing and potential Bitcoin users - are concerned about their potential for advancement. The Commercial National Security Algorithm Suite (CNSA) 2.0, for instance, has mandated software and networking equipment to be upgraded to post-quantum schemes by 2030, with browsers and operating systems fully upgraded by 2033. Additionally, according to NIST IR 8547, Elliptic Curve Cryptography (ECC) is planned to be disallowed within the US federal government after 2035 (with an exception made for hybrid cryptography, or the use of ECC and post-quantum algorithms together). These kinds of mandates have triggered concern by some ECC users, including some Bitcoin users who prefer to be prepared out of an abundance of caution.
While some may balk at the potential threat of quantum computers to Bitcoin given their limited functionality to date, some others including governments, corporations and some existing and potential Bitcoin users are concerned about their potential for advancement. The Commercial National Security Algorithm Suite (CNSA) 2.0, for instance, has mandated software and networking equipment to be upgraded to post-quantum schemes by 2030, with browsers and operating systems fully upgraded by 2033. Additionally, according to NIST IR 8547, Elliptic Curve Cryptography (ECC) is planned to be disallowed within the US federal government after 2035 (with an exception made for hybrid cryptography, or the use of ECC and post-quantum algorithms together). These kinds of mandates have triggered concern by some ECC users, including some Bitcoin users who prefer to be prepared out of an abundance of caution.


===Motivation===

The primary threat to Bitcoin from Cryptographically Relevant Quantum Computers (CRQCs) is their potential to break the key cryptographic assumption which secures the digital signatures used in Bitcoin.<ref>A Cryptographically Relevant Quantum Computer is an ''object'' which is only loosely defined by ''characteristics'' in quantum physics as of today. It could be understood in the context of this BIP and in Bitcoin that it's a ''hardware-agnostic'' computer supposed to have the architecture to keep ''coherent'' a sufficient number of logical qubits to be able to run Shor's algorithm in an efficient fashion.</ref> More specifically, [https://arxiv.org/pdf/quant-ph/0301141 Shor's algorithm] enables a CRQC to solve the Discrete Logarithm Problem (DLP) exponentially faster than classical methods.<ref>Shor's algorithm is believed to need 10^8 operations to break a 256-bit elliptic curve public key.</ref> This allows the derivation of private keys from public keys - a process referred to here as quantum key recovery.<ref>Meaning, deriving private keys from public keys via Shor's algorithm</ref> While it is unclear when or if CRQCs will become viable in the future, we propose the addition of a quantum-resistant, tapscript-native output type for those interested in this level of protection.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a “tapscript-native” output type? This appears to be a new term that I’m unfamiliar with and that is being used without definition.

Edit: Having reached the Glossary, I would also consider it sufficient to link to the definition there on the first use. That said, the term does strike me as somewhat odd: P2TR leaf scripts could be used with other leaf script versions in the future, e.g., making use of Simplicity, so the use of Tapscript in the script leaves does not necessarily seem to be the defining characteristic.


===Long Exposure vs Short Exposure Attacks===

For clarity, this proposal specifically mitigates against the risk of long exposure attacks on tapscript-native outputs. While other Bitcoin output types already mitigate against this risk, Tapscript outputs (P2TR output types) are vulnerable to long exposure quantum attacks.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don’t introduce new terms for concepts with established names, and please use only one term for the same concept. Especially it seems odd to emphasize the tapscript-use here, when the issue is the public key visible due to the taproot construction. I would suggest just talking about taproot outputs or P2TR outputs, since that seems to be what you mean.
Still confused by the newly introduced term “tapscript-native output”.

Suggested change
For clarity, this proposal specifically mitigates against the risk of long exposure attacks on tapscript-native outputs. While other Bitcoin output types already mitigate against this risk, Tapscript outputs (P2TR output types) are vulnerable to long exposure quantum attacks.
For clarity, this proposal specifically mitigates against the risk of long exposure attacks on taproot outputs. While other Bitcoin output types already mitigate against this risk, taproot outputs are vulnerable to long exposure quantum attacks.


For clarity, this proposal specifically mitigates against the risk of long exposure attacks on tapscript-native outputs. While other Bitcoin output types already mitigate against this risk, Tapscript outputs (P2TR output types) are vulnerable to long exposure quantum attacks.

A long exposure attack is an attack performed on exposed blockchain data, such as exposed public keys or the spend scripts of spent outputs. These are likely to be the earliest quantum attacks made possible on Bitcoin, because attackers will have ample time - as much time as vulnerable keys are exposed - to carry out quantum key recovery.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A long exposure attack is an attack performed on exposed blockchain data, such as exposed public keys or the spend scripts of spent outputs. These are likely to be the earliest quantum attacks made possible on Bitcoin, because attackers will have ample time - as much time as vulnerable keys are exposed - to carry out quantum key recovery.
A long exposure attack is an attack performed on exposed blockchain data, such as exposed public keys or the output scripts of spent outputs. These are likely to be the earliest quantum attacks made possible on Bitcoin, because attackers will have ample time as much time as vulnerable keys are exposed to carry out quantum key recovery.


* P2PK outputs (e.g. Satoshi's coins, CPU miners)
* Reused outputs*
* Tapscript outputs (starts with bc1p)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Tapscript outputs (starts with bc1p)
* Taproot outputs (starts with bc1p)

<source>
[count] (1 byte), # Number of elements in the witness
[size] signature (1 + 64 bytes = 65 bytes),
tapleaf script = [size] [OP_PUSHBYTES_32, 32-byte public key, OP_CHECKSIG] (1 + 1 + 32 + 1 bytes = 35 bytes),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tapleaf script = [size] [OP_PUSHBYTES_32, 32-byte public key, OP_CHECKSIG] (1 + 1 + 32 + 1 bytes = 35 bytes),
leaf script = [size] [OP_PUSHBYTES_32, 32-byte public key, OP_CHECKSIG] (1 + 1 + 32 + 1 bytes = 35 bytes),


Thus, the P2TSH witness would be 103 - 66 = 37 bytes larger than a P2TR key path spend witness.

If the Merkle tree has more than a single leaf, then the Merkle path must be included in the control block, increasing the size by ''32 * m'' bytes, where m is the depth of the Merkle tree. This would make such witness 37 + 32 * m bytes larger than a P2TR key path spend witness.<ref>If ''m >= 8'', then the compact size will use 3 bytes rather than 1 byte</ref>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaves in script trees can be at different depths, so the length of the Merkle path does not necessarily need to match the depth of the script tree, but depends on the depth of the script leaf that is being used to spend the output.

Comment on lines +291 to +294
==Performance Impact==

P2TSH is slightly more computationally performant than P2TR script path spends, as the operations to spend a P2TSH output is a strict subset of the operations needed to perform a script path spend on a P2TR output.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While theoretically correct, I cannot imagine this having real world impact or being relevant to readers.

Suggested change
==Performance Impact==
P2TSH is slightly more computationally performant than P2TR script path spends, as the operations to spend a P2TSH output is a strict subset of the operations needed to perform a script path spend on a P2TR output.


==Backward Compatibility==

Older wallets and nodes that have not been made compatible with SegWit version 2 and P2TSH will not recognize these outputs. Users should ensure they are using updated wallets and nodes to use P2TSH outputs and validate transactions using P2TSH outputs. P2TSH is fully compatible with tapscript and existing tapscript programs can be used in P2TSH outputs without modification.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that both BIP 350 and BIP 173 suggest that any implementers permit sending to future native segwit output types, so all spec-compliant implementations should be able to send to such outputs immediately, even if they cannot receive them and will not enforce the corresponding rules before upgrading.


==Security==

P2TSH outputs provide the same tapscript functionality as P2TR outputs, but with the quantum-vulnerable key path spend removed. The similarity between these output types enables users to easily migrate coins from P2TR outputs to P2TSH outputs for protection against long exposure quantum attacks.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that many users of P2TR outputs are using them only with a key path spending condition, this statement feels like a bit of a stretch.

@murchandamus murchandamus added the PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author label Jan 8, 2026
===Script Validation===

A P2TSH output is a native SegWit output (see [[bip-0141.mediawiki|BIP 141]]) with version 2 and a 32-byte witness program. The witness program is the root of the tapscript tree. For the sake of comparison, we have - as much as possible - copied the language verbatim from the script validation section of [[bip-0341.mediawiki|BIP 341]].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence feels out of place and is very much redundant: (the next line says the same thing)

Suggested change
A P2TSH output is a native SegWit output (see [[bip-0141.mediawiki|BIP 141]]) with version 2 and a 32-byte witness program. The witness program is the root of the tapscript tree. For the sake of comparison, we have - as much as possible - copied the language verbatim from the script validation section of [[bip-0341.mediawiki|BIP 341]].
A P2TSH output is a native SegWit output (see [[bip-0141.mediawiki|BIP 141]]) with version 2 and a 32-byte witness program. For the sake of comparison, we have - as much as possible - copied the language verbatim from the script validation section of [[bip-0341.mediawiki|BIP 341]].

Comment on lines +220 to +221
* Fail if the witness stack does not have two or more elements.
* If there are at least three witness elements, and the first byte of the last element is 0x50, this last element is called ''annex a'' and is removed from the witness stack. The annex (or the lack thereof) is always covered by the signature and contributes to transaction weight, but is otherwise ignored during P2TSH validation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a subtle divergence from the way P2TR is validated. When there are exactly two witness stack items and the second one starts with 0x50, P2TR interprets this as (public key, annex) and performs key path validation, while P2TSH as specified here interprets this as (script, control block). It just so happens that this will always fail because the 0x50 byte doesn't meet the leaf version requirement that the lowest bit be set to 1, but it might be preferable to make this explicit. If for some reason the lowest bit requirement were later revised to be 0 then the "annex" could be interpreted as a non-c0 version control block and pass validation.

Suggested wording:

Suggested change
* Fail if the witness stack does not have two or more elements.
* If there are at least three witness elements, and the first byte of the last element is 0x50, this last element is called ''annex a'' and is removed from the witness stack. The annex (or the lack thereof) is always covered by the signature and contributes to transaction weight, but is otherwise ignored during P2TSH validation.
* Fail if the witness stack does not have two or more elements.
* If the first byte of the last element is 0x50:
** Fail if the witness stack does not have at least three elements.
** The last element is called ''annex a'' and is removed from the witness stack. The annex (or the lack thereof) is always covered by the signature and contributes to transaction weight, but is otherwise ignored during P2TSH validation.

* Fail if the witness stack does not have two or more elements.
* If there are at least three witness elements, and the first byte of the last element is 0x50, this last element is called ''annex a'' and is removed from the witness stack. The annex (or the lack thereof) is always covered by the signature and contributes to transaction weight, but is otherwise ignored during P2TSH validation.
* There must be at least two witness elements left.
** Call the second-to-last stack element ''s'', the script (as defined in [[bip-0341.mediawiki|BIP 341]])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
** Call the second-to-last stack element ''s'', the script (as defined in [[bip-0341.mediawiki|BIP 341]])
** Call the second-to-last stack element ''s'', the script (as defined in [[bip-0341.mediawiki|BIP 341]]).

* There must be at least two witness elements left.
** Call the second-to-last stack element ''s'', the script (as defined in [[bip-0341.mediawiki|BIP 341]])
** The last stack element is called the control block ''c'', and must have length ''1 + 32 * m'', for a value of ''m'' that is an integer between 0 and 128, inclusive. Fail if it does not have such a length.
** Let ''v = c[0] & 0xfe'' be the ''leaf version'' (as defined in [[bip-0341.mediawiki|BIP 341]]). To maintain ''leaf version'' encoding compatibility the last bit of c[0] is unused and must be 1.<ref>Why set the last bit of c[0] to one? Consider a faulty implementation that deserializes the ''leaf version'' as c[0] rather than c[0] & 0xfe for both P2TR and P2TSH. If they test against P2TSH outputs and require that last bit is 1, this deserialization bug will cause an immediate error.</ref>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be just subjective preference, but I think requiring the unused bit to be 0 would make a lot more sense, as you'd get rid of the masking and have the first byte be the actual leaf version. Masking doesn't make much sense without the parity bit as used in BIP-341.

Suggested change
** Let ''v = c[0] & 0xfe'' be the ''leaf version'' (as defined in [[bip-0341.mediawiki|BIP 341]]). To maintain ''leaf version'' encoding compatibility the last bit of c[0] is unused and must be 1.<ref>Why set the last bit of c[0] to one? Consider a faulty implementation that deserializes the ''leaf version'' as c[0] rather than c[0] & 0xfe for both P2TR and P2TSH. If they test against P2TSH outputs and require that last bit is 1, this deserialization bug will cause an immediate error.</ref>
** Let ''v = c[0]'' be the ''leaf version'' (as defined in [[bip-0341.mediawiki|BIP 341]]). Fail if the last bit of ''v'' is not 0.<ref>Why is the last bit of the leaf version required to be zero? In BIP 341 the last bit is masked out and used to check the parity of the output public key. Because the bit is now unused, by setting it to zero we maintain the same leaf version set between P2TR and P2TSH.</ref>

** Let ''v = c[0] & 0xfe'' be the ''leaf version'' (as defined in [[bip-0341.mediawiki|BIP 341]]). To maintain ''leaf version'' encoding compatibility the last bit of c[0] is unused and must be 1.<ref>Why set the last bit of c[0] to one? Consider a faulty implementation that deserializes the ''leaf version'' as c[0] rather than c[0] & 0xfe for both P2TR and P2TSH. If they test against P2TSH outputs and require that last bit is 1, this deserialization bug will cause an immediate error.</ref>
** Let ''k<sub>0</sub> = hash<sub>TapLeaf</sub>(v || compact_size(size of s) || s)''; also call it the ''tapleaf hash''.
** For ''j'' in ''[0,1,...,m-1]'':
*** Let ''e<sub>j</sub> = c[33+32j:65+32j]''.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is meant to be:

Suggested change
*** Let ''e<sub>j</sub> = c[33+32j:65+32j]''.
*** Let ''e<sub>j</sub> = c[1+32j:33+32j]''.

===Common Signature Message Construction===

The [https://learnmeabitcoin.com/technical/upgrades/taproot/#common-signature-message common signature message] construction for P2TSH outputs is exactly the same procedure as defined in [[bip-0341.mediawiki|BIP 341]] for Taproot transactions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The common signature message is extended in BIP-342 by setting ext_flag = 1 and appending the tapleaf hash, key version and codeseparator position. Something similar ought to be specified here as well.


=== Compatibility with BIP 141 ===

By adhering to the SegWit transaction structure and versioning, P2TSH outputs are compatible with existing transaction processing rules. Nodes that do not recognize SegWit version 2 will treat these outputs as anyone-can-spend but, per [[bip-0141.mediawiki|BIP 141]], will not relay or mine such transactions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BIP-141 actually specifies no such thing. May I suggest:

Suggested change
By adhering to the SegWit transaction structure and versioning, P2TSH outputs are compatible with existing transaction processing rules. Nodes that do not recognize SegWit version 2 will treat these outputs as anyone-can-spend but, per [[bip-0141.mediawiki|BIP 141]], will not relay or mine such transactions.
By adhering to the SegWit transaction structure and versioning, P2TSH outputs are compatible with existing transaction processing rules. Nodes that do not recognize SegWit version 2 will treat these outputs as anyone-can-spend but will generally not relay or mine transactions that spend them.


===Transaction Size and Fees===

Equivalent P2TSH and P2TR outputs are always the same size. P2TSH inputs can be slightly larger or smaller than their equivalent P2TR inputs, depending on the use of key path vs script path spend in the case of P2TR. Let's consider the cases.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be further generalized:

Suggested change
Equivalent P2TSH and P2TR outputs are always the same size. P2TSH inputs can be slightly larger or smaller than their equivalent P2TR inputs, depending on the use of key path vs script path spend in the case of P2TR. Let's consider the cases.
All P2TSH and P2TR outputs are always the same size. P2TSH inputs can be slightly larger or smaller than their equivalent P2TR inputs, depending on the use of key path vs script path spend in the case of P2TR. Let's consider the cases.


====Comparison with P2TR script path spend====

A P2TSH witness will be smaller than the witness to an equivalent P2TR script path spend. This is because P2TSH does not require inclusion of any internal public key in the control block to unlock and spend an output. For this reason, a P2TSH witness will always be 32 bytes smaller than an equivalent P2TR script path spend witness.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A P2TSH witness will be smaller than the witness to an equivalent P2TR script path spend. This is because P2TSH does not require inclusion of any internal public key in the control block to unlock and spend an output. For this reason, a P2TSH witness will always be 32 bytes smaller than an equivalent P2TR script path spend witness.
A P2TSH witness will be smaller than the witness to an equivalent P2TR script path spend. This is because P2TSH does not require inclusion of an internal public key in the control block to unlock and spend an output. For this reason, a P2TSH witness will always be 32 bytes smaller than an equivalent P2TR script path spend witness.

@murchandamus
Copy link
Contributor

murchandamus commented Jan 8, 2026

Murch wrote:

That said, the term does strike me as somewhat odd: P2TR leaf scripts could be used with other leaf script versions in the future, e.g., making use of Simplicity, so the use of Tapscript in the script leaves does not necessarily seem to be the defining characteristic.

I realized today that I should have also pointed out that calling the output type “Pay to Tapscript Hash” feels a bit like a misnomer to me. As mentioned in my review, Tapscript refers to the variant of Script that is used by version 0xc0 P2TR script leaves, and Tapscript doesn’t feel like the main defining characteristic to either P2TR outputs or your new proposed output type — while there are hashes of script leaves that contain Tapscript appear as a building block in the tree, it seems fairly removed from the witness program and output script. The most defining characteristic to me seems that spending can only happen per one of the script leaves of the tree, so something mentioning the tree, alternative scripts, or a branch would have seemed more natural to me, maybe Pay to Script Tree or Pay to Tree Hash.

In an adhoc survey of one, the person guessed that an output type called “P2TSH” it would encode a P2WSH-like output using Tapscript instead of Script.

Anyway, naming is hard and YMMV, so beyond that I’ll try to keep my bike shedding to myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New BIP PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author

Projects

None yet

Development

Successfully merging this pull request may close these issues.