bip352: clarify/fix specification to disallow sender to create outputs the receiver can't find#2153
Open
edilmedeiros wants to merge 5 commits intobitcoin:masterfrom
Open
bip352: clarify/fix specification to disallow sender to create outputs the receiver can't find#2153edilmedeiros wants to merge 5 commits intobitcoin:masterfrom
edilmedeiros wants to merge 5 commits intobitcoin:masterfrom
Conversation
Member
|
Pinging BIP authors @RubenSomsen, @theStack and @josibake for feedback, please. |
The specification limits how many keys the receiver is allowed to scan. Thus, we should not allow the sender to generate more than that many keys/outputs to prevent loss of funds. Co-authored-by: themhv <themhv@proton.me> Co-authored-by: joaozinhom <joaomcr@proton.me> Co-authored-by: IsaqueFranklin <isaque@harlock.xyz> Co-authored-by: lucasdcf <lucasdcf@users.noreply.github.com> Co-authored-by: oleonardolima <oleonardolima@users.noreply.github.com> Co-authored-by: Lorenzo <maturanolorenzo@gmail.com>
Co-Authored-By: themhv <themhv@proton.me> Co-Authored-By: joaozinhom <joaomcr@proton.me> Co-Authored-By: IsaqueFranklin <isaque@harlock.xyz> Co-Authored-By: lucasdcf <lucasdcf@users.noreply.github.com> Co-Authored-By: oleonardolima <oleonardolima@users.noreply.github.com> Co-Authored-By: Lorenzo <maturanolorenzo@gmail.com>
The original implementation references does a trick to avoid generating more outputs thatn the receiver is allowed to scan: it clones the payment specification before calling the crate_outputs() function. Then, when creating groups, the function will see the same address many times and create an artifically big group. This is not a reasonable interpretation of the spec, i.e., if I want to send 2324 outputs for the same address, this should be interpretated as a single group containing a single address. This is what this commit implements. Note that this will NOT pass the unit tests. Next commit will fix this. Co-Authored-By: themhv <themhv@proton.me> Co-Authored-By: joaozinhom <joaomcr@proton.me> Co-Authored-By: IsaqueFranklin <isaque@harlock.xyz> Co-Authored-By: lucasdcf <lucasdcf@users.noreply.github.com> Co-Authored-By: oleonardolima <oleonardolima@users.noreply.github.com> Co-Authored-By: Lorenzo <maturanolorenzo@gmail.com>
Co-Authored-By: themhv <themhv@proton.me> Co-Authored-By: joaozinhom <joaomcr@proton.me> Co-Authored-By: IsaqueFranklin <isaque@harlock.xyz> Co-Authored-By: lucasdcf <lucasdcf@users.noreply.github.com> Co-Authored-By: oleonardolima <oleonardolima@users.noreply.github.com> Co-Authored-By: Lorenzo <maturanolorenzo@gmail.com>
58c4ac6 to
47ef418
Compare
Author
|
Rebased after #1961. |
This was referenced May 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#2106 introduced a limit on how many keys the receiver is allowed to scan. But the sender specification still allows for creating outputs that exceed that limit, risking loosing funds. I tried to organize each commit so to make review as easy as possible:
Rationale
The specification of the sender and receiver seems to be out of sync, i.e. the sender can create a spec-compliant transaction such that a spec-compliant receiver will not find all funds received, implying the loss of funds. This is an edge case more theoretical than practical. I consulted @RubenSomsen about this possibility and we agreed opening a PR straight away would be safe for current users of silent payments.
#2106 introduced the
K_maxparameter which spirit is to limit how much effort the receiver is allowed to perform when scanning a candidate silent payment transaction.But things are not as clear in the sender side: the spec asks the sender to:
Let's analyze the case in which one is using a single silent payment address, but want to create 2324 (K_max + 1) outputs for the receiver. This is exactly scenario was covered by a new test case added together with #2106.
Well, there's one silent payment address, so that would make for one group with a single
B_mwithin. Then, the required check (group size should not exceedK_max) should not fail and we are going to proceed with output generation with no more additional checks required by the specification. We would end up with a transaction with 2324 outputs, but the receiver will only scan for 2323 (K_max) and miss one output.Note that the receiver could continue scanning anyhow and find all his funds, but version 1.1.x of the spec won't allow this.
About the changes in the reference implementation
Turns out that the test case expected result is that the described transaction creation should fail. And it does so in the reference implementation.
#2106 introduced a field
counton therecipientsspecification for tests and added a test case in which the sender is given a single silent payment address and wants to create 2324 outputs for it, just as described above.Before calling
create_outputs(), which is the reference implementation of this specification, the test harness will clone the silent payment addresscounttimes and pass those copies tocreate_outputs(). Thus, in the sender process, it will create a group with 2324 elements, all of which carry the same silent payment address (i.e. the sameB_m), and will fail as per the spec.I don't believe this to be what any developer would implement from reading the specification:
Indeed, I found this during a deep dive on the silent payments specification at Vinteum together with @lorenzolfm, @oleonardolima, @lucasdcf, @IsaqueFranklin, @joaozinhom, and @TheMhv and we all agreed we would not implement the specification like in the reference implementation.
We started looking at what wallets that support silent payments currently do and some didn't even implemented v1.1.0 yet, which introduced the described interpretation.