BIP376: Spending Silent Payment outputs with PSBTs#2089
BIP376: Spending Silent Payment outputs with PSBTs#2089nymius wants to merge 1 commit intobitcoin:masterfrom
Conversation
murchandamus
left a comment
There was a problem hiding this comment.
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.
|
I have pushed the changes in separated commits, to squash later. |
|
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? |
|
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. |
|
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. |
43d3ce2 to
aa4c4ed
Compare
|
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:
This would be a source of ambiguity. I will consider the options and update once I've a conclusion. |
|
Okay, I’ll consider this in your court until you state otherwise in a comment here. :) |
|
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 To avoid this I suggest creating a new field called |
09e9b51 to
2a3ca6a
Compare
|
I have revised the spec to address grammar and phrasing, and included the following updates regarding content:
|
macgyver13
left a comment
There was a problem hiding this comment.
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
| * ''hash<sub>tag</sub>(x)'': refers to ''SHA256(SHA256(tag) || SHA256(tag) || x)''. | ||
|
|
||
| === Fields === | ||
|
|
There was a problem hiding this comment.
I would suggest including the following:
This document specifies new fields and new field inclusion/exclusion requirements.
The new per-input types are defined as follows:
I agree, I will add them to the What is the reason for |
I agree |
fbc81c7 to
f6ef1a8
Compare
|
I've included a preamble to the I've squashed all commits in f6ef1a8. I'm open to receive another round of reviews. cc: @macgyver13 @craigraw |
f6ef1a8 to
75b7922
Compare
|
Included a grammar change that was left outside of last push. |
craigraw
left a comment
There was a problem hiding this comment.
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.
bip-0376.mediawiki
Outdated
|
|
||
| === Motivation === | ||
|
|
||
| BIP 352 specify the Silent Payment protocol, which provides a new way to create P2TR outputs and spend them. |
There was a problem hiding this comment.
Typo: use specifies instead of specify.
bip-0376.mediawiki
Outdated
| | Silent Payment Spend Key BIP 32 Derivation Path<ref name="why_sticking_to_bip32_derivation">''' 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 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.</ref> | ||
| | <tt>PSBT_IN_SP_SPEND_BIP32_DERIVATION = 0x1f</tt> | ||
| | <tt><33-byte spend key></tt> | ||
| | The 33-byte spend public key locking this input. |
There was a problem hiding this comment.
It would be more accurate to say The 33-byte spend public key used to derive the key locking this input. The tweaked key actually locks the input.
bip-0376.mediawiki
Outdated
| | <tt>PSBT_IN_SP_TWEAK = 0x20</tt> | ||
| | None | ||
| | No key data | ||
| | <tt><32-byte hash></tt> |
There was a problem hiding this comment.
<32-byte hash> is misleading. When a label is used, the value is t_k + label_tweak — a sum of two scalars, not a hash. Should be <32-byte tweak> to match the field name and the description.
bip-0376.mediawiki
Outdated
| | 2 | ||
| |} | ||
|
|
||
| Per [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#spending BIP 352 spending] the <tt><32-byte-hash></tt> is ''hash<sub>BIP0352/SharedSecret</sub>(ser<sub>P</sub>(ecdh_shared_secret) || ser<sub>32</sub>(k))'' |
There was a problem hiding this comment.
Same issue: <32-byte-hash> should be <32-byte tweak> for consistency.
bip-0376.mediawiki
Outdated
|
|
||
| Per [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#spending BIP 352 spending] the <tt><32-byte-hash></tt> is ''hash<sub>BIP0352/SharedSecret</sub>(ser<sub>P</sub>(ecdh_shared_secret) || ser<sub>32</sub>(k))'' | ||
|
|
||
| or ''hash<sub>BIP0352/SharedSecret</sub>(ser<sub>P</sub>(ecdh_shared_secret) || ser<sub>32</sub>(k)) + hash<sub>BIP0352/Label</sub>(ser<sub>256</sub>(b<sub>scan</sub>) || ser<sub>32</sub>(m)'', |
There was a problem hiding this comment.
Missing a closing parenthesis here.
bip-0376.mediawiki
Outdated
|
|
||
| The updater '''must add''' <tt>PSBT_IN_SP_TWEAK</tt> when an input spends a Silent Payment output. | ||
|
|
||
| The updater '''must add''' <tt>PSBT_IN_SP_SPEND_BIP32_DERIVATION_TWEAK</tt> when spending a Silent Payment output using BIP 32 derivation scheme. If the updater does not want to reveal the fingerprint or derivation path, it can set the value of the field to zero. |
There was a problem hiding this comment.
Field name typo: PSBT_IN_SP_SPEND_BIP32_DERIVATION_TWEAK should be PSBT_IN_SP_SPEND_BIP32_DERIVATION.
Also, "set the value of the field to zero" is a little ambiguous. Should clarify the structure, for example: "it can set the value to a 4-byte zero fingerprint with an empty derivation path".
There was a problem hiding this comment.
Agree, I took this formula from BIP 375, so this should be amended there too.
I will use: it can set the value to a 4-byte zero fingerprint with no derivation paths
bip-0376.mediawiki
Outdated
|
|
||
| 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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
| The updater '''must add''' <tt>PSBT_IN_SP_TWEAK</tt> when an input spends a Silent Payment output. | ||
|
|
||
| The updater '''must add''' <tt>PSBT_IN_SP_SPEND_BIP32_DERIVATION_TWEAK</tt> when spending a Silent Payment output using BIP 32 derivation scheme. If the updater does not want to reveal the fingerprint or derivation path, it can set the value of the field to zero. | ||
|
|
There was a problem hiding this comment.
Roles for the Signer and Finalizer are not present. I think they need to be, particularly for verifying the tweak is correct. Without it, a signer blindly trusts the updater's tweak. By checking d*G == P (where P is determined from the required PSBT_IN_WITNESS_UTXO field), the signer confirms the tweak is consistent with the output being spent. This is cheap (one EC multiplication) and prevents signing for an attacker-controlled key.
The Finalizer role should specify the additional cleanup required.
I suggest the following:
==== Signer ====
For each input that has a <tt>PSBT_IN_SP_TWEAK</tt> field set, the Signer must determine the spend private key <tt>b<sub>spend</sub></tt> 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 <tt>d = (b<sub>spend</sub> + tweak) mod n</tt>, where <tt>tweak</tt> is the value of <tt>PSBT_IN_SP_TWEAK</tt>. Let <tt>P</tt> be the output key from the <tt>PSBT_IN_WITNESS_UTXO</tt> scriptPubKey. If the Y coordinate of <tt>d·G</tt> is odd (i.e. does not match the X-only output key <tt>P</tt>), the Signer must negate <tt>d</tt>.
The Signer must verify that the X coordinate of <tt>d·G</tt> equals <tt>P</tt>. 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>
The Signer must produce a BIP 340 Schnorr signature using the private key <tt>d</tt> and set the result in the <tt>PSBT_IN_TAP_KEY_SIG</tt> field as defined in BIP 371.
==== Finalizer ====
For each input that has a <tt>PSBT_IN_SP_TWEAK</tt> field set, the Finalizer must verify that a <tt>PSBT_IN_TAP_KEY_SIG</tt> field is present. If not, the input is not fully signed and cannot be finalized.
The 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 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.
There was a problem hiding this comment.
Agree.
Some lights on my thought process:
I followed BIP 370 approach for this, and it left all this unspecified as it relies mainly in BIP 341.
I thought we could rely back in BIP 352 too.
This was clearly an oversight.
75b7922 to
c4b7f50
Compare
|
Thanks for the thorough review @craigraw, much appreciated! I will leave it up to you to decide if the conversations are resolved. |
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