BIP: 376 source
Layer: Applications
Title: Spending Silent Payment outputs with PSBTs
Authors: nymius <nymius@proton.me>
Status: Draft
Type: Specification
Assigned: 2026-02-05
License: BSD-2-Clause
Discussion: 2024-05-17: https://delvingbitcoin.org/t/bip352-psbt-support/877/30 [delving bitcoin post] Original discussion
2025-12-05: https://gist.github.com/nymius/b3dd0b8a08c6735d617e6216b73c4260 [gist] First draft
2025-12-15: https://gnusha.org/pi/bitcoindev/R53cG3TeXgXDUUS4kH_q226GlaFCjI0DZVT6mdTQzSQdj3RnNqWA-bFT7uGgGQFJG6938kDGvDJVoFQj8ItEMsJ6NyOjCTvpVEarYiyW6-8=@proton.me/ [bitcoin-dev] [BIP Proposal] Add PSBT_IN_SP_TWEAK field
Requires: 352, 370, 371
This document proposes additional per-input fields for BIP 370 PSBTv2 that allow BIP 352 Silent Payment tweaks to be included in a PSBT of version 2. These fields are relevant to Silent Payment output spending.
BIP 352 specifies the Silent Payment protocol, which provides a new way to create P2TR outputs and spend them.
The existing PSBT fields are unable to support Silent Payment without changes, due to the new method by which outputs are created.
BIP 375 and complementary BIP 374 specify how to create outputs locked with Silent Payment keys using PSBTs. But they don't specify how to unlock these outputs in a transaction.[1]
Therefore, new fields must be defined to allow PSBTs to carry the information necessary for tweaking taproot keys without following the BIP 341 tagging scheme.
We use the following functions and conventions:
- ser32(i): serializes a 32-bit unsigned integer i as a 4-byte sequence, most significant byte first.
- ser256(p): serializes the integer p as a 32-byte sequence, most significant byte first.
- serP(P): serializes the coordinate pair P = (x,y) as a byte sequence using SEC1's compressed form: (0x02 or 0x03) || ser256(x), where the header byte depends on the parity of the omitted Y coordinate.
- hashtag(x): refers to SHA256(SHA256(tag) || SHA256(tag) || x).
This document specifies new fields and new field inclusion/exclusion requirements.
The new per-input types are defined as follows:
| Name | <keytype> | <keydata> | <keydata> Description | <valuedata> | <valuedata> Description | Versions Requiring Inclusion | Versions Requiring Exclusion | Versions Allowing Inclusion |
|---|---|---|---|---|---|---|---|---|
| Silent Payment Spend Key BIP 32 Derivation Path[2] | PSBT_IN_SP_SPEND_BIP32_DERIVATION = 0x1f | <33-byte spend key> | The 33-byte spend public key used to derive the key locking this input. | <4-byte fingerprint> <32-bit little endian uint path element>* | The master key fingerprint as defined by BIP 32 concatenated with the derivation path of the spend public key. The derivation path is represented as indexed 32-bit unsigned integers concatenated with each other. Input Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed. | 0 | 2 | |
| Silent Payment Tweak | PSBT_IN_SP_TWEAK = 0x20 | None | No key data | <32-byte tweak> | A 32-byte raw tweak. Input Finalizers should remove this field after PSBT_IN_FINAL_SCRIPTWITNESS is constructed. | 0 | 2 |
Per BIP 352 spending the <32-byte tweak> is hashBIP0352/SharedSecret(serP(ecdh_shared_secret) || ser32(k))
or hashBIP0352/SharedSecret(serP(ecdh_shared_secret) || ser32(k)) + hashBIP0352/Label(ser256(bscan) || ser32(m)),
where hashBIP0352/Label(ser256(bscan) || ser32(m)) is the optional label derived by some integer m.
This document modifies some existing roles.
The Updater MUST add PSBT_IN_SP_TWEAK when an input spends a Silent Payment output.
The Updater SHOULD add PSBT_IN_SP_SPEND_BIP32_DERIVATION when spending a Silent Payment output using the BIP 32 derivation scheme. If the Updater does not want to reveal the fingerprint or derivation path, it can set the value to a 4-byte zero fingerprint with no derivation paths.
Let P be the 32-byte output key from a P2TR output script contained in PSBT_IN_WITNESS_UTXO, i.e., in the form 0x5120<32-bytes of output key P>.
The Signer MUST compute the signing private key d = (bspend + tweak) mod n, where tweak is the value of PSBT_IN_SP_TWEAK and bspend is the spend private key obtained using either PSBT_IN_SP_SPEND_BIP32_DERIVATION or other methods.
The Signer MUST negate d if the y-coordinate of d·G is odd.
The Signer MUST fail if the x-coordinate of d·G does not equal P, as the tweak does not produce the expected spend output.[3]
The Signer MUST produce a BIP 340 Schnorr signature using the private key d and set the result in the PSBT_IN_TAP_KEY_SIG field as defined in BIP 371.
The Input Finalizer MUST verify that a PSBT_IN_TAP_KEY_SIG field is present for each input that has a PSBT_IN_SP_TWEAK field set. If not, the input is not fully signed and cannot be finalized.
The Input Finalizer MUST construct the PSBT_IN_FINAL_SCRIPTWITNESS containing the single witness element from PSBT_IN_TAP_KEY_SIG, as per the BIP 341 key path spending rule.
The Input Finalizer MUST remove the PSBT_IN_SP_TWEAK, PSBT_IN_SP_SPEND_BIP32_DERIVATION, PSBT_IN_TAP_KEY_SIG, and PSBT_IN_WITNESS_UTXO fields for any input where the PSBT_IN_FINAL_SCRIPTWITNESS is present.
On PSBTs, when spending non-Silent Payment outputs, one just relies on PSBT_IN_BIP32_DERIVATION or any of the allowed PSBT_IN_TAP_* combinations. These are used to get the right private keys to sign each input. For Silent Payment outputs, it is not that simple. To get the private key needed to sign a Silent Payment output, you have to combine a private key with the tweak obtained from the transaction corpus. Currently, there is no field prescribed for this.
The tweak is produced by combining some data from the transaction and the public keys belonging to the outputs being spent by that transaction. Providing these outputs not only imposes a burden on the signer, who has to perform extra cryptographic operations to combine this data, but it also increases the total amount of data included in the PSBT.
For example, if we consider a transaction with two P2WPKH outputs spent and one P2TR output created, and account for the weight of the prevouts, the total amount of bytes sent would increase by ~413 bytes, see the number details.
This is ~10x more data than the 32 bytes required by the tweak. This tweak is computed during the scanning of a Silent Payment output, and is easier to store than to regenerate.
It is possible, but brittle. This may require extra lookups for keys that are not unified across implementations.
PSBT_IN_TAP_MERKLE_ROOT was a candidate to host the tweak. It has the same size, and the tweaking operation for Schnorr is similar, but the tagged hash used for tweaking differs.
PSBT_IN_BIP32_DERIVATION was also considered, but discarded. A tweak would not fit exactly, and the purpose of this field is different.
In any case, reusing any of these fields would require another component to recognize the input as a Silent Payment output. This would create additional requirements that would not be worth the effort. A different field with a Silent Payment reference in the name would avoid the issue more simply.
Assuming different tweaking schemes are available, PSBT_IN_TAP_RAW_TWEAK would be a more general solution. However, PSBT fields are usually specified according to the nature of their contents, and it is unclear how a hardware wallet would determine the field’s content in the 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 keys cannot use PSBT_IN_TAP_BIP32_DERIVATION because BIP 352 specifies 33-byte spend keys[4], which do not fit within this keydata field. Furthermore, reliance on PSBT_IN_BIP32_DERIVATION is precluded because BIP 352 spending rules follow BIP 341, which mandates the use of Schnorr signatures.
These are new fields added to the existing PSBT format. Because PSBT is designed to be extensible, old software will ignore the new fields.
TODO
TODO
Gross amount of bytes required for tweak computation in a transaction with two P2WPKH inputs and one P2TR output
| Transaction header | |
|---|---|
| Field | Size |
| Version | 4 |
| Marker | 1 |
| Flag | 1 |
| Input count (Compact size) | 1 |
| Output count (Compact size) | 1 |
| Locktime | 4 |
| Total bytes | 12 |
| Field | P2TR Output | P2WPKH Ouptut (x2) |
|---|---|---|
| Amount | 8 | 8 |
| Output script length (Compact size) | 1 | 1 |
| Output script | 34 | 22 |
| Total bytes | 43 | 31 x 2 = 62 bytes |
| P2WPKH Input (x2) | P2WPKH Witness (x2) | |||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||||||||||||||||||
| Total bytes | 41 x 2 = 82 | 107 x 2 = 214 |
The gross amount of bytes required for the Signer to compute the tweak is: 12 + 43 + 62 + 82 + 214 = 413 bytes
This could be reduced by removing unnecessary fields, but at the cost of increasing the complexity for the Signer, without any significant gain.
This document is licensed under the 2-clause BSD license.
Thanks to Craig Raw, macgyver, josibake and all others who participated in discussions on this topic.
- ^ Why not including this new field in BIP 375? Historically, Silent Payment has been categorized from the perspective of the user of the protocol: receiver or sender. BIP 375 has followed this convention, as stated in its title: Sending Silent Payments with PSBTs. Given that spending belongs to the receiver’s sphere, and considering this convention, this specification should be a different BIP.
- ^ Why only considering BIP 32 for spend key generation? Although alternative key derivation methods exist (e.g., FROST) and have devised mechanisms to interact with PSBTs without modifying the format, the vast majority of hardware wallets are architected around the BIP 32 derivation scheme. As primary consumers of the PSBT format, these devices have significantly influenced its design. Consequently, this BIP avoids preemptively enforcing a shift away from the established BIP 32 paradigm.
- ^ 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.
- ^ Why not 32-byte x-only keys? The spend public key Bspend is a 33-byte signed key. P = Bspend + tweak·G is the derived key in the output script, also a 33-byte signed key. After computing d = bspend + tweak this extra sign byte is critical to decide whether the unlocking private key is d (P = d·G) or -d (P = -d·G).