bip352: clarify/fix specification to disallow sender to create outputs the receiver can't find #2153

pull edilmedeiros wants to merge 5 commits into bitcoin:master from edilmedeiros:bip352/fix_kmax changing 3 files +38 −37
  1. edilmedeiros commented at 1:42 PM on May 7, 2026: none

    #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:

    1. 4b9b490: Adds an additional check in the sender specification to disallow creating more keys/outputs than the receiver will surely scan (as per the specification).
    2. 2028356: Adds an additional functional test requirement for wallet implementors.
    3. 0de6dfb: Changes the reference implementation so that groups of silent payment addresses are calculated in a more sensible way (see details below). This commit WILL FAIL with the test vectors.
    4. c14fd21: Implement the proposed check in the reference implementation.
    5. 58c4ac6: Suggests minor redaction clarifications and fix typos.

    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_max parameter 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:

    Group receiver silent payment addresses by B_scan (e.g. each group consists of one B_scan and one or more B_m). If any of the groups exceed the limit of K_max (=2323) silent payment addresses, fail.

    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_m within. Then, the required check (group size should not exceed K_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 count on the recipients specification 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 address count times and pass those copies to create_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 same B_m), and will fail as per the spec.

    I don't believe this to be what any developer would implement from reading the specification:

    Group receiver silent payment addresses by B_scan (e.g. each group consists of one B_scan and one or more B_m).

    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.

  2. jonatack added the label Proposed BIP modification on May 7, 2026
  3. jonatack added the label Pending acceptance on May 7, 2026
  4. jonatack commented at 2:14 AM on May 8, 2026: member

    Pinging BIP authors @RubenSomsen, @theStack and @josibake for feedback, please.

  5. Add check for how many keys sender generated
    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>
    358f1d1f39
  6. Require functional test for number of outputs generated in a transaction
    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>
    18f9e281f4
  7. Change reference implementation to be spec compliant
    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>
    47699caa72
  8. Add check to the amount of keys generated per group
    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>
    cea7e3ebf7
  9. Fix typos and suggest minor redaction improvements 47ef418a11
  10. edilmedeiros force-pushed on May 8, 2026
  11. edilmedeiros commented at 2:15 PM on May 8, 2026: none

    Rebased after #1961.

  12. joaozinhom commented at 12:27 PM on May 9, 2026: none

    ACK 47ef418a112c70b829da03cfe4b875a39098e6ba


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bips. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-05-09 19:10 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me