Subject: Re: [bitcoin-dev] Draft BIP for SNICKER

From: SomberNight <[email-masked]>
Date: Sun, 20 Oct 2019 00:29:25 +0000

Hi all,

waxwing, ThomasV, and I recently had a discussion about implementing SNICKER in Electrum; specifically the "Receiver" role. To me, SNICKER is an interesting proposal, due to the non-interactivity and because it seems it would be easy to implement the "Receiver" role in a light wallet. If enough users are using wallets that implement the "Receiver" role, even if full nodes and specialised scripts are needed to run SNICKER as a "Proposer", then coinjoins via SNICKER could become fairly frequent on-chain, benefitting the whole ecosystem indirectly by breaking common chain-analysis assumptions even further.

The BIP (draft) describes how the Receiver can deterministically find all his outputs and reconstruct all corresponding private keys, just from the seed words and the blockchain.
However what is not explicitly pointed out, and what I would like to point out in this mail, is that SNICKER breaks watch-only functionality.

See "Receiver actions" > "Storage of Keys" section ("Re-derive from blockchain history"). [0]

Specifically, the output address in the SNICKER transaction that pays to the "Receiver", is constructed from the pubkey `P_A + cG`, where `P_A` is a pubkey of "Receiver" (typically a leaf pubkey along some BIP32 path), and `c` is a tweak. This tweak was constructed such that `c = ECDH(Q, P_A)`, where `Q` is a pubkey of the "Proposer" that appears in the witness of the SNICKER tx.

As the referenced section [0] explains, the "Receiver" can restore from seed, and assuming he knows he needs to do extra scanning steps (e.g. via a seed version that signals SNICKER support), he can find and regain access to his SNICKER outputs. However, to calculate `c` he needs access to his private keys, as it is the ECDH of one of the Receiver's pubkeys and one of the Proposer's pubkeys.

This means the proposed scheme is fundamentally incompatible with watch-only wallets.
Nowadays many users expect being able to watch their addresses from an unsecure machine, or to be able to offline sign transactions. In the case of Electrum specifically, Electrum Personal Server (EPS) is also using xpubs to function. We've been exposing users to xpubs since the initial BIP32 implementation (and even predating BIP32, in the legacy Electrum HD scheme, there were already "master public keys").

It would seem that if we implemented SNICKER, users would have to make a choice, most likely during wallet creation time, whether they want to be able to use xpubs or to potentially participate in SNICKER coinjoins as a "Receiver" (and then encode the choice in the seed version). This choice seems rather difficult to communicate to users. Further, if SNICKER is not supported by the default choice then it is less likely to take off and hence less useful for the user; OTOH if xpubs are not supported by the default choice then existing user expectations are broken.

(Note that I am using a loosened definition of xpub here. The pubkeys in SNICKER tx output scripts are not along any BIP32 derivation. The point here is whether they could somehow be identified deterministically without access to secret material.)

Unfortunately it is not clear how the SNICKER scheme could be adjusted to "fix" this. Note that `c` needs to be known exactly by the two coinjoin-participants and no-one else; otherwise the anonymity set (of 2) is broken as:
- which SNICKER output corresponds to the tweaked public key and hence to the Receiver, can then be identified (as soon as the output is spent and the pubkey appears on-chain), and
- using subset-sum analysis the inputs and the outputs can be linked
SNICKER assumes almost no communication between the two parties, so it seems difficult to find a sufficient construction for `c` such that it can be recreated by the Receiver if he only has an xpub (and access to the blockchain) as all pubkeys from the xpub that the Proposer would have access to are already public information visible on-chain.

ghost43

[0] https://gist.github.com/AdamISZ/2c13fb5819bd469ca318156e2cf25d79#Storage_of_Keys

> Hello list,
> Here is a link for a draft of a BIP for a different type of CoinJoin I've named 'SNICKER' = Simple Non-Interactive Coinjoin with Keys for Encryption Reused.
>
> https://gist.github.com/AdamISZ/2c13fb5819bd469ca318156e2cf25d79
>
> Purpose of writing this as a BIP:
> There was some discussion on the Wasabi repo about this recently (https://github.com/zkSNACKs/Meta/issues/67) and it prompted me to do something I should have done way back when I came up with the idea in late '17: write a technical specification, because one of the main attractive points about this is that it isn't a hugely difficult task for a wallet developer to implement (especially: Receiver side), and it would only really have value if wallet developers did indeed implement it. To be specific, it requires ECDH (which is already available in libsecp256k1 anyway) and ECIES which is pretty easy to do (just ecdh and hmac, kinda).
>
> Plenty of uncertainty on the specs, in particular the specification for transactions, e.g. see 'Partially signed transactions' subsection, point 3). Also perhaps the encryption specs. I went with the exact algo already used by Electrum here, but it could be considered dubious (CBC).
>
> Thanks for any feedback.
>
> Adam Gibson / waxwing