On-chain coinjoin is blended with off-chain coinswaps in this fascinating new hybrid approach.
There is a new privacy tool coming to town: coinswaps on statechains. The original statechain design was proposed by Ruben Somsen at Scaling Bitcoin 2018 in Tokyo. I will summarize quickly, but Aaron van Wirdum has a very thorough explainer of the original concept here. The general idea is to have a facilitating entity (the statechain operator) create a 2-of-2 multisig address with a user to facilitate the off-chain transfer of a UTXO. The user then transfers their private key for the 2-of-2 to a new user. The statechain entity would be informed of when this happens and at that point will only allow the new owner to transfer the funds out. So the whole idea is to transact by literally transferring the private key itself and have the state chain operator enforce current ownership.
And just like Lightning Network channels, each user has a pre-signed transaction allowing them to take unilateral control of the UTXO after a time lock has expired. This way if the statechain operator were to disappear, the funds wouldn’t be trapped in that 2-of-2 forever. But this backup option has to be balanced against the risk of one of the parties trying to misuse their pre-signed transaction to steal the funds. Somsen’s proposal depends on eltoo in order to facilitate the new owner replacing the previous owner’s pre-signed closure transaction in the event that the previous owner tries to steal back the funds. The last major part of the statechain design is a chain of signatures from one owner to another that starts with the original owner and goes all the way to the current one. This is passed from one owner to another and appended in parallel with each transaction so everyone can keep a local copy proving legitimate transfer and, in the case of the current owner, that they are in fact the legitimate owner.
Because of the dependence on eltoo and the fact that soft forks tend not to happen overnight, CommerceBlock began work on implementing a variant of statechains in 2020 that does not depend on eltoo. In place of eltoo allowing the most recent transaction to replace prior ones, they have implemented a decrementing nLocktime scheme called Mercury. The idea is that the original owner’s closure transaction is timelocked to a period of x blocks into the future; they cannot execute their transaction to take back the funds until the blockchain has reached this threshold. And then on the next ownership transfer, the new owner’s transaction is timelocked to x-1. This allows the current owner to submit their closure transaction to the chain before the original owner’s becomes valid to submit. As further ownership transfers take place, the timelocks continue decrementing (x-2, x-3, etc), guaranteeing that the current owner can always act before any of the previous owners’ transactions unlock. This removes the requirement for eltoo, but introduces a limitation in transferring statechains between owners: you can only decrement the timelocks so many times before it cannot be lowered anymore; at some point, the future, minus some amount of time (blocks), becomes equal to the present (the nLocktime is the current blockheight). At this point users must close out the statechain or older owners will be able to steal the coins as those earlier nLocktime transactions reach their locktime maturity and become valid.
Another key difference between Somsen’s original design and Mercury is how the key generation is handled. Instead of using an obvious 2-of-2 multisig script, Mercury implements ECDSA-MPC (elliptic curve digital signature algorithm multi-party computation). You can think of this as functionally similar to a MuSig address using Schnorr, except in Schnorr’s case users simply add two public keys together in order to create an address both are required to sign for. With ECDSA-MPC, the key generation is a more interactive process with multiple steps. In the end they functionally produce the same result: a single public key that is not obviously a multisig and where both parties involved have a share of the matching private key needed to sign a transaction.
The transfer process utilizing ECDSA-MPC is an interactive process where instead of the original owner explicitly transferring an existing private key as described in Somsen’s proposal, the statechain operator and the sender collaborate through ECDSA-MPC to generate a private key via keyshares. Crucially, there is more than one set of possible keyshares that can generate that same private key. So the statechain operator then recreates the private key with the recipient, but by making different keyshares. The statechain operator then deletes the keyshare they held that corresponds to the previous owner. CommerceBlock enforces this with an HSM (hardware security module), although this doesn’t remove all trust. This way if the statechain is operating honestly, it is literally incapable of signing a closure transaction with a past owner because the keyshare it currently holds does not work with past owner’s keyshare to create a valid signature. Also in the case of such collusion, public proof would be publishable showing that the statechain entity has acted dishonestly. This is a reputational disincentive to do so.
How does the public proof work? CommerceBlock has previously designed a variation of Opentimestamps called Mainstay. Opentimestamps is just a protocol for taking any arbitrary data and including it in a very large merkle tree with the root committed to a Bitcoin transaction. The problem with Opentimestamps is that the tree is completely unordered; things just get added to the end of the tree as they come in. This means it provides no guarantees that conflicting information isn’t committed to by the same anchoring transaction in the blockchain. What Mainstay does is effectively assign canonical “slots” in the merkle tree for specific pieces of data, for example an oracle attesting to the outcome of a sports game. Everyone can know which “slot” to check for that specific oracle and can then ignore any conflicting timestamps not in that slot. This allows people to attest to something with a timestamp without leaving open the possibility of timestamping conflicting things to reveal selectively (if you can write anywhere in the merkle tree, you could have the real timestamp in one place while pointing to a bogus one elsewhere). Every transfer of a Mercury statechain is attested to in a specific mainstay slot in order to provide a timestamped proof of current ownership that can be published if the statechain entity acts dishonestly.
Now that the details of the statechain implementation are out of the way, onto the interesting part: coinswaps. The general distinction historically made between coinjoins and coinswaps are that a coinjoin is an explicit and publicly visible use of privacy enhancing techniques occurring in a single transaction, while a coinswap is generally thought of as covert and, in the cooperative case of success, not a publicly-visible use of a privacy technique occurring across multiple separate transactions. The whole world can see when a UTXO goes into a coinjoin, but if implemented as generally discussed previously, no one except the participants would know when a UTXO is involved in a coinswap.
The coinswap implementation built on top of Mercury statechains breaks this clear distinction between coinjoins and coinswaps in terms of this overt versus covert privacy property. Transfers of statechains are recorded in the Mainstay commitments, so adversarially you have to assume that it’s public knowledge each time a statechain changes owners. But each transfer could also be a coinswap with any other statechain transferred in the same block interval. So in terms of anonymity tools, this becomes a sort of Frankenstein’s monster combining the anonymity properties of coinjoins while using the mechanism of a coinswap to conduct the exchange of UTXOs off chain. It uses a “coinswap” off chain on top of a statechain to emulate similar anonymity properties of a coinjoin without incurring an on-chain fee for each swap.
Coinswaps on Mercury statechains are essentially just regular statechain transfers with some fun cryptographic magic to make them anonymous. When you register a UTXO for a typical coinjoin (like Whirlpool or Wasabi), you register a UTXO as an input and then receive a blinded cryptographic credential you can use to create an output in the coinjoin to get your coins back over a new network connection to protect your privacy against the coordinator. This same coordination is approximated in Mercury’s scheme by registering statechains, receiving blind tokens and then querying the coordinator to be randomly assigned a new address to transfer their statechain to. There is even a chance of receiving your own statechain back to yourself. It’s random. After that it’s essentially just everyone signing off on their statechain transfers atomically, just like a coinjoin.
In the end what we have here is something very counterintuitive and at a strange point in the “trust spectrum” of Bitcoin tools that people probably aren’t used to considering deeply. Strictly speaking on a technical level, what is happening is a coinswap; coins are covertly being swapped without leaving a direct on-chain fingerprint that a swap of UTXOs is happening. But because of the Mainstay commitment to all transfers and the heuristic analysis potential of which statechains transferred owners in different time periods, you can infer the coinswap occurred, thereby reducing the anonymity set gains to be equivalent to a standard coinjoin. But you don’t have to pay fees on chain for each “coinjoin.”
To really drive home the point of the “strange point,” arguably with a single entity functioning as the statechain operator you could view this as approximating a custodial arrangement. But because of the HSM-enforced keyshare deletion, Mainstay attestations and the pre-signed closure transactions, users always have a path of unilateral exit from the system as long as the operator doesn’t collaborate with a prior statechain owner to defraud the legitimate owner.
The best way I can think to describe the trust model is to paraphrase Tom Trevethan from CommerceBlock: “This aims to occupy the middle ground between a fully custodial mixer and a fully trustless coinjoin in terms of privacy tools.” There is undeniably some degree of trust in the statechain operator, in this case CommerceBlock, to act honestly. But there are also mechanisms in place to publicly alert users of dishonest behavior from them and clear privacy benefits to be gained with a potential fee saving versus pure on-chain coinjoins.
It’s not quite trustless, but it’s also not quite completely trust based. It’s a new spot in the spectrum in terms of privacy tools. Personally, given the underappreciated fact of how widely used centralized mixers still are, I’m interested in seeing where this fits into that ecosystem. There’s a new kid in town.
This is a guest post by Shinobi. Opinions expressed are entirely their own and do not necessarily reflect those of BTC, Inc. or Bitcoin Magazine.