As previously announced in the libsecp256k1 silentpayments module discussion and on the mailing list ~2 weeks ago, this PR introduces a K_max limit to BIP-352 to mitigate worst-case scanning time for adversarial transactions. So far no objections have been raised against that protocol change, which is backwards-incompatible in theory.
The Python reference implementation is adapted and test vectors for the following two scenarios are added:
- Sending fails if any recipient group (i.e. recipients that share the same scan public key) exceeds the limit
- Scanning only detects outputs with k values up to K_max (exclusive, i.e. from k=0..2322), even if more would be available
Can be tested by running $ ./bip-0352/reference.py ./bip-0352/send_and_receive_test_vectors.json. The test vectors pass the tests in the libsecp256k1 module as well, see commit https://github.com/theStack/secp256k1/commit/65ce62310a27d54784952de41607d10aaab30218. [1]
Note that the value K_max=1000 is somewhat arbitrary and can still be debated, it’s simply one that came up relatively early in the discussion and is believed to be fine even for very unusual scenarios like “exchange sends to another exchange” (see https://github.com/bitcoin-core/secp256k1/issues/1799#issuecomment-3773155788). An alternative number that was brought up later was K_max=2324, as this is the theoretical maximum for standard-sized (i.e. <= 100_000 kvB) transactions (https://github.com/bitcoin-core/secp256k1/issues/1799#issuecomment-3789112995). Personally I think even a lower limit than K_max=1000 would be fine, like something in the “lower hundreds” range, but with 1000 we are still comfortably in the “seconds” range for the worst-case on a reasonably modern machine. // EDIT: the proposed value was raised from 1000 to 2324
The chosen value of Kmax = 2323 (2324 was suggested earlier in https://github.com/bitcoin-core/secp256k1/issues/1799#issuecomment-3789112995 and in #2106 (comment) below, corrected to 2323) represents the maximum number of P2TR outputs that can fit into a 100kvB transaction, meaning a transaction that adheres to the current standardness rules is guaranteed to be within the limit. This ensures flexibility and also mitigates potential fingerprinting issues. See benchmark results https://github.com/bitcoin-core/secp256k1/pull/1765#issuecomment-3862265628 for more details.
Another suggested BIP change is introducing a warning about wallet interoperability w.r.t. the number of labels created. As I see this as an orthogonal change, I will open a separate PR for this. One slightly related PR is #2087, which would standardize the EC parts of the reference code and make it look a bit nicer. It’s not strictly necessary, but I’m happy to rebase this PR if #2087 gets in first.
[1] I haven’t included this commit in the secp PR yet as it’s unclear to me if we want to bloat the repository with >120k new LOC and several mega-bytes of additional test data, considering a test case for this already exists. Something to be discussed further in https://github.com/bitcoin-core/secp256k1/pull/1765. // EDIT: after the test vector encoding improvements as suggested in #2106 (comment), this is not an issue anymore