-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bip Draft: Sending Silent Payments in PSBTs #1687
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,187 @@ | ||||||||||||||
<pre> | ||||||||||||||
BIP: ? | ||||||||||||||
Layer: Applications | ||||||||||||||
Title: Sending Silent Payments with PSBTs | ||||||||||||||
Author: Andrew Toth <andrewstoth@gmail.com> | ||||||||||||||
Ava Chow <me@achow101.com> | ||||||||||||||
josibake <josibake@protonmail.com> | ||||||||||||||
Comments-Summary: No comments yet. | ||||||||||||||
Comments-URI: TBD | ||||||||||||||
Status: Draft | ||||||||||||||
Type: Standards Track | ||||||||||||||
Created: 2024-05-14 | ||||||||||||||
License: BSD-2-Clause | ||||||||||||||
</pre> | ||||||||||||||
|
||||||||||||||
==Introduction== | ||||||||||||||
|
||||||||||||||
===Abstract=== | ||||||||||||||
|
||||||||||||||
This document proposes additional fields and updated role responsibilities for BIP 370 PSBTv2 | ||||||||||||||
which adds support for sending to silent payments as described in BIP352. | ||||||||||||||
Comment on lines
+20
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consistency nit: "BIP 370", but "BIP352" |
||||||||||||||
|
||||||||||||||
===Copyright=== | ||||||||||||||
|
||||||||||||||
This BIP is licensed under the 2-clause BSD license. | ||||||||||||||
|
||||||||||||||
===Motivation=== | ||||||||||||||
|
||||||||||||||
Partially Signed Bitcoin Transaction Version 2 as described in BIP 370 is not compatible with sending to silent payments as described in BIP352. In particular, the output script of a silent payment cannot be computed until after all transaction inputs have been added. | ||||||||||||||
Also, any inputs that the Signer has the private keys for must be signed with SIGHASH_ALL and all inputs must not have any scriptPubKeys with Segwit version > 1. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What creates the requirement to sign with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had the same question. The rationale in BIP 352 seems to imply that just forbidding ANYONECANPAY, i.e. that all signatures must fully commit to the input set, which seems sufficient even the PSBT setting? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Signing with I suppose I could add this as a footnote. |
||||||||||||||
Additionally, the silent payment outputs computed by a signer must be verifiable to other entities. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there is a single signer, why would others need to be able to verify? If there are multiple signers, wouldn’t all signers need to collaborate by putting forth shares rather than "computing silent payment outputs"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In the case of a hardware wallet connected to a software wallet, the hardware wallet is the single signer but the software wallet must verify that the output is computed properly before broadcasting.
Yes, all signers need to collaborate and put forth shares, but they must also compute the output script before signing. This computed output script must be added to the PSBT before signing to be compatible with BIP 370 signing process. After it is added, the other signers can compute the output script to verify themselves before signing. |
||||||||||||||
Therefore, new fields and role responsibilities must be added to carry, compute, and verify the silent payment data. | ||||||||||||||
|
||||||||||||||
==Specification== | ||||||||||||||
|
||||||||||||||
This document specifies new fields and new field inclusion/exclusion requirements. | ||||||||||||||
|
||||||||||||||
<tt>PSBT_OUT_SCRIPT</tt> is modified to be optional for outputs in silent payments capable PSBTs. If this field is not included in the output, then the field PSBT_OUT_SP_V0_INFO must be included. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make sense to require the presence of either Would it perhaps be sufficient to declare an output that has both the fields Perhaps the interplay of these two fields could be elaborated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think making these fields exclusive will work. The
That would indeed soften this requirement. This BIP would have to be modified to support that extension, making it
I don't really have an idea on how this could be made more graceful for that scenario.
I will add some more context in a footnote, thanks. |
||||||||||||||
|
||||||||||||||
The new global types are defined as follows: | ||||||||||||||
|
||||||||||||||
{| | ||||||||||||||
! Name | ||||||||||||||
! <tt><keytype></tt> | ||||||||||||||
! <tt><keydata></tt> | ||||||||||||||
! <tt><keydata></tt> Description | ||||||||||||||
! <tt><valuedata></tt> | ||||||||||||||
! <tt><valuedata></tt> Description | ||||||||||||||
! Versions Requiring Inclusion | ||||||||||||||
! Versions Requiring Exclusion | ||||||||||||||
! Versions Allowing Inclusion | ||||||||||||||
|- | ||||||||||||||
| Silent Payment Global ECDH Share | ||||||||||||||
| <tt>PSBT_GLOBAL_SP_ECDH_SHARE = 0x07</tt> | ||||||||||||||
| <tt><33 byte scan key> <36 byte outpoint>*</tt> | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to imply any subset of the inputs can be specified, presumably for grouping by owner. The main advantage over allowing only one outpoint per ECDH share seems to be a reduction in proving complexity for signers who choose to provide DLEQ proofs, since the 36 byte outpoint outweighs a Some disadvantages:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The main advantage is reduction in both ECDH share generation and proving complexity. Consider the common case of a single sig wallet using a hardware signing device receiving many small inputs over time. The wallet now contains 100 utxos and wants to spend to a single silent payment address. re: disadvantages
|
||||||||||||||
| The scan key and a list of outpoints corresponding to the prevouts of the inputs that this ECDH share is for. The outpoints are composed of a 32 byte txid followed by a 32-bit little endian uint. | ||||||||||||||
| <tt><32 byte share></tt> | ||||||||||||||
| An ECDH share for a scan key, followed by a list of outpoints. The ECDH shared is computed with ''a * B_scan'', where ''a'' is the sum of all private keys of the inputs matching the list of outpoints, and ''B_scan'' is the scan key of a recipient. | ||||||||||||||
Comment on lines
+57
to
+58
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as already noted in the DLEQ gist, this should have a size of 33 bytes instead, as it represents a point on the curve (https://gist.github.com/andrewtoth/df97c3260cc8d12f09d3855ee61322ea?permalink_comment_id=5250407#gistcomment-5250407), and representing it as x-only very likely only increases complexity for the DLEQ proof. |
||||||||||||||
| | ||||||||||||||
| 0 | ||||||||||||||
| 2 | ||||||||||||||
|- | ||||||||||||||
| Silent Payment Global DLEQ Proof | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggest defining "Discrete Log Equality Proofs (DLEQ)" above this / on first use, and discuss overlap with #1689 (if any) or linkage to be made between the two. |
||||||||||||||
| <tt>PSBT_GLOBAL_SP_DLEQ = 0x08</tt> | ||||||||||||||
| <tt><33 byte scan key> <36 byte outpoint>*</tt> | ||||||||||||||
| The scan key and a list of outpoints corresponding to the prevouts of the inputs that this proof covers. The outpoints are composed of a 32 byte txid followed by a 32-bit little endian uint. | ||||||||||||||
| <tt><64-byte proof></tt> | ||||||||||||||
| A DLEQ proof computed for the matching ECDH share. | ||||||||||||||
Comment on lines
+66
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For a given set of outpoints, there are multiple relevant There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this is a great insight, thank you! Would it not also reduce the complexity, since it would only be one proof to verify after summing the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you mean given This reference (section 3.2.3.3) seems to suggest it isn't, see footnote 16 on page 73, there's additional delinearization terms which are similar to key cancellation mitigation (and afaict are amenable to Fiat-Shamir just the same). This is an improvement over my implied suggestion as batched multiplication be used, but it does not reduce it to a single multiplication. Admittedly I don't yet see how to actually attack soundness as a malicious prover, especially when the prover does not control the choice of the the B_scan keys. The batch proof I'm familiar with involves having an R point per generator, so same structure as proposed in the DLEQ BIP, just generalized from 2 to n+1 verification equations. When the proof is encoded as the challenge and the response, the encoding the n+1 R points is implicit, so the size would still be 64 bytes and both prover and verifier work is concretely reduced (~half the verification equations, and a shared challenge hash), but not asymptotically as the total work is still linear for both prover and verifier. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using the mentioned protocol, "RME-based common exponent Schnorr protocol" (Henry14 3.2.3.3), the verifier performs 2+k ECC mults per proof, where k is the number of silent payment outputs, but the k mults can be shared for a batch of proofs, which large transactions can be a significant improvement in verifier complexity. Compared to this protocol the strawman protocol I described in the previous comment is broken in two ways, not just one:
In a non-interactive setting, the t_i terms of the random linear combination is generated by hashing. If Unfortunately the full set of SP_V0_INFO fields to be finalized before DLEQ proofs can be computed in that case, but if I understand Lemma 3.5 I think the |
||||||||||||||
| | ||||||||||||||
| 0 | ||||||||||||||
| 2 | ||||||||||||||
|} | ||||||||||||||
|
||||||||||||||
One new per-output type is defined as follows: | ||||||||||||||
|
||||||||||||||
{| | ||||||||||||||
! Name | ||||||||||||||
! <tt><keytype></tt> | ||||||||||||||
! <tt><keydata></tt> | ||||||||||||||
! <tt><keydata></tt> Description | ||||||||||||||
! <tt><valuedata></tt> | ||||||||||||||
! <tt><valuedata></tt> Description | ||||||||||||||
! Versions Requiring Inclusion | ||||||||||||||
! Versions Requiring Exclusion | ||||||||||||||
! Versions Allowing Inclusion | ||||||||||||||
|- | ||||||||||||||
| Silent Payment Data | ||||||||||||||
| <tt>PSBT_OUT_SP_V0_INFO = 0x08</tt> | ||||||||||||||
| None | ||||||||||||||
| No key data | ||||||||||||||
| <tt><33 byte scan key> <33 byte spend key></tt> | ||||||||||||||
| The scan and spend public keys from the silent payments address. | ||||||||||||||
| | ||||||||||||||
| 0 | ||||||||||||||
| 2 | ||||||||||||||
|} | ||||||||||||||
|
||||||||||||||
===Unique Identification=== | ||||||||||||||
|
||||||||||||||
Silent payment capable PSBTs can be uniquely identified the same way as PSBTv2s, except when including silent payment outputs. For silent payment capable PSBTs, all silent payment outputs must use the PSBT_OUT_SP_V0_INFO instead of PSBT_OUT_SCRIPT as the output script when creating the unsigned transaction used for unique identification. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found this sentence confusing. Does this also hold if both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, it does not hold once |
||||||||||||||
|
||||||||||||||
==Roles== | ||||||||||||||
|
||||||||||||||
This document modifies some existing roles. | ||||||||||||||
|
||||||||||||||
===Constructor=== | ||||||||||||||
|
||||||||||||||
All rules must be followed from PSBTv2 for this role, with the following exception: | ||||||||||||||
When an output is added, it must have either PSBT_OUT_SCRIPT or PSBT_OUT_SP_V0_INFO, or both, set. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I only understood here that both of these fields can be set at the same time. Perhaps that could be explained above where |
||||||||||||||
|
||||||||||||||
Additionally to PSBTv2, the Constructor must also follow additional rules: | ||||||||||||||
|
||||||||||||||
Inputs spending an output with script using Segwit version > 1 may only be added if there are no outputs with PSBT_OUT_SP_V0_INFO set. | ||||||||||||||
Outputs with PSBT_OUT_SP_V0_INFO set may only be added if there are no inputs spending an output script using Segwit version > 1. | ||||||||||||||
Comment on lines
+113
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This might be a bit out of scope for your PR, but I was just wondering: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe BIP 352 specifies that only the script template This is what I understood from @josibake's explanation. |
||||||||||||||
|
||||||||||||||
===Signer=== | ||||||||||||||
|
||||||||||||||
All rules must be followed from PSBTv2 for this role. If there are any outputs with PSBT_OUT_SP_V0_INFO set, then the following additional rules must also be adhered to: | ||||||||||||||
|
||||||||||||||
If any input is spending an output with script using Segwit version > 1, the Signer must fail. | ||||||||||||||
|
||||||||||||||
For all outputs with PSBT_OUT_SP_V0_INFO set, the Signer should: | ||||||||||||||
- Compute and set an ECDH share and DLEQ proof using all inputs it has the private key for. | ||||||||||||||
- Verify the DLEQ proofs for all inputs it does not have the private keys for. | ||||||||||||||
- If all eligible inputs have an ECDH share, compute and set the PSBT_OUT_SCRIPT. | ||||||||||||||
Comment on lines
+123
to
+125
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
||||||||||||||
If the Signer sets any missing PSBT_OUT_SCRIPTs, it must set the Inputs Modifiable flag to False. | ||||||||||||||
|
||||||||||||||
If any output does not have PSBT_OUT_SCRIPT set, the Signer must not yet add a signature. | ||||||||||||||
Comment on lines
+127
to
+129
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIUC, if it were not for this, blinding the SP_V0_INFO field would be technically be possible. Since that would necessarily add another round of communication between the various entities, as only only updaters with access to the blinding keys could set the output. A global flag to indicate whether the additional round is required might make sense? This flag might have 3 values, indicating if blinding is not used (allowing signers to update outputs), optional (precluding that), or required in which case all outputs must have SP_V0_INFO, with dummy values used for non-SP outputs. "required" or "mandatory" blinding is a bit misleading, it's providing deniability as to which outputs use SP, not requiring SP and blinding actually be used. |
||||||||||||||
|
||||||||||||||
The Signer should additionally compute the silent payment addresses, optionally showing this data to the user instead of the computed segwit v1 addresses. | ||||||||||||||
|
||||||||||||||
If a sighash type is provided and there are silent payment outputs present, the signer must fail if the sighash type is not SIGHASH_ALL. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned above, this seems to be stricter than BIP 352 itself. Is this intentional? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is intentional. |
||||||||||||||
If a sighash type is not provided and there are silent payment outputs present, the signer must sign using SIGHASH_ALL. | ||||||||||||||
|
||||||||||||||
====Computing the DLEQ Proof==== | ||||||||||||||
|
||||||||||||||
For each output with PSBT_OUT_SP_V0_INFO set, the Signer may generate a proof for other entities to generate the output scripts and verify that the output scripts were generated correctly. | ||||||||||||||
|
||||||||||||||
Generate a global ECDH share for each scan key ''B<sub>scan</sub>'' and all eligible inputs the Signer has private keys for as follows: | ||||||||||||||
|
||||||||||||||
Using the notation from [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#specification BIP352] | ||||||||||||||
|
||||||||||||||
* Let ''A<sub>n</sub>'' be the sum of the public keys ''A'' of all eligible inputs | ||||||||||||||
* Let ''a<sub>n</sub>'' be the sum of the private keys ''a'' of all eligible inputs | ||||||||||||||
* Let ''C = a<sub>n</sub>·B<sub>scan</sub>'' | ||||||||||||||
|
||||||||||||||
Use a key ''B<sub>scan</sub>'' followed by a list of the outpoints of all eligible inputs. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was surprised that we provide a single share and a single DLEQ proof per participant rather than one per input. In case there are multiple participants, this leaks to all other participants which inputs were provided in bulk by one party. I was wondering if there might be better privacy properties if participants provide a separate share for each input, that way all subsequent participants do not know how previous inputs group if the PSBT is passed in a circle rather than shared with all participants after each step. Maybe I’m overthinking this, though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is provided as a performance optimization so that there is only one proof for multiple inputs. |
||||||||||||||
|
||||||||||||||
Set the value for the key of PSBT_GLOBAL_SP_ECDH_SHARE to ''C''. | ||||||||||||||
|
||||||||||||||
Compute the DLEQ proof for ''C'' using ''a<sub>n</sub>'' and ''B<sub>scan</sub>''. | ||||||||||||||
Set the value for the key of PSBT_GLOBAL_SP_DLEQ to the proof. | ||||||||||||||
|
||||||||||||||
====Verifying the DLEQ Proof==== | ||||||||||||||
|
||||||||||||||
For each output with PSBT_OUT_SP_V0_INFO set, the Signer should verify the ECDH shares for all eligible inputs it does not have the private key for using the proofs provided by other Signers. | ||||||||||||||
|
||||||||||||||
====Computing the Output Scripts==== | ||||||||||||||
|
||||||||||||||
Compute the PSBT_OUT_SCRIPT using the procedure in [https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#user-content-Creating_outputs BIP352] but substituting ''a·B<sub>scan</sub>'' with the sum of all PSBT_GLOBAL_SP_ECDH_SHAREs for that scan key. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Assuming my suggestion to make shares be one per input is rejected, this needs to verify that the sets of outpoints in all ECDH_SHARE fields for a given scan key form a valid partition of the BIP 352 input set (no duplicates, no missing outpoints) before computing the sum of the values, or this sum might differ from |
||||||||||||||
If there are multiple silent payment codes with the same scan key, sort the codes lexicographically in ascending order to determine the ordering of the ''k'' value. | ||||||||||||||
If there are multiple silent payment codes with both the same scan and spend keys, sort the subgroup by output index in ascending order. | ||||||||||||||
|
||||||||||||||
====Change Detection==== | ||||||||||||||
|
||||||||||||||
Updaters may add two PSBT_OUT_BIP32_DERIVATION key-value-pairs with the corresponding derivation path of both the scan and spend keys. The Signer can then use these fields to verify that the silent payment code is change. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the "Updater" role perhaps appear before the "Signer"? Adding change would probably happen at the same time participants add inputs, so surely before signing? |
||||||||||||||
|
||||||||||||||
===Transaction Extractor=== | ||||||||||||||
|
||||||||||||||
For silent payment capable PSBTs, the transaction extractor should compute all output scripts for silent payment codes and verify they are correct using the ECDH shares and DLEQ proofs, otherwise fail. | ||||||||||||||
|
||||||||||||||
==Backwards Compatibility== | ||||||||||||||
|
||||||||||||||
Silent payment capable PSBTs are backwards compatible with PSBTv2 once all outputs have PSBT_OUT_SCRIPT set. Otherwise they are not backwards compatible. | ||||||||||||||
|
||||||||||||||
==Test Vectors== | ||||||||||||||
|
||||||||||||||
Todo | ||||||||||||||
|
||||||||||||||
==Rationale== | ||||||||||||||
|
||||||||||||||
<references/> | ||||||||||||||
|
||||||||||||||
==Reference implementation== | ||||||||||||||
|
||||||||||||||
Todo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.