-
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 352: Silent Payments #1458
BIP 352: Silent Payments #1458
Conversation
0ef28f3
to
f1c188f
Compare
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.
Glad to see this proposal advancing! I think with some minor changes it can be compatible with MuSig2 Taproot Keypaths (and potentially other off chain key aggregation schemes), which make it a powerful way of transacting privately even between users with advanced keys and scripts on Taproot.
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.
Some light review so far, but I'm really liking the proposal. Being able to easily implement just the sending part will no doubt greatly accelerate adoption by wallets.
Apart from the inline comments I also have a few style nits:
- "e.g" is used instead of "e.g." in a few places.
- Mixed usage of curly (
’
) and straight ('
) single quotes. - Some footnotes ("Rationale and References") are missing a period at the end.
- In Creating outputs, "Let a = a0 + a1 + … ai, where each ai" should have an be the last member of the sum, like in the rest of the document. Same goes for the sum in Scanning where the last member should be An.
f1c188f
to
1ae1b4b
Compare
98f37a9
to
d9e5a1b
Compare
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.
Second round of review. To complement this I wrote a quick and dirty implementation covering most of both sending and receiving. It was quite easy and seems to work, can't wait for test vectors to see how many bugs it has! 😅
In addition to the inline comments I have one general comment and one style nit:
- There are no specifics on how to deal with situations where EC operations fail to produce a valid point. I'm not sure if this is necessary, just mentioning this because my implementation has a lot of assertions.
- Tweak expressions are not consistent in whether the G part comes first or second. For example, in BIP341 it always comes second.
889a0b6
to
be18f6f
Compare
Thanks for the continued review, @vostrnad !
Do you have a specific scenario in mind? I'm certainly not an expert in this area, but I don't think we should get a failure by doing additions and multiplications (summing priv keys, pub keys, ecdh). If we can have a failure when summing up the private keys, public keys, or during the ECDH step, our only recourse would be to restart the coin selection process and ensure we get different inputs. |
ad7fa34
to
d342de6
Compare
One reason EC operations can fail is when a pseudorandom scalar value exceeds the curve order, which should only happen with negligible probability but other BIPs still have special cases for when it happens (e.g. BIP32, BIP340 and BIP341). I suppose it could be fine to ignore this, but I'm certainly no expert either. |
87f3104
to
d920133
Compare
I'll take a look to see how it's being handled in those BIPs. Ideally, we can reuse the same solution here. The main thing is ensuring both the sender and receiver can deterministically handle these low-probability events. |
@luke-jr Unless you see anything objectionable, please assign BIP number. |
I did some more reading on this and from what I can tell this applies to choosing a scalar which results in a valid point on the curve, which is not true for every scalar. In our case, we are already using existing valid private keys or, in the case of the silent payment address, are using BIP32 to generate them. Adding these keys together (using the elliptic curve group operation) or multiplying a valid scalar with a point (ECDH) gives us a result that is guaranteed to be a valid point on the curve. |
input_hash = get_input_hash([vin.outpoint for vin in vins], A_sum) | ||
pre_computed_labels = { | ||
(generate_label(b_scan, label) * G).get_bytes(False).hex(): generate_label(b_scan, label).hex() | ||
for label in given["labels"] |
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.
I have a suggestion to reflect “always check for the change label” in reference implementation and test vector. I believe the following changes should be enough.
Given this, the address for change would have to be removed from the relevant test case but I believe that it would be consistent with “It is important that the wallet never hands out the label with m = 0.”
Reference (always check for m = 0):
for label in given["labels"] | |
for label in given["labels"] + [0] |
And then in test data (don't explicitly refer to label 0):
diff --git a/bip-0352/send_and_receive_test_vectors.json b/bip-0352/send_and_receive_test_vectors.json
index 5d329f7..99cc52c 100644
--- a/bip-0352/send_and_receive_test_vectors.json
+++ b/bip-0352/send_and_receive_test_vectors.json
@@ -1829,14 +1829,11 @@
"spend_priv_key": "b8f87388cbb41934c50daca018901b00070a5ff6cc25a7e9e716a9d5b9e4d664",
"scan_priv_key": "11b7a82e06ca2648d5fded2366478078ec4fc9dc1d8ff487518226f229d768fd"
},
- "labels": [
- 0
- ]
+ "labels": []
},
"expected": {
"addresses": [
- "sp1qqw6vczcfpdh5nf5y2ky99kmqae0tr30hgdfg88parz50cp80wd2wqqauj52ymtc4xdkmx3tgyhrsemg2g3303xk2gtzfy8h8ejet8fz8jcw23zua",
- "sp1qqw6vczcfpdh5nf5y2ky99kmqae0tr30hgdfg88parz50cp80wd2wqqlv6saelkk5snl4wfutyxrchpzzwm8rjp3z6q7apna59z9huq4x754e5atr"
+ "sp1qqw6vczcfpdh5nf5y2ky99kmqae0tr30hgdfg88parz50cp80wd2wqqauj52ymtc4xdkmx3tgyhrsemg2g3303xk2gtzfy8h8ejet8fz8jcw23zua"
],
"outputs": [
{
@jirijakes thanks for the thorough review!
Great point, I'm leaning towards having it match the versioning restrictions of BIP350 to avoid unnecessary headache for implementers. Regardless, I think we also need to include sending to a higher version address in our test vectors.
Great suggestion, will add! |
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.
Began an initial review a fortnight ago -- a couple comments I had at the time before GitHub loses them, that may or may not be relevant.
d8ed18c
to
36fefe5
Compare
I’m not quite sure what the status of this PR is, but since at least it looked like it had an open Change Request from Ruben, I requested that he review again. |
It has been pointed out to me that @RubenSomsen suggested that the document were ready for final. I interpret this as his prior change request having been satisfied and we can disregard the open Change Request. However, it seems to me that the next step would be to move the proposal status from Draft to Proposed rather than Final. |
As pointed out in the prior comments, Ruben’s review from 2023 appears to be outdated.
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.
This proposal seems to be complete and ready to go. I have left a few nits, but none of these are blockers. I’m not merging immediately to give the BIP champions a chance to respond to my review.
ACK 36fefe5
Status: Draft | ||
Type: Standards Track | ||
Created: 2023-03-09 | ||
License: BSD-2-Clause |
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.
Please consider adding the "Post-History" header to link to the mailing list and additional fora where this proposal has been discussed.
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.
Added.
|
||
Bob publishes a public key ''B'' as a silent payment address. Alice discovers Bob's silent payment address, selects a UTXO with private key ''a'', public key ''A'' and creates a destination output ''P'' for Bob in the following manner: | ||
|
||
* Let ''P = B + hash(a·B)·G'' |
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.
- Let ''P = B + hash(a·B)·G''
Nit: I noticed that the symbol ''·'' (presumably elliptic curve scalar multiplication) was not introduced in the first paragraph of Overview.
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.
Added.
|
||
''' Spend and Scan Key ''' | ||
|
||
Since Bob needs his private key ''b'' to check for incoming payments, this requires ''b'' to be exposed to an online device. To minimize the risks involved, Bob can instead publish an address of the form ''(B<sub>scan</sub>, B<sub>spend</sub>)''. This allows Bob to keep ''b<sub>spend</sub>'' in offline cold storage and perform the scanning with the public key ''B<sub>spend</sub>'' and private key ''b<sub>scan</sub>''. Alice performs the tweak using both of Bob's public keys in the following manner: |
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.
Is this still an open todo?
Given that there is at least one implementation of your BIP already, I was wondering whether you have considered advancing it’s status to "Proposed". |
bip-0352.mediawiki
Outdated
@@ -140,7 +140,7 @@ For everything not defined above, we use the notation from [https://github.com/b | |||
|
|||
=== Versions === | |||
|
|||
This document defines version 0 (''sp1q''). Version is communicated through the address in the same way as Segwit addresses. Future upgrades to silent payments will require a new version. As much as possible, future upgrades should support receiving from older wallets (e.g. a silent payments v0 wallet can send to both v0 and v1 addresses). Any changes that break compatibility with older silent payment versions should be a new BIP. | |||
This document defines version 0 (''sp1q''). Version is communicated through the address in the same way as bech32 addresses (see [[https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 BIP173]]. Future upgrades to silent payments will require a new version. As much as possible, future upgrades should support receiving from older wallets (e.g. a silent payments v0 wallet can send to both v0 and v1 addresses). Any changes that break compatibility with older silent payment versions should be a new BIP. |
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.
I’m sorry, I was confused, this link should have used single brackets instead of double brackets.
This document defines version 0 (''sp1q''). Version is communicated through the address in the same way as bech32 addresses (see [[https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 BIP173]]. Future upgrades to silent payments will require a new version. As much as possible, future upgrades should support receiving from older wallets (e.g. a silent payments v0 wallet can send to both v0 and v1 addresses). Any changes that break compatibility with older silent payment versions should be a new BIP. | |
This document defines version 0 (''sp1q''). Version is communicated through the address in the same way as bech32 addresses (see [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 BIP173]. Future upgrades to silent payments will require a new version. As much as possible, future upgrades should support receiving from older wallets (e.g. a silent payments v0 wallet can send to both v0 and v1 addresses). Any changes that break compatibility with older silent payment versions should be a new BIP. |
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.
Fixed.
5b17cd3
to
32a3293
Compare
Co-Authored-By: Ruben Somsen <rsomsen@gmail.com>
* reference.py contains the silent payment specific code * secp256k1.py for doing the EC operations * bech32m.py contains code for encoding/decoding bech32(m) addresses * bitcoin_utils.py contains some helper code, not specific to silent payments * send_and_receive_test_vectors.json contains the wallet unit test vectors Co-Authored-By: S3RK <1466284+S3RK@users.noreply.github.com> Co-Authored-By: Oghenovo Usiwoma <37949128+Eunovo@users.noreply.github.com> Co-authored-by: S.Blagogee <34041358+setavenger@users.noreply.github.com>
Punctuation and wording improvements. Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
32a3293
to
82c2f78
Compare
Updated to Proposed. Thanks for the review @murchandamus , RFM! |
82c2f78
to
a60bfc3
Compare
- Fix link - Add explanation for scalar multiplication - Spelling error in test section
a60bfc3
to
17e1d16
Compare
@josibake When thinking about potential APIs for BitcoinJS with SP, the concept of PSBTs doesn't seem to work well with SP at all. It almost precludes the tx creation, signing, and finalizing MUST be done on the same device in one go. I think the SP BIP should at least mention that PSBT use should be avoided in the case of fully unsigned PSBTs or only has signatures that are SIGHASH_ANYONECANPAY. Since someone could easily modify the input set. In the long run, SP will require a few upgrades to PSBT one of which is backwards incompatible.
There are a lot of use cases for PSBT which would be dangerous to use with SP and some loose non-required "conventions." I would be interested to hear your thoughts. I don't have a clear change proposal so I couldn't think of a PR to make, so excuse my reviving a dead PR. |
Hey @junderw , we are discussing PSBT proposals on delving bitcoin and @andrewtoth has already started a draft BIP. It would be great to have your input over there! Regarding updates to this BIP, I think it would be more appropriate to finalize a silent payments PSBT BIP and then link to that BIP here. If we do end up needing a PSBTv3 for supporting silent payments, then we should definitely mention incompatibility with older PSBT versions here and point to the new PSBTv3 proposal. |
Silent payments is a static address protocol for Bitcoin, originally proposed on the mailing list here: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-March/020180.html
Since then, the proposal has received several rounds of review and has a WIP implementation here: bitcoin/bitcoin#27827 . The proposal has also been sent to the mailing list for review here: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-June/021750.html
Proposing this as an informational BIP to ensure wallets across the ecosystem can standardize and correctly implement the protocol.