Consider abandoning BIP-69
Trezor Suite is going to abandon the use of BIP-69 and instead just randomize the order of transaction inputs and the position of the change-output. The user-entered transaction outputs will be in the same order as the user entered them.
According to https://ishaana.com/blog/wallet_fingerprinting/ Electrum and Trezor Suite are the only mainstream wallets that use BIP-69. Trezor implemented BIP-69 when it seemed that everyone will be using it, but now almost no one uses it, so it's actually making Electrum and Trezor more easy to fingerprint instead of making it harder. There is also a pretty convincing discussion about this topic in the Bitcoin core repository, see bitcoin/bitcoin#12457.
This change in Trezor Suite will make Electrum even easier to fingerprint using the BIP-69 ordering as a heuristic, since it will be the only mainstream wallet that uses BIP-69. It is therefore worth considering abandoning the use of BIP-69 in Electrum too.
cc @prusnak
Some notes while contemplating this:
- lightning uses bip69(+cltv) order for a lot of txs
- by default the APIs in transaction.py sort according to bip69 (tx.from_io, tx.add_inputs, tx.add_outputs)
- we probably have around 100 unit tests that contain one or more hardcoded raw txs, which assume bip69
- it would be a lot of work to rewrite these, but we could add some internal toggle for bip69 and let these tests keep using it
- there are also already some unit tests extracted from other bips that do not use bip69 but require a specific order
- when writing tests, I quite like the fact the we create deterministic transactions. It would be quite a shame to lose this.
- so even for new tests, I would want to just enable bip69
- alternatively, we could make the "random" sort order instead be deterministic using a client secret, as in
[0]or[1].- This would also solve the "leaking secrets via sort order" concern mentioned in bip69 -- though I am not sure how realistic that is.
- I guess maybe the most problematic case is with an online PC + offline PC cold signing setup, where the offline PC reorders the tx inputs/outputs before signing, which the user would likely not notice (especially the inputs...).
- unfortunately this only works well if all inputs belong to the same wallet
- This would also solve the "leaking secrets via sort order" concern mentioned in bip69 -- though I am not sure how realistic that is.
Trezor Suite is going to [...] just randomize the order of transaction inputs and the position of the change-output. The user-entered transaction outputs will be in the same order as the user entered them.
If we abandoned bip69, I would much rather just randomise all inputs/outputs. That way, the random sort can be called in the same low-level APIs where we currently call the bip69 sort (tx.from_io, tx.add_inputs, tx.add_outputs), and we don't have to care about the otherwise many potential code paths and tx constructions (standard send, bump_fee, cpfp, double-spend cancel, rbf_batching, ln chan open, ln chan close, join_with_other_psbt, etc). Just as currently these methods have a boolean toggle for bip69 (default: True), we could change it to a sort order enum: manual/random/bip69 (default: random?).
Are there really no other wallets that use bip69? :/ I know that some exchanges, for example bitstamp, use bip69 for withdrawals. I wonder what libraries they use.
[0]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-June/008656.html
[1]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-October/016457.html
I would much rather just randomise all inputs/outputs
That is our plan for later, but this requires some changes in the Trezor firmware and python-trezor. But we will do this eventually.
OTOH keeping outputs in user-entered order and just inserting change address in random index does not require any change for us.