Re: [bitcoin-dev] Design for a CoinSwap implementation for massively improving Bitcoin privacy and fungibility
Good morning Ruben and Chris, > >For a much greater anonymity set we can use 2-party ECDSA to create 2-of-2 > >multisignature addresses that look the same as regular single-signature > >addresses > > This may perhaps be counter-intuitive, but SAS doesn't actually require > multisig for one of the two outputs, so a single key will suffice. ECDSA is a > signing algorithm that doesn't support single key multisig (at least not > without 2p-ECDSA), but notice how for the non-timelocked SAS output we never > actually have to sign anything together with the other party. We swap one of > the two keys, and the final owner will create a signature completely on their > own. No multisig required, which means we can simply use MuSig, even today > without Schnorr. Just to be clear, you mean we can use the MuSig key-combination protocol for the non-timelocked SAS output, but (of course) not the signing protocol which is inherently Schnorr. Then knowledge of both of the original private keys is enough to derive the single combined private key. > Of course the other output will still have to be a 2-of-2, for which you > rightly note 2p-ECDSA could be considered. It may also be interesting to > combine a swap with the opening of a Lightning channel. E.g. Alice and Bob > want to open a channel with 1 BTC each, but Alice funds it in her entirety > with 2 BTC, and Bob gives 1 BTC to Alice in a swap. This makes it difficult > to tell Bob entered the Lightning Network, especially if the channel is > opened in a state that isn't perfectly balanced. And Alice will gain an > uncorrelated single key output. Dual-funding could be done by a single-funding Lightning open followed by an onchain-to-offchain swap. Though the onchain swap would have to be done, at least currently, with hashes. > >=== PayJoin with CoinSwap === > > While it's probably clear how to do it on the timelocked side of SAS, I > believe PayJoin can also be applied to the non-timelocked side. This does > require adding a transaction that undoes the PayJoin in case the swap gets > aborted, which means MuSig can't be used. Everything else stays the same: > only one tx if successful, and no timelock (= instant settlement). I can > explain it in detail, if it happens to catch your interest. I am not in fact convinced that PayJoin-with-CoinSwap adds *that* much privacy. These transactions: +---+ +---+ Alice ---| |--| |--- Bob Alice ---| | | | Bob ---| | +---+ +---+ Are not really much different in coin ownership analysis from these: +---++---+ Alice ---| || |--- Bob Alice ---| | +--| | +---+ | +---+ Bob -+ The latter is possible due to private key handover, the intermediate output becomes owned solely by Bob and Bob can add many more inputs to that second transaction unilaterally for even greater confusion to chain analysis, basically private key handover gets us PayJoin for free. It also removes the need for Bob to reveal additional UTXOs to Alice during the swap protocol; yes PoDLE mitigates the privacy probing attack that Alice can mount on Bob, but it is helpful to remember this is "only" a mitigation. Now of course things are different if Alice is paying some exact amount to Carol, and Alice wants to dissociate her funds from the payment. The difference is then: +---++---+ Alice ---| || |--- Bob Alice ---| |--+ | | Bob ---| | | +---+ +---+ +- Alice Change +---++---+ Bob ---| || |--- Carol | |--+ +---+ +---+ | +- Bob Change Versus: +---++---+ Alice ---| || |--- Bob Alice ---| | +--| | +---+ | +---+ Bob -+ +---++---+ Bob ---| || |--- Carol | |--+ | |--- Alice Change +---+ | +---+ +- Bob Change In the above, with PayJoin on the first-layer transaction, the Alice Change is correlated with Alice and Bob inputs, whereas with the PayJoin on the second the Alice change is correlated with Bob inputs and Carol outputs. But if Alice, using commodity CoinSwap wallets, always has a policy that all sends are via CoinSwap (a reasonable policy, similar to the policy in JoinMarket of ensuring that all spends out of the wallet are via CoinJoin), then the above two trees are not much different for Alice in practice. The Alice Change will be swapped with some other maker anyway when it gets spent, so what it correlates with will not be much of a problem for Alice. At the same time, with PayJoin on the second-layer transaction (possible due to private key turnover, which is an inherent part of the SAS protocol): * Bob does not have to reveal any other coins it owns to Alice other than what it is directly
Re: [bitcoin-dev] Design for a CoinSwap implementation for massively improving Bitcoin privacy and fungibility
Hey Chris, Excellent write-up. I learned a few new things while reading this (particularly how to overcome the heuristics for address reuse and address types), so thank you for that. I have a few thoughts about how what you wrote relates to Succinct Atomic Swaps (SAS)[0]. Perhaps it's useful. >For a much greater anonymity set we can use 2-party ECDSA to create 2-of-2 multisignature addresses that look the same as regular single-signature addresses This may perhaps be counter-intuitive, but SAS doesn't actually require multisig for one of the two outputs, so a single key will suffice. ECDSA is a signing algorithm that doesn't support single key multisig (at least not without 2p-ECDSA), but notice how for the non-timelocked SAS output we never actually have to sign anything together with the other party. We swap one of the two keys, and the final owner will create a signature completely on their own. No multisig required, which means we can simply use MuSig, even today without Schnorr. Of course the other output will still have to be a 2-of-2, for which you rightly note 2p-ECDSA could be considered. It may also be interesting to combine a swap with the opening of a Lightning channel. E.g. Alice and Bob want to open a channel with 1 BTC each, but Alice funds it in her entirety with 2 BTC, and Bob gives 1 BTC to Alice in a swap. This makes it difficult to tell Bob entered the Lightning Network, especially if the channel is opened in a state that isn't perfectly balanced. And Alice will gain an uncorrelated single key output. As a side note, we could use the same MuSig observation on 2-of-2 outputs that need multisig by turning the script into (A & B) OR MuSig(A,B), which would shave off quite a few bytes by allowing single sig spending once the private key is handed over, but this would also make the output stick out like a sore thumb... Only useful if privacy is not a concern. >=== Multi-transaction CoinSwaps to avoid amount correlation === This can apply cleanly to SAS, and can even be done without passing on any extra secrets by generating a sharedSecret (Diffie-Hellman key exchange). Non-timelocked: CoinSwap AddressB = aliceSecret + bobSecret CoinSwap AddressC = aliceSecret + bobSecret + hash(sharedSecret,0)*G CoinSwap AddressD = aliceSecret + bobSecret + hash(sharedSecret,1)*G The above is MuSig compatible (single key outputs), there are no timelocks to worry about, and the addresses cannot be linked on-chain. >they would still need to watch the chain and respond in case a hash-time-locked contract transaction is broadcasted Small detail, but it should be noted that this would require the atomic swap to be set up in a specific way with relative timelocks. >=== PayJoin with CoinSwap === While it's probably clear how to do it on the timelocked side of SAS, I believe PayJoin can also be applied to the non-timelocked side. This does require adding a transaction that undoes the PayJoin in case the swap gets aborted, which means MuSig can't be used. Everything else stays the same: only one tx if successful, and no timelock (= instant settlement). I can explain it in detail, if it happens to catch your interest. Cheers, Ruben [0] Succinct Atomic Swaps (SAS) https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-May/017846.html On Mon, May 25, 2020 at 3:21 PM Chris Belcher via bitcoin-dev < bitcoin-dev@lists.linuxfoundation.org> wrote: > === Abstract === > > Imagine a future where a user Alice has bitcoins and wants to send them > with maximal privacy, so she creates a special kind of transaction. For > anyone looking at the blockchain her transaction appears completely > normal with her coins seemingly going from address A to address B. But > in reality her coins end up in address Z which is entirely unconnected > to either A or B. > > Now imagine another user, Carol, who isn't too bothered by privacy and > sends her bitcoin using a regular wallet which exists today. But because > Carol's transaction looks exactly the same as Alice's, anybody analyzing > the blockchain must now deal with the possibility that Carol's > transaction actually sent her coins to a totally unconnected address. So > Carol's privacy is improved even though she didn't change her behaviour, > and perhaps had never even heard of this software. > > In a world where advertisers, social media and other companies want to > collect all of Alice's and Carol's data, such privacy improvement would > be incredibly valuable. And also the doubt added to every transaction > would greatly boost the fungibility of bitcoin and so make it a better > form of money. > > This undetectable privacy can be developed today by implementing > CoinSwap, although by itself that isn't enough. There must be many > building blocks which together make a good system. The software could be > standalone as a kind of bitcoin mixing app, but it could also be a > library that existing wallets can implement allowing their users to send > Bitcoin
[bitcoin-dev] Announcing Bitcoin Wallet Tracker
Hi all, I recently released bwt [0], an HD wallet indexer implemented in Rust, using a model similar to that of Electrum Personal Server. It uses the bitcoind wallet functionality to do the heavy lifting and builds additional indexes on top of that, which can be queried using the Electrum RPC protocol, as well as a more modern, developer-friendly HTTP REST API. The electrum server can also be used as an electrum plugin [1], which integrates the server straight into the electrum client. From the user's perspective, this allows connecting electrum directly to a full node. The HTTP API is my take on a modern design for a wallet tracking API aimed at app developers. Some use-cases include using it as a backend for wallets (similarly to Samuari's Dojo) or to track deposits to a watch-only xpub (similarly to BTCPay's NBXplorer). Compared to using the bitcoind RPC directly, bwt provides: - The ability to track an xpub and automatically have new addresses derived and imported as needed, according to the gap limit. - Two additional indexes, one for looking up the transaction history of addresses, and another one for looking up txo spends (a map of funding_txid:vout => spending_txid:vin). - Real-time updates using Server-Sent Events [2] (a long-lived streaming HTTP connection) or Web Hooks [3] (an HTTP request sent to a configured URL). The updates being sent [4] directly provide information about the funded and spent wallet txos, instead of the client figuring it out from the tx. - Some API conveniences and simplifications, like including key origin information directly alongside inputs/outputs [5], the ability to specify key origins in place of addresses (eg. GET /hd/15cb9edc/8/utxos), a compact history format [6], and an easy way to catch-up with missed events [7]. Unless explicitly asked for, the API omits information about non-wallet inputs/outputs and protocol-level details like scriptsig and witnesses, which are typically not needed for higher-level app development. The indexer is designed in a way that minimizes RPC requests to bitcoind. By using labels to store key origin information, it is able to index incoming transactions using the information available from `listtransactions` alone (plus 3 extra rpc requests that don't grow with the number of transactions), but requires 1 additional rpc call per outgoing transaction (to learn which prevouts were spent). It can index 10k incoming txs in under a second, or a mixture of 5k/5k in under 5 seconds. The index is currently entirely in- memory and does not get persisted. The indexer logic can be seen in [8]. One major item on the roadmap that I'm hoping to tackle soon is support for output script descriptors. If anyone is interested in contributing, the README has some useful developer resources [9] and a handy script for setting up a development environment. This is an early alpha release, recommended for use with testnet/regtest. All feedback welcome! Cheers, Nadav [0] https://github.com/shesek/bwt [1] https://github.com/shesek/bwt#electrum-plugin [2] https://github.com/shesek/bwt#server-sent-events [3] https://github.com/shesek/bwt#web-hooks [4] https://github.com/shesek/bwt#event-categories [5] https://github.com/shesek/bwt#wallet-transaction-format [6] https://github.com/shesek/bwt#get-txssinceblock-heightcompact [7] https://github.com/shesek/bwt#catching-up-with-missed-events--re-org-detection [8] https://github.com/shesek/bwt/blob/master/src/indexer.rs (sync_transactions and load_transactions_since) [9] https://github.com/shesek/bwt#developing ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev