Skip to content

Conversation

@cryptoquick
Copy link
Owner

  • Pay-to-Quantum-Resistant-Hash (P2QRH) has been renamed to Pay-to-Tapscript-Hash (P2TSH)
  • Substantial re-writes/edits to correct errors and clarify authors' intent
  • Adds updated image of Tapscript tree/Merkle root and scriptPubkey construction
  • Added a brief glossary of terms
  • Formats revised BIP-0360 as a mediawiki document

Based on @notmike-5 's #31 with additional rounds of review from a collaborative google doc
Closes #26

cryptoquick and others added 2 commits December 17, 2025 08:48
Co-authored-by: Ethan Heilman <ethan.r.heilman@gmail.com>
elements larger than 520 bytes. Note this change to OP_DUP is not consensus critical and does not require any sort of fork. This is
because currently there is no way to get a stack element larger than 520 bytes onto the stack so triggering this rule is currently
impossible and would only matter if the stack element size limit was raised.
1. Minimize changes to the network. We should reuse existing Bitcoin code and preserve existing software behavior, workflows, user expectations and compatibility whenever possible.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Using # rather than 1 will make mediawiki understand this as a list and format it correctly. I realize the multiline nature of this complicates this formatting. We can also fix it later as it doesn't have to do with the content.

Suggested change
1. Minimize changes to the network. We should reuse existing Bitcoin code and preserve existing software behavior, workflows, user expectations and compatibility whenever possible.
# Minimize changes to the network. We should reuse existing Bitcoin code and preserve existing software behavior, workflows, user expectations and compatibility whenever possible.

Copy link
Owner Author

Choose a reason for hiding this comment

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

How will mediawiki know to correctly number the list when paragraphs are skipped?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It is doable, but I forget the exact method, I think there is some way of using </br> and some way of doing skipped #. I think we fixed this on one of versions of the PR.
Let's skip fixing this for now and then I can fiddle with the mediawiki formatting later

@EthanHeilman
Copy link
Collaborator

These subsections should really be sections.

image

To construct a P2QRH output we follow the same process as [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP 341]
to compute the tapscript Merkle root. However, instead of the root of the Merkle tree being hashed together with the internal
key in P2QRH the root is hashed by itself using the tag "QuantumRoot".
To construct a P2TSH output, we follow the process outlined in [[bip-0341.mediawiki|BIP 341]] to compute the final tapbranch hash, which is the merkle root of the tapleaves; however, instead of tweaking the internal key with the root of the Merkle tree (as is the case with P2TR outputs), P2TSH outputs commit only to final tapbranch hash, which is tagged, "TapBranch".
Copy link
Collaborator

@notmike-5 notmike-5 Dec 17, 2025

Choose a reason for hiding this comment

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

suggest taking a second look at this. What happens in Taproot is:

tweaked_pubkey = internal_pubkey + H("TapTweak" || internal_pubkey || taptree_root) * G

There's some language in #31 that describes this.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Ethan and I can't quite figure out what's wrong or what needs to change based on this feedback. Can you please clarify or provide a suggested change?

Copy link
Collaborator

@notmike-5 notmike-5 Dec 18, 2025

Choose a reason for hiding this comment

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

You say, 'instead of tweaking the internal key with the root of the Merkle tree (as is the case with P2TR outputs)...' but that isn't what Taproot does. You cannot 'tweak' (add together) an elliptic curve point and a 32-byte number. What Taproot does is it generates a new point from the hash of the tag 'TapTweak', the internal public key, and the root of the taptree (concatenated as I show above). And then it adds this new point to the internal public key to produce the tweaked public key. Here is the way I described it in #31:

"To construct a P2TSH output, we first follow the process outlined in [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP 341] to compute the Merkle root of a given taptree. Then, instead of summing the internal public key with another elliptic curve point generated from the hash of the tag 'TapTweak', the internal public key, and the derived taptree root (i.e. H("TapTweak" || internal_pubkey || merkle_root) * G) as is done in Taproot, P2TSH outputs commit only to the root of the taptree."

Copy link
Owner Author

Choose a reason for hiding this comment

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

I see what you're saying now. We already link to BIP 341, so in my opinion, those details don't need to be repeated here, especially because that's not the point we're trying to make.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok, sounds good. As an alternative you could just say 'instead of tweaking the internal pubkey as is the case with P2TR' and leave it at that. My point here is that Taproot doesn't tweak the internal pubkey with the root of any Merkle tree as is stated.

While P2TR outputs (and the use of key path spend) will remain an option for folks wishing to use them, we aim to be clear about the tradeoffs of using P2TSH outputs, which disable the key path spend for the benefit of quantum resistance.

We define the Pay to Quantum Resistant Hash (P2QRH) output structure as follows.
First off, P2TSH script path spends are slightly larger than P2TR key path spends, because you have to include the control byte and script in the transaction. That said, script path spends from P2TSH outputs will be slightly smaller than script path spends from P2TR outputs. For a more complete comparison of output type transaction sizes, the "Transaction Size and Fees" section may be reviewed later in this proposal.
Copy link
Collaborator

@notmike-5 notmike-5 Dec 17, 2025

Choose a reason for hiding this comment

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

You also have to include the merkle path and the script's inputs.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Including a note on merkle path (if depth > 0), but the script input isn't relevant in this case

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree on the merkle path, we should include if depth >0.

If we are doing an apples to apples comparison, then the script input is just the signature and so it is the same size as the signature in P2TR.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think my suggestion here was that P2TSH spends (they are all script path) are not 'slightly larger' than P2TR key-path spends. They are always much larger than P2TR key path, because their witnesses require a script, its inputs, and a control block. A P2TR key path witness requires only a small signature.

Copy link
Owner Author

Choose a reason for hiding this comment

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

I will remove the words "slightly" here. I also realized that there wasn't balance in that we didn't explain why P2TSH script path spends are smaller than P2TR script path spends. I made it so it's like this now:

First off, P2TSH script path spends are larger than P2TR key path spends, because you have to include the control byte, merkle path (if depth > 0), and script in the transaction. That said, P2TSH script path spends will be smaller than P2TR script path spends because there is no longer an internal key that must also be revealed. For a more complete comparison of output type transaction sizes, the "Transaction Size and Fees" section may be reviewed later in this proposal.

Let me know if that's adequate @EthanHeilman @notmike-5

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would make it clear here that you're comparing the sizes of witnesses, and if you wanted you could simplify by saying 'P2TSH spends' since they are all script path by design. Also, in the witness for P2TSH you have to provide 1) the leaf script's inputs, 2) the leaf script, and 3) the control block which contains the control byte and the Merkle path (if any). Otherwise spot on.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Okay, how's this?

First off, the witness for a P2TSH script path spend is larger than the witness for a P2TR key path spend, because you have to include the control byte, merkle path (if depth > 0), inputs, and the selected tapleaf's tapscript in the transaction. That said, P2TSH script path spends will be smaller than P2TR script path spends because there is no longer an internal key that must also be revealed. For a more complete comparison of output type transaction sizes, the "Transaction Size and Fees" section may be reviewed later in this proposal.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Just realized we also forgot a crucial element in the explanation, regarding P2TR spends... Please double-check this language is accurate @notmike-5 @EthanHeilman

First off, the witness for a P2TSH script path spend is larger than the witness for a P2TR key path spend, because you have to include the control byte, merkle path (if depth > 0), inputs, and the selected tapleaf's tapscript in the transaction, and P2TR key path spends only require a Schnorr signature. That said, P2TSH script path spends will be smaller than P2TR script path spends because there is no longer an internal key that must also be revealed. For a more complete comparison of output type transaction sizes, the "Transaction Size and Fees" section may be reviewed later in this proposal.

Copy link
Collaborator

@notmike-5 notmike-5 Dec 18, 2025

Choose a reason for hiding this comment

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

Yeah, that's a lot better. The leaf script is a tapscript, and so you could just say either of 'leaf script' or 'tapscript' instead of 'tapleaf's tapscript'. Totally your call.

You might say:

"The witness to a P2TSH spend is always larger than the witness to a P2TR key path spend. This is because a P2TR key path spend requires only a Schnorr signature in the witness. For P2TSH, the witness must include your chosen leaf script, its inputs, and a control block consisting of the control byte and Merkle path (if any).

That said, the witness to a P2TSH spend will always be smaller than the witness to an equivalent P2TR script path spend, because there is no longer any internal key in P2TSH that must be revealed in the control block. For a more complete comparison of output type transaction sizes, the "Transaction Size and Fees" section may be reviewed later in this proposal."

Copy link
Owner Author

Choose a reason for hiding this comment

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

I think that's solid.. I'll review that language with Ethan and Isabel before I commit it and will let you know if we need to make any further changes.

Copy link
Collaborator

@notmike-5 notmike-5 left a comment

Choose a reason for hiding this comment

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

Good job, guys!

cryptoquick and others added 5 commits December 17, 2025 18:23
Co-authored-by: Ethan Heilman <ethan.r.heilman@gmail.com>
Updates the vector file merkletree.svg.
Co-authored-by: Ethan Heilman <ethan.r.heilman@gmail.com>
Co-authored-by: notmike <notmike-5@users.noreply.github.com>
Copy link
Collaborator

@EthanHeilman EthanHeilman left a comment

Choose a reason for hiding this comment

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

LGTM!

@cryptoquick cryptoquick merged commit 56be885 into p2qrh Dec 19, 2025
9 checks passed
@cryptoquick cryptoquick deleted the p2tsh-rewrite branch December 19, 2025 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants