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
_______________________________________________
bitcoin-dev mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev