Skip to content

BIP376: Spending Silent Payment outputs with PSBTs#2089

Open
nymius wants to merge 1 commit intobitcoin:masterfrom
nymius:bip-spending-silent-payments-outputs-with-psbts
Open

BIP376: Spending Silent Payment outputs with PSBTs#2089
nymius wants to merge 1 commit intobitcoin:masterfrom
nymius:bip-spending-silent-payments-outputs-with-psbts

Conversation

@nymius
Copy link
Copy Markdown
Contributor

@nymius nymius commented Jan 19, 2026

Abstract

This document proposes an additional per input field for BIP 370 PSBTv2 that allows BIP 352 silent payment tweaks to be included in a PSBT of version 2. This field will be relevant to silent payment outputs spending.

Mailing list discussion: https://groups.google.com/g/bitcoindev/c/Kap7NMwzl2k
Delving bitcoin discussion: https://delvingbitcoin.org/t/bip352-psbt-support/877/32

Copy link
Copy Markdown
Member

@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 start, most parts seem to already be here. Would be great to get some more eyes on this from other people working on Silent Payments.

@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Jan 29, 2026

I have pushed the changes in separated commits, to squash later.
Thanks for the feedback!

@murchandamus
Copy link
Copy Markdown
Member

What’s the next step here? Will you be asking for people to provide some review, do you still have planned work, are there any open questions?

@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Feb 4, 2026

So far, I haven't received any negative feedback on the proposal, so I plan to do a second round of review on the rationale. I would like to steel-man the argument for this approach against the other alternatives.
Since the feedback occurred outside the designated channels, I will try to move the discussion there whenever possible.

@murchandamus
Copy link
Copy Markdown
Member

Assigned BIP376. Please update the BIP and Assigned headers in the preamble, add a table entry in the README for your proposal, and update your documents filename.

@murchandamus murchandamus changed the title BIP Draft: Spending Silent Payment outputs with PSBTs BIP376: Spending Silent Payment outputs with PSBTs Feb 5, 2026
@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from 43d3ce2 to aa4c4ed Compare February 5, 2026 20:18
@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Feb 5, 2026

While weighing the requirement of BIP 375, I detected there is no mention of how to source the base key to which the PSBT_IN_SP_TWEAK is added.

I have multiple ideas for this:

  • The 33 byte spend public key is included in the keydata from the new field.
  • The derivation information of the spend key is included in the corresponding BIP 32 fields.
  • The spend public key is transformed into a 32 xonly public key and it is included in one of the BIP 371 fields and both parities are considered.
  • This is left unspecified and the signer should implement a way to match the private key with the input and the tweak.

This would be a source of ambiguity. I will consider the options and update once I've a conclusion.

@murchandamus murchandamus added the PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author label Feb 6, 2026
@murchandamus
Copy link
Copy Markdown
Member

Okay, I’ll consider this in your court until you state otherwise in a comment here. :)

@craigraw
Copy link
Copy Markdown
Contributor

craigraw commented Feb 6, 2026

Good catch. I don't think this should be left unspecified.

Further, I think this choice can be simplified by considering the requirements of hardware wallets. I checked the firmware for both the Coldcard and the BitBox02 - both derive private keys from derivation paths, not public keys.

While you could use PSBT_IN_BIP32_DERIVATION, there may be some confusion with PSBT_OUT_TAP_BIP32_DERIVATION since BIP352 spends Taproot outputs.

To avoid this I suggest creating a new field called PSBT_IN_SP_SPEND_BIP32_DERIVATION which contains the same keydata and valuedata definitions used for PSBT_IN_BIP32_DERIVATION.

@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from 09e9b51 to 2a3ca6a Compare February 11, 2026 16:34
@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Feb 11, 2026

I have revised the spec to address grammar and phrasing, and included the following updates regarding content:

  • Following @craigraw suggestion (thanks!) I added a new PSBT_IN_SP_BIP32_DERIVATION field:
    • I considered other alternatives that do not adhere to the BIP 32 scheme, such as FROST. However, as the PSBT specification is primarily built around the BIP 32 derivation scheme, I decided not to deviate from that standard. When the time comes, these protocols will likely propose updates to align with the PSBT specification. I added a reference at the end explaining this.
    • I moved the PSBT_IN_SP_TWEAK below this new field.
    • I added a paragraph to the rationale justifying the creation of this new field rather than reusing one of the existing *_BIP32_DERIVATION fields.
  • I removed a paragraph from the rationale regarding the complexity of making BIP 341 and BIP 352 compatible to reuse Taproot BIP 371 fields (03e925c): I realized that the discussion of whether BIP 352 could have been designed to comprise BIP 341 tag hashes pertains to BIP 352 itself, not this document. This BIP should address BIP 352 as currently defined; changes to the BIP 352 standard belong to a different proposal.

Copy link
Copy Markdown
Contributor

@macgyver13 macgyver13 left a comment

Choose a reason for hiding this comment

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

Concept ACK 2a3ca6a

Thank you for putting this BIP forward. I support the addition of these two PSBT fields for spending Silent Payments outputs.

Regarding the BIP text I would like to see more explicit use of language to describe the inclusion of these fields for spending Silent Payments, similar to BIP-375 (PSBT_OUT_SCRIPT / PSBT_OUT_SP_V0_INFO). I think the Rationale explains the reasoning but having a more clear specification would reduce ambiguity. I am on the fence as to whether to include the following as general spec statements or in a specific role.

  • PSBT_IN_SP_TWEAK must be included when an input spends a Silent Payment output
  • PSBT_IN_SP_SPEND_BIP32_DERIVATION should be included when spending a Silent Payment output using BIP 32 derivation schemes

@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Feb 17, 2026

  • PSBT_IN_SP_TWEAK must be included when an input spends a Silent Payment output

  • PSBT_IN_SP_SPEND_BIP32_DERIVATION should be included when spending a Silent Payment output using BIP 32 derivation schemes

I agree, I will add them to the Updater in the same fashion as BIP 375.

What is the reason for PSBT_IN_SP_SPEND_BIP32_DERIVATION to be a should and not a must?

@macgyver13
Copy link
Copy Markdown
Contributor

What is the reason for PSBT_IN_SP_SPEND_BIP32_DERIVATION to be a should and not a must?

I agree must is fine here too. I was erroring on conservative specification constraint.

@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from fbc81c7 to f6ef1a8 Compare March 5, 2026 19:15
@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Mar 5, 2026

I've included a preamble to the Field specification, and expanded on the requirements of the Updater role.

I've squashed all commits in f6ef1a8.

I'm open to receive another round of reviews.

cc: @macgyver13 @craigraw

@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from f6ef1a8 to 75b7922 Compare March 5, 2026 19:21
@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Mar 5, 2026

Included a grammar change that was left outside of last push.

Copy link
Copy Markdown
Contributor

@craigraw craigraw left a comment

Choose a reason for hiding this comment

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

Added comments inline. My major comment is around the lack of Signer and Finalizer roles. The Signer must verify the tweak provided by the Updater for safety.


Assuming different tweaking schemes available, <tt>PSBT_IN_TAP_RAW_TWEAK</tt> would be a more general solution, but PSBT fields are usually specified as to the nature of the contents, and is unclear how a hardware wallet will determine what the content of the field were in the first more general case.

The inclusion of the tweak in the PSBT is insufficient in isolation; it must be accompanied by the information required to derive the correct private key. Silent Payment spend public key cannot utilize <tt>PSBT_IN_TAP_BIP32_DERIVATION</tt> because BIP 352 specifies 33-byte spend keys, which do not fit within this <tt>keydata</tt> field. Furthermore, reliance on <tt>PSBT_IN_BIP32_DERIVATION</tt> is precluded because BIP 352 spending rules follow BIP 341, which mandates the use of Schnorr signatures.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The rationale explains that PSBT_IN_TAP_BIP32_DERIVATION can't be used because BIP 352 uses 33-byte spend keys, but doesn't explain why 33-byte (compressed) form is needed rather than 32-byte x-only. The reason is that the spend key is an intermediate value, and the parity matters when computing d = b_spend + tweak and then checking against the x-only output key.

Copy link
Copy Markdown
Contributor Author

@nymius nymius Mar 6, 2026

Choose a reason for hiding this comment

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

This left me wondering why spend/scan key were left uncompressed not made x-only and force script pub key parity in the silent payment derivation. Fingerprinting? (again, I confused key parity with x-only keys)

It would be a good addition to BIP 352 rationales.

@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from 75b7922 to c4b7f50 Compare March 6, 2026 20:11
@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Mar 6, 2026

Thanks for the thorough review @craigraw, much appreciated! I will leave it up to you to decide if the conversations are resolved.

@craigraw
Copy link
Copy Markdown
Contributor

craigraw commented Mar 8, 2026

Thanks, looks good. Just one typo: The new footnote <ref name="why_33_byte_keys> is missing a closing double-quote.

@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from c4b7f50 to 37d80a4 Compare March 9, 2026 19:04
@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from 37d80a4 to 986e0c2 Compare March 12, 2026 13:35
@andrewtoth
Copy link
Copy Markdown
Contributor

What is the reason for PSBT_IN_SP_SPEND_BIP32_DERIVATION to be a should and not a must?

I agree must is fine here too. I was erroring on conservative specification constraint.

Hmm I think must is too restrictive. If you only have 1 private key, you don't need a derivation path to find it.

@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Mar 13, 2026

Hmm I think must is too restrictive. If you only have 1 private key, you don't need a derivation path to find it.

But you could still use the field zeroing the derivation path. It isn't disabling the case, it's forcing the explicitness of the keys in the PSBT.

@andrewtoth
Copy link
Copy Markdown
Contributor

But you could still use the field zeroing the derivation path. It isn't disabling the case, it's forcing the explicitness of the keys in the PSBT.

To me that sounds like making the case for should. Why require a field if it is not needed, only to be forced to zero it out? Zeroing it out is more ambiguous than not including the field at all if not needed.

@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from 986e0c2 to a11f705 Compare March 13, 2026 15:04
Copy link
Copy Markdown
Member

@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.

Just checking in. What’s the status from your end? I have a few minor comments. Perhaps a review from @theStack and @achow101 would be useful?


The Input Finalizer must construct the <tt>PSBT_IN_FINAL_SCRIPTWITNESS</tt> containing the single witness element from <tt>PSBT_IN_TAP_KEY_SIG</tt>, as per the BIP 341 key path spending rule. The Input Finalizer must then remove the <tt>PSBT_IN_SP_TWEAK</tt>, <tt>PSBT_IN_SP_SPEND_BIP32_DERIVATION</tt>, <tt>PSBT_IN_TAP_KEY_SIG</tt>, and <tt>PSBT_IN_WITNESS_UTXO</tt> fields.

== Rationale ==
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The structure of the Rationale reads a bit jumbled. Perhaps consider turning it into a definition list, where each sentence responds to a question, or restructuring it a bit to make it flow more naturally.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree, I'm going to work on this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've pushed some updates addressing the clarity of the Rationale. Let me know if you have any comments.

@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from a11f705 to cf2d98a Compare March 16, 2026 18:31
@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Mar 16, 2026

What’s the status from your end?

Based on my review, I believe the content is complete, but I am allowing time to receive feedback and apply changes.

I plan to request ACKs on the final document once I have addressed all reviewer comments and sufficient time has passed without receiving new ones.

Perhaps a review from @theStack and @achow101 would be useful?

Thank you for bringing this up. Yes, that would be useful, and it may help cover other angles I might have missed.

@murchandamus
Copy link
Copy Markdown
Member

Okay, then I’ll continue to leave the "PR Author action required" label on this PR as we previously communicated until you write to let me know that you consider it ready to be published.

@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch 2 times, most recently from 073e88c to dff2aa1 Compare March 19, 2026 20:44
@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from dff2aa1 to 7ffdc94 Compare March 27, 2026 15:54
@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Mar 27, 2026

I've added the new fields to the BIP 174 table.

@murchandamus, I consider this ready for publication. Thanks to all reviewers!

@murchandamus
Copy link
Copy Markdown
Member

Hey, thanks for letting me know. I’m going to be afk next week, but I’ll give it another pass when I’m back.

@murchandamus murchandamus removed the PR Author action required Needs updates, has unaddressed review comments, or is otherwise waiting for PR author label Mar 29, 2026
Copy link
Copy Markdown
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

Looks good to me overall.


For each input that has a <tt>PSBT_IN_SP_TWEAK</tt> field set, the Signer MUST determine the spend private key ''b<sub>spend</sub>'' using the derivation path provided in <tt>PSBT_IN_SP_SPEND_BIP32_DERIVATION</tt>. If this field is not present, or the Signer does not have the key matching the indicated fingerprint and path, the Signer MUST skip this input.

The Signer MUST compute the signing private key ''d = (b<sub>spend</sub> + tweak) mod n'', where ''tweak'' is the value of <tt>PSBT_IN_SP_TWEAK</tt>. Let ''P'' be the output key from the <tt>PSBT_IN_WITNESS_UTXO</tt> output script. If the y-coordinate of ''d·G'' is odd (i.e. does not match the x-only output key ''P''), the Signer MUST negate ''d''.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: for the sake of completeness, could mention that the PSBT_IN_WITNESS_UTXO output script must be of type P2TR (i.e. in the form 0x5120<32-bytes output key P>)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We can go a little bit further and fail if we have an PSBT_IN_SP_TWEAK combined with a non P2TR PSBT_IN_WITNESS_UTXO, as that's something impossible. What do you think?

diff --git a/bip-0376.mediawiki b/bip-0376.mediawiki
index fecfa2d..49418b2 100644
--- a/bip-0376.mediawiki
+++ b/bip-0376.mediawiki
@@ -96,7 +96,9 @@ The Updater SHOULD add <tt>PSBT_IN_SP_SPEND_BIP32_DERIVATION</tt> when spending
 
 For each input that has a <tt>PSBT_IN_SP_TWEAK</tt> field set, the Signer MUST determine the spend private key ''b<sub>spend</sub>'' using the derivation path provided in <tt>PSBT_IN_SP_SPEND_BIP32_DERIVATION</tt>. If this field is not present, or the Signer does not have the key matching the indicated fingerprint and path, the Signer MUST skip this input.
 
-The Signer MUST compute the signing private key ''d = (b<sub>spend</sub> + tweak) mod n'', where ''tweak'' is the value of <tt>PSBT_IN_SP_TWEAK</tt>. Let ''P'' be the output key from the <tt>PSBT_IN_WITNESS_UTXO</tt> output script. If the y-coordinate of ''d·G'' is odd (i.e. does not match the x-only output key ''P''), the Signer MUST negate ''d''.
+If <tt>PSBT_IN_SP_TWEAK</tt> field is set, but <tt>PSBT_IN_WITNESS_UTXO</tt> is not a P2TR output, i.e., of the form `0x5120<32-bytes>`, the Signer MUST fail, as the only Silent Payment outputs possible are P2TR outputs.
+
+The Signer MUST compute the signing private key ''d = (b<sub>spend</sub> + tweak) mod n'', where ''tweak'' is the value of <tt>PSBT_IN_SP_TWEAK</tt>. Let ''P'' be the 32-byte output key from the <tt>PSBT_IN_WITNESS_UTXO</tt> P2TR output script. If the y-coordinate of ''d·G'' is odd (i.e. does not match the x-only output key ''P''), the Signer MUST negate ''d''.
 
 The Signer MUST verify that the x-coordinate of ''d·G'' equals ''P''. If they are not equal, the Signer MUST fail, as the tweak does not correspond to the spent output.<ref name="why_verify_tweak">''' Why must the Signer verify the tweak?''' The tweak is provided by the Updater and could be incorrect, either through error or malice. Without verification, the Signer would produce a valid Schnorr signature for a key it does not control, which could be used to steal funds. Verifying that the tweaked key matches the output key ensures the Signer is signing for the expected output.</ref>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That sounds reasonable yes 👍 IIUC, the only way reaching this state is if "Updater" entity misbehaved or the PSBT have been tampered with, so it makes sense to fail in this case.

@nymius nymius force-pushed the bip-spending-silent-payments-outputs-with-psbts branch from 7ffdc94 to ca49162 Compare March 31, 2026 14:45
@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Mar 31, 2026

I considered this ready for publication, and I still do, but after last comment I added the following changes:

  • Introduced failure case when a non P2TR output script has the PSBT_IN_SP_TWEAK field set.
  • Removed back references to reduce ambiguity.
  • Introduced the Role + Action [ + Reason ] formula to all role paragraphs to reduce ambiguity, and make each protocol step implication stand out on first sight.
  • Reordered role paragraphs to fail early when possible.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants