BIP-352: introduce per-group recipient limit K_max (=1000)#2106
BIP-352: introduce per-group recipient limit K_max (=1000)#2106theStack wants to merge 3 commits intobitcoin:masterfrom
Conversation
In theory this is a backwards incompatible protocol change. Practically, no existing Silent Payments wallets out there supports sending to such a high quantity of recipients (not even in terms of _total_ number of recipients), so the K_max limit should be safe to introduce, without any negative effects in the wallet ecosystem.
Test case: as the (only) recipient group contains 1001 addresses and thus exceeds the K_max limit by one, sending fails. Can be tested by `$ ./bip-0352/reference.py ./bip-0352/send_and_receive_test_vectors.json`
Test case: even though there are 1001 outputs targeted to the recipient, only 1000 are found due to the introduced K_max limit. Any implementation following the new BIP protocol rule wouldn't create such a transaction in the first place, but an attacker might do. Can be tested by `$ ./bip-0352/reference.py ./bip-0352/send_and_receive_test_vectors.json`
|
I guess I misunderstood so far what kind of limit you were looking to impose. I thought that Silent Payment transactions would generally be limited to 1000 outputs. If a malicious party were to send 1000 outputs to two recipients, they’d incur a 2×1000² validation time on two recipients, or a 2²×1000² total validation time. If they make an oversized transaction and send 1000 outputs each to 23 recipients, each of the 23 recipients would have 23×1000² total validation time. So, the total validation time is still quadratic, but distributed to multiple recipients, but it gets worse for each recipient the more recipients there are. Wouldn’t it be better to just limit silent payment transactions to 1000 outputs? It’s not like that would make Silent Payment transactions stick out like a sore thumb. ;) |
Limiting the total number of transaction outputs for Silent Payments eligibility might be a possible alternative, but it seems to be more restrictive in terms of composability. There is currently no rule that in a Silent Payments transaction all (taproot) outputs have to be Silent Payments related, users are free to combine it with an arbitrary number of non-Silent-Payments outputs. Considering this, can we be sure that a total tx output limit would never cause unintended problems in any wallet flow? It could e.g. happen that a user first creates exactly N_max [1] outputs with a Silent Payments library, and then some collaborative protocol adds another unrelated taproot output on top, without necessarily being aware that the already existing outputs even have a Silent Payments context (they just look like random taproot outputs). In that scenario the Silent Payments recipients wouldn't get paid, as the resulting transaction isn't considered Silent Payments eligible, due to having N_max+1 outputs and thus exceeding the limit. (Slightly related: #2055 (comment)). That said, I'm not too familiar with concrete collaboration protocols and flows, so the scenario I painted might also be a bit far-fetched, especially since it must be a single entity having control over all the inputs private keys (as otherwise it couldn't have created the Silent Payments outputs in the first place). When thinking about simpler solutions, one obvious idea would be to limit the size of Silent Payments eligible transactions to 100 kvB. No matter what protocols are in use, it seems at least very unlikely to me that any of them would at the end not respect the current policy limit and create a tx that would likely not be relayed and need out-of-band miner communication. On the other hand, no policy limit is set in stone, so in some sense even that would potentially restrict flexibility for the future. 🤷♂️ [1] using the N_max notion for your "limit total outputs" proposal to differentiate it from the K_max one |
|
cc: @josibake, @RubenSomsen |
As previously announced in the libsecp256k1
silentpaymentsmodule discussion and on the mailing list ~2 weeks ago, this PR introduces aK_maxlimit 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:
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 theStack/secp256k1@7ae84f8. [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 bitcoin-core/secp256k1#1799 (comment)). 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 (bitcoin-core/secp256k1#1799 (comment)). 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. See benchmark results bitcoin-core/secp256k1#1765 (comment) 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 bitcoin-core/secp256k1#1765.