this notes have been largely superseded by discussions in the https://github.com/zkSNACKs/WabiSabi repository.
secondly, this describes a general framework which may be instantiated in different ways, a point that was not made clearly (the specific types described are more like independent examples of possible designs, not a specific proposal)
Modifications to the zerolink Chaumian coinjoin scheme to support:
- more flexible amounts
- more flexible fee structure
- arbitrary payments with batching
Could use existing scheme (blind sigs), possibly with probablistic Wagner attack mitigation, or consider privacy pass style tokens on secp256k1. There are different efficiency tradeoffs to consider, and in introducing reissuance, a different threat model (but same consequences - if the security of per round token keys is compromised, an attacker can cause rounds to fail with the wrong user being blamed, but theft is not an issue since the coinjoin transaction must still be signed at the end).
Token represent unlinkable units of some known type. Different types represent different amounts, as well as additional purposes depending on the round, fee model, incentive structure, etc.
To support construction of transactions according different mixing strategies, tokens need a reissuance operation where users may redeeum a multiset of tokens (possibly of multiple types) to produce a multiset of replacement tokens of equal value, but otherwise with arbitrary requested types.
Clients can reissue tokens to break up or consolidate inputs, optionally convert to different token types, and eventually construct final output amounts. To improve privacy from the coordinator, clients should randomly schedule the necessary reissuance operations throughout the input registration phase with sufficient fan out to avoid temporal fingerprinting by the coordinator upon recombination at output registration.
A common model assumptions used for analyzing coinjoins, namely that no net transfers/payments apart between participants (apart from fees) occur in a coinjoin. In order to make that assumption invalid tokens should be transferrable through the reissuance operation:
- Alice creates blinded token multiset, and sends it to Bob
- Bob takes the union of Alice's token multiset with his own, and and requests them to be signed by the coordinator by redeeming his own tokens.
- Bob forwards the subset of signatures corresponding to Alice's tokens to her
Below "blinded token" refers to a signing request, "token signature" is the response, and "unblinded token" or just "token" are used interchangeably when referring to redemption.
All connections between clients and coordinator use should be anonymous and unlinkable (ephemeral tor circuits).
Rounds have ephemeral keys for different token types. The per-round keys should be authenticatable by the client based on some static coordinator credential.
The coordinator announces these per-round keys, as well (some of) the following metadata:
- per tx item mining fees:
- input mining (should be a sum of two linear functions -
f(x) = a x + b
, one of size and one of witness, maybe linear function of vbytes) - ouptut fees (linear function of size or vbytes)
- coordination fees (linear/constant function of amount)
- non-linear? outputs of a certain class could be discounted incur additional fees (
f(x) = { if x == c_1 then a_1 x + b_1, if x == c_2 then a_2 x + b_2, ... }
)
- input mining (should be a sum of two linear functions -
- allowed input denominations: any, range(s), exact values.
- allowed output denominations & types (type denotes whether per output class tokens are used, see Output Registration below)
- schedule - could be hard or soft. soft schedule extended indefinitely or cause early termination of phases subject to conditions:
- minimum/maximum number of inputs (of a given size)
- minimum/maximum number of outputs (of a given size)
- minimum/maximum total amount of fee amounts (latter expressed as a sum of linear functions on amount, size?
Rounds are used to collaboratively construct sub-transactions with unlinkable components. Different round types may have different constraints/rules, which are enforced by the token structure (see Token Types below).
For example, pure mixing rounds might only accept inputs of a certain size, and allow construction of outputs of a certain size. Some round types may allow arbitrary amounts to be used/combined.
Rounds terminate when the coordinator proposes a compatible coinjoin transaction, and input owners provide signatures after verifying. If transfers are allowed, there are additional considerations (see Signing Phase).
Client provides:
- spendable outpoint
- proof of ownership/spendability
- optional unblinded prepaid fee token multiset
- a multiset of blinded tokens for signing, with their requested types
The coordinator deducts the per input fees from the input amount, and then adds up the requested number & types of blinded tokens, to make sure they match.
If valid, then blind signatures are provided for all requested tokens.
Outputs of an apparent or known (by same coordinator) coinjoin transaction can be treated as different types at registration, similar to how whrilpool's tx0 is required before mixing transactions.
This can be used to provide different fee/incentive structure for mixing.
Tokens can be reissued arbitrarily many times during input phase, which allows clients to construct sets suitable for output regisration phase, as well as transfer tokens to recipients.
Different round types, incentive structures, etc may employ different token types, and only input credit tokens are strictly required.
- Input credit tokens - different types corresponding to
2^{0..k}
satoshi amounts. can be redeemed by combining multiple tokens. - Output class tokens - some finite number of tokens issued on input registration with certain denominations, or by conversion during output registration. These tokens are redeemable for outputs of a certain class, and may only be redeemed separately. Rationale: improves
- Long lived fee credit tokens - different types corresponding to
2^{0..k}
satoshi amounts that can be added along side input credit tokens, but only up to the per input/output mining fees and coordination fees. - Abuse prevention token - some finite number of tokens issued on input registration, one must be redeemed/reissued with every reissuance operation. multiple tokens should be provided to allow participants to invite recipients into a round. effectively limits concurrent requests by single participant.
When the input registration phase concludes, tokens are used for:
- registration of outputs, both change & mixed:
- unblinded per class token (only if required by round output class restrictions)
- unblinded input credit tokens (covering output amount and per output fees, can be omitted input/output amounts are uniform)
- unblinded fee tokens to offset input credit
- issuance of long lived fee tokens (input credits can be converted to long lived fee tokens, but probably not the other way to avoid legal liability for coordinator)
Once all round tokens have been redeemed the round moves into the signing phase.
As in original zerolink, the input owners must sign the proposed transaction if the outputs contain the outputs they registered.
Additionally, concurrent rounds may be combined into a single coinjoin transaction by the server, with the same signing rules for participants.
For cooperative transfers using tokens, the receiver should simply authorize the output state so the sender will sign, there is no need to disclose the receiver's registered output(s) to the sender. If the receiver defects the sender may choose to sign or not, at the risk of being banned. A blame mechanism could be added, for requesting unbanning of inputs that did not sign, but i see no clear advantage over static limits per non signing input, since both parties have an incentive to cooperate.
Although in general multisets are required for conversions (e.g. consolidating an amount {2^n, 2^n} -> {2^n+1}
), some operations should be constrained to sets or single values where appropriate.
For example, in a round intended to produce fungible outputs of some fixed amount (only one denomination), with arbitrary input amounts, outputs could be registered by providing arbitrary input credit tokens, also covering the mining fees, and constructing the output and change in the same operation.
This is obviously undesirable because it it discloses change & supposedly fungible output linkage to the coordinator, and leaks information about the input denominations as well.
To improve the privacy and prevent misuse, the output registration operation should instead require a set (not multiset) that exactly represents the precise binary decomposition of a single output amount, including fees.
This can be further decoupled simplifying round synchronization if fungible output require exactly one token. Continuing the above example, suppose the fungible amount was 129 satoshi, the mining fees are 1 sat per input/output, 6 sat coordinator fee per fungible output, and Alice is registering an input of size 64 satoshi and another input of size 97 satoshi, she would perform the following parallelizable operations:
- Register inputs
- register input of size 64 (0b01000000). deducting per input fees, Alice receives 6 input credit tokens worth 63 ((0b00111111)) satoshi:
{32, 16, 8, 4, 2, 1}
- register input of size 97 (0b01100001). deducting per input fees, Alice receives 2 input credit tokens worth 96 ((0b01100000)) satoshi:
{64, 32}
- Convert amounts. Numbers denote input credit tokens of that amount:
{64, 64} -> {128}
{32, 32} -> {64}
{128, 8} -> {fungible output class token}
(also covers per output fees)
- output registration phase
- redeem
{fungible}
to register fungible output worth 129 sat - redeem
{1, 2, 4, 16, 64}
to register change output worth 86 sat
Finally, we can introduce long lived fee tokens to this round in order to reduce the hamming weight of change outputs.
If the round succeeds, then Alice will be able to claim persistent tokens, that can be used to cover fees in future rounds.
Instead of the output worth 86 sat, assuming amounts should be rounded to a multiple of 16 satoshi:
- redeem
{1, 64, 16}
to register change output worth 80 sat - redeem
{2, 4}
to equivalent long lived fee tokens
When a round fails, long lived fee tokens must be refunded to clients who did sign (perhaps only after one of the inputs has been double spent with confirmation?)
Not clear how/whether to do blame apart from banning inputs that did not sign. Might be appropriate if transfer
Types are not mutually exclusive, they may be enforced by constraints or just incentivized by fees, and they may determine scheduling related conditions, depending on the goal of the round.
Similar to current round structure, but inputs of a single user are only linkable by amount correlation.
Fee structure could accomodate uniform input/output amount by:
- requiring long lived fee tokens
- requiring fees to be covered by merging with some concurrent sibling round
Change outputs could be allowed or forbidden by some combination of token type.
For (batch) payments, transfers, UTXO consolidation.
No restriction on amounts, can be used to prepare UTXOs for mixing, or for different payment protocols.
Restrictions on input type can provide better fungibility (e.g. arbitrary payments can only be constructed with already mixed inputs, etc), so it makes sense to have different types of arbitrary amount rounds with mixing rounds in between.
The sender registers an output with the receiver's output script.
If recipient script is static, the coordinator may link input in log(n) failed rounds where n is the number of apparent participants by bisecting input set.
This is intended to emulate JoinMarket's patient send.
For low time preference transactions, the sender register an input, and then transfers tokens to the receiver, who register their own outputs.
The sender may also provide an equivalent transaction (possibly payjoin transaction) to the receiver for zero conf security security, which is strictly better than only providing coinjoin tokens (the sender can always cancel by refusing to sign the coinjoin transaction).
Intended to make payjoin, cahoots or bustapay style exchanges possible as part of a coinjoin.
TODO: consider possibility of allowing P2W?SH outputs if it can enable interoperability with atomic swaps, lightning funding, splicing and in general interactive tx construction, and non interactive channels