Subject: Re: [bitcoin-dev] Design for a CoinSwap implementation for massively improving Bitcoin privacy and fungibility

From: ZmnSCPxj <[email-masked]>
Date: Sun, 31 May 2020 02:30:55 +0000

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 swapping, removing a privacy probe vector.
* Bob can unilaterally combine more than one input to the second transaction going to Bob, which further increases the uncertainty of clustering around the inputs from Alice than just adding *one* input.

---

A thing I have been trying to work out is whether SAS can be done with more than one participant, like in [S6](https://joinmarket.me/blog/blog/multiparty-s6/).

So far, I have not figured out a way to make it multiparty (multihop?).
Because the secret being transported is a private key that protects a specific UTXO, it seems it is not possible to safely use the same secret across more than two parties.
Perhaps others have come ideas?

Regards,
ZmnSCPxj