From: ZmnSCPxj <ZmnSCPxj@protonmail•com>
To: Chris Belcher <belcher@riseup•net>
Cc: Bitcoin Protocol Discussion <bitcoin-dev@lists•linuxfoundation.org>
Subject: Re: [bitcoin-dev] Detailed protocol design for routed multi-transaction CoinSwap
Date: Fri, 21 Aug 2020 04:20:23 +0000 [thread overview]
Message-ID: <WtKtWCdqIFVTTqw9-EggdsTIo6ejfP8my868MYyAqO8FUboiXWZUd0hw2PyvEKZNJxqAWJ_9BnOllAGEuUYYcA654amKTC4MSmO3TO4A7pU=@protonmail.com> (raw)
In-Reply-To: <e8ca67be-d07c-3f2e-4318-0d2bab061dd9@riseup.net>
Good morning,
> Right, so if the taker uses only a single maker then they must have more
> than one UTXO.
Spending one UTXO is fine, it is generating a transaction that has one output that is problematic.
What needs to happen is that this single UTXO is spent to two outputs: the CoinSwap 2-of-2 and the change output.
This is because intermediate makers will have very high likelihood of generating such a pattern (it is unlikely they have an exact amount that a taker would require of them), and the occassional maker might have a very large UTXO that it can use for similar purposes.
One thing a taker can do would be to multipath its CoinSwap, i.e. it spends any number of UTXOs and creates two outputs, which are actually two separate CoinSwap 2-of-2s to different makers.
As each maker is unaware of the other, this should be similar to the case where the maker is an intermediate hop and is getting its incoming HTLC from another maker, which is unlikely to have a precise amount and will thus have a transaction that has two outputs, the 2-of-2 CoinSwap and the change.
>
> This leak in the case of a taker spending a single UTXO also happens
> when the taker needs to create a branching route. I described this in my
> original email "Design for a CoinSwap implementation for massively
> improving Bitcoin privacy and fungibility" under the section "Combining
> multi-transaction with routing" (the second diagram).
>
> I think this might be unavoidable. If the taker has just one UTXO they'd
> be much better off using multiple makers for this reason.
>
> > - The makers can try timing the communications lag with the taker.
> > The general assumption would be that more makers == more delay in taker responses.
> >
>
> Sounds like adding random delays would fix this. The protocol already
> involves waiting for a confirmation (average waiting time 10 minutes, at
> best) and might involve more confirmations for extra security and
> privacy. So adding a random delay of up to 0.5-1 minutes shouldnt cause
> too many issues.
> Also the Tor network can be pretty laggy so that might add enough noise
> anyway.
Indeed, this seems a bit of a long shot for the surveilling maker.
> > > === Miner fees ===
> > > Makers have no incentive to pay any miner fees. They only do
> > > transactions which earn them an income and are willing to wait a very
> > > long time for that to happen. By contrast takers want to create
> > > transactions far more urgently. In JoinMarket we coded a protocol where
> > > the maker could contribute to miner fees, but the market price offered
> > > of that trended towards zero. So the reality is that takers will pay all
> > > the miner fees. Also because makers don't know the taker's time
> > > preference they don't know how much they should pay in miner fees.
> > > The taker will have to set limits on how large the maker's transactions
> > > are, otherwise makers could abuse this by having the taker consolidate
> > > maker's UTXOs for free.
> >
> > Why not have the taker pay for the first maker-spent UTXO and have additional maker-spent UTXOs paid for by the maker?
> > i.e. the taker indicates "swap me 1 BTC in 3 bags of 0.3, 0.3, and 0.4 BTC", and pays for one UTXO spent for each "bag" (thus pays for 3 UTXOs).
> > Disagreements on feerate can be resolved by having the taker set the feerate, i.e. "the customer is always right".
> > Thus if the maker has to spend two UTXOs to make up the 0.4 BTC bag, it pays for the mining fees for that extra UTXO.
> > The maker can always reject the swap attempt if it has to spend multiple UTXOs and would lose money doing so if the taker demands a too-high feerate.
>
> Having the taker pay for just one UTXO will have an unfortunate side
> effect of resulting in the maker's money being split up into a large
> number of UTXOs, because every CoinSwap they take part in has an
> incentive to increase their UTXO count by one. At the start of
> JoinMarket this was an issue where then a taker wanting to CoinJoin a
> large would come along and the result would be a huge CoinJoin
> transaction with many many small inputs. Perhaps the taker could pay for
> 2-3 UTXOs to counteract this. (Of course the exact number would be
> configurable by the taker user, but defaults usually don't get changed).
>
> I'm still not convinced with having makers contribute to miner fees. In
> JoinMarket we tried to get makers to contribute a little to miner fees
> and simply they never did in any meaningful way. The market has spoken.
> In terms of incentives makers are happy to wait a very long time, if we
> assume they're just HODLers then even if they earn a few thousand
> satoshis that's good.
>
> > > == Contract transaction definitions ==
> > > Contract transactions are those which may spend from the 2-of-2 multisig
> > > outputs, they transfer the coins into a contract where the coins can be
> > > spent either by waiting for a timeout or providing a hash preimage
> > > value. Ideally contract transactions will never be broadcast but their
> > > existence keeps all parties honest.
> > > M~ is miner fees, which we treat as a random variable, and ultimately
> > > set by whichever pre-signed RBF tx get mined. When we talk about the
> > > contract tx, we actually mean perhaps 20-30 transactions which only
> > > differ by the miner fee and have RBF enabled, so they can be broadcasted
> > > in sequence to get the contract transaction mined regardless of the
> > > demand for block space.
> >
> > The highest-fee version could have, in addition, CPFP-anchor outputs, like those being proposed in Lightning, so even if onchain fees rise above the largest fee reservation, it is possible to add even more fees.
> > Or not.
> > Hmm.
>
> I think RBF transactions are better because they ultimately use less
> block space than CPFP.
>
> There seems to be very little cost in signing many additional
> precomputed RBF transactions. So the taker and makers could sign
> transactions all the way up to 10000 sat/vbyte. I think this doesn't
> apply to Lightning, because bandwidth seems to be more constrained
> there: even a tiny micropayment for 1 satoshi would require 10x or 100x
> more bandwidth if every lightning htlc used precomputed RBF.
I was wondering if it would be a good idea actually if the **largest** fee RBF transaction had additional CPFP anchor outputs, not saying to replace the entire group of RBF transactions entirely.
This is just in case of a very sudden increase in feerates that goes beyond the largest that was prepared beforehand.
"You cannot predict the feerates future" is becoming something of a mantra over in Lightning, though I guess a "big enough" spread of RBF transactions would work in practice >99% of the time.
> > Another thought: later you describe that miner fees are paid by Alice by forwarding those fees as well, how does that work when there are multiple versions of the contract transaction?
>
> Alice only pays the miner fees for the funding transactions, not the
> contract transaction. The miner fees for the contract transactions are
> taken from the contract balance. The contract transactions are 1-input
> 1-output, and whoever ends up with the money will be the one who paid
> the miner fee.
Okay, that is much clearer.
> > > (Alice+timelock_A OR Bob+hash) = Is an output which can be spent
> > > either with Alice's private key
> > > after waiting for a relative
> > > timelock_A, or by Bob's private key by
> > > revealing a hash preimage value
> >
> > The rationale for relative timelocks is that it makes private key turnover slightly more useable by ensuring that, after private key turnover, it is possible to wait indefinitely to spend the UTXO it received.
> > This is in contrast with absolute timelocks, where after private key turnover, it is required to spend received UTXO before the absolute timeout.
> > The dangers are:
> >
> > - Until it receives the private key, if either of the incoming or outgoing contract transactions are confirmed, every swap participant (taker or maker) should also broadcast the other contract transaction, and resolve by onchain transactions (with loss of privacy).
> > - After receiving the private key, if the incoming contract transaction is confirmed, it should spend the resulting contract output.
> > - It is possible to steal from a participant if that participant goes offline longer than the timeout.
> > This may imply that there may have to be some minimum timeout that makers indicate in their advertisements.
> > - The taker can detect if the first maker is offline, then if it is offline, try a contract transaction broadcast, if it confirms, the taker can wait for the timeout; if it times out, the taker can clawback the transaction.
> > - This appears to be riskless for the taker.
> > - Against a similar attack, Lightning requires channel reserves, which means the first hop never gains control of the entire value, which is a basic requirement for private key turnover.
> > - On the other hand, the taker has the largest timeout before it can clawback the funds, so it would wait for a long time, and at any time in between the first maker can come online and spend using the hashlock branch.
> > - But the taker can just try on the hope it works; it has nothing to lose.
> > - This attack seems to be possible only for the taker to mount.
> > Other makers on the route cannot know who the other makers are, without cooperation of the taker, who is the only one who knows all the makers.
> > - On the other hand, the last maker in the route has an outgoing HTLC with the smallest timelock, so it is the least-risk and therefore a maker who notices its outgoing HTLC has a low timeout might want to just do this anyway even if it is unsure if the taker is offline.
>
> Every off-chain protocol like this has the livelyness requirement. Each
> party must always be watching the chain and be ready to broadcast
> something in response. I'm not sure how any of this relates to the
> choice of relative vs absolute time locks.
Absolute timelocks mean that you can set a timer where you put your node to sleep without risk of loss of funds (basically, once the absolute timelocks have resolved, you can forget about CoinSwaps).
But I think the ability to spend at any time would be better, and getting 100% online 144 blocks a day, 2016 blocks a retargeting period is becoming more and more feasible.
>
> You're right that attempting such an move by the taker is riskless, but
> its not costless. The taker sets up the entire CoinSwap protocol because
> they wanted more privacy; but if the taker broadcasts the Alice contract
> transaction and waits for the timeout, then all they've achieved is
> spent miner fees, got their own coin back and draw attention to it with
> the unusual HTLC script. They've achieved no benefit from what I see, so
> they won't do this. Any taker or maker who attempts anything like this
> will be spending miner fees.
They would be spending miner fees *from the funds being stolen*, thus still costless.
In particular, let us imagine a simple 1-maker swap.
* The taker and the maker complete the swap.
* The taker now has possession of:
* The private key for its incoming HTLC.
* The pre-signed contract transaction for its outgoing HTLC.
* The taker spends from its incoming HTLC using the private key.
* The maker ignores this, because this is just normal operation.
* Fees paid for this is not an **additional** cost, because a taker that wants to put its freshly-private funds into cold storage will do this anyway.
* The taker gets a fresh, private coin from this incoming HTLC, so it gets the privacy it paid for.
* The taker waits for the incoming-HTLC-spend to confirm.
* The taker broadcasts the pre-signed contract transaction, in the hope that the maker is offline.
* The fees paid for this are from the contract transaction that the taker is trying to steal.
Even if the theft attempt fails, the taker has already gotten its private money out, and is thus not risking anything.
* Semantically, the outgoing HTLC is already "owned" by the maker (the maker has private key to it).
* Thus, the taker commits an action that the maker pays fees for!
* The maker cannot react except to spend via the hashlock branch.
In particular, because the taker-incoming (maker-outgoing) UTXO is already spent, it cannot retaliate by also broadcasting the contract transaction of the taker-incoming (maker-outgoing) HTLC.
* The theft succeeds (the timelock passes) because the maker happens to be offline for that long.
* This is "free money" to the taker, who has already gotten what it paid for --- private money in cold storage --- from the CoinSwap.
* Even if the stolen fund reveals the contract, the taker can re-acquire privacy for the funds it stole for free, by paying for --- wait for it --- another CoinSwap for its swag.
Using an absolute timelock (implemented by a `nLockTime` tx directly off the 2-of-2, ***not*** `OP_CHECKLOCKTIMEVERIFY`), plus a Scriptless Script 2p-ECDSA (again implemented by a tx directly off the 2-of-2) instead of a hashlock, seems to avoid this, I think, at the cost of reducing the utility of private key turnover by having a deadline where the private key *has to* be used.
This is because there is no contract transaction that is share-owned by both participants in the swap.
Instead there are two distinct transactions with separate ownerships: a timeout tx (that is owned by the participant paying for the HTLC/PTLC) and a claim tx (that is owned by the participant accepting the HTLC/PTLC).
> > - Participants might want to spend from the UTXO to a new address after private key turnover anyway.
> > Makers could spend using a low-fee RBF-enabled tx, and when another request comes in for another swap, try to build a new funding tx with a higher-fee bump.
> >
>
> I don't think this will happen very often. It's spending money on block
> space for not much benefit. If the maker ever decides to shut down their
> maker they can transfer all their coins in HTLCs to single-sig
> transactions exclusively controlled by them, but in normal operation I
> doubt it will happen.
Accidents can happen (e.g. somebody trips over the power cord of the maker hardware), so hedging this somewhat might give a useful safety net.
>
> The attack I describe works because Alice chooses both MA~ and MB~. The
> attack is that Alice chooses MA~ to be a very low value (e.g. 1 sat/vb)
> and chooses MB~ to be a very high value (e.g. 1000 sat/vb). Then Alice
> intentionally sabotages the CoinSwap and forces it to go to the timeout
> case, what happens is that Bob's wallet balance falls by much more than
> Alice's, because MB~ > MA~. So this is a DOS attack: Alice can waste
> Bob's resources without wasting much of her own.
Ah, right, that is clearer.
> > > == EC tweak to reduce one round trip ==
> > > When two parties are agreeing on a 2-of-2 multisig address, they need to
> > > agree on their public keys. We can avoid one round trip by using the EC
> > > tweak trick.
> > > When Alice, the taker, downloads the entire offer book for the liquidity
> > > market, the offers will also contain a EC public key. Alice can tweak
> > > this to generate a brand new public key for which the maker knows the
> > > private key. This public key will be one of the keys in the 2-of-2
> > > multisig. This feature removes one round trip from the protocol.
> > > q = EC privkey generated by maker
> > > Q = q.G = EC pubkey published by maker
> > > p = nonce generated by taker
> > > P = p.G = nonce point calculated by taker
> > > R = Q + P = pubkey used in bitcoin transaction
> > > = (q + p).G
> >
> > Whoa whoa whoa whoa.
> > All this time I was thinking you were going to use 2p-ECDSA for all 2-of-2s.
> > In which case, the private key generated by the taker would be sufficient tweak to blind this.
> > In 2p-ECDSA, for two participants M = m * G; T = t * G, the total key is m * t * G = m * T = t * M.
> > Are you going to use `2 <T> <Q+P> 2 OP_CHECKMULTISIG` instead of 2p-ECDSA?
> > Note that you cannot usefully hide among Lightning mutual closes, because of the reserve; Lightning mutual closes are very very likely to be spent in a 1-input (that spends from a 2-of-2 P2WSH), 2-output (that pays to two P2WPKHs) tx.
>
> Yes, I intend for 2p-ECDSA to be used eventually, but for the first
> version I'll only implement regular multisigs with OP_CHECKMULTISIG.
> Once all the other details of this protocol are implemented correctly
> and mostly-bug-free then 2p-ECDSA can be added. It can be added in the
> protocol steps 0-1, 3-5 and 7-9.
Okay, that is clearer.
I think 2p-ECDSA should be first priority after getting a decent alpha version.
> This document also doesn't talk about PayJoin-with-CoinSwap, but that
> can be added later too.
2p-ECDSA with Scriptless Script potentially gives a lot more privacy than any PayJoin IMO, due simply to the much larger anonymity set, and there are enough chain-analysis-heuristic-breaking shenanigans we can implement with plain CoinSwap, I think.
Regards,
ZmnSCPxj
next prev parent reply other threads:[~2020-08-21 4:20 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-11 12:05 Chris Belcher
2020-08-20 11:17 ` ZmnSCPxj
2020-08-20 15:28 ` Nadav Kohen
2020-08-20 21:38 ` ZmnSCPxj
2020-08-20 22:37 ` Chris Belcher
2020-08-20 22:15 ` Chris Belcher
2020-08-21 4:20 ` ZmnSCPxj [this message]
2020-08-21 9:47 ` Chris Belcher
2020-08-22 1:09 ` ZmnSCPxj
2020-08-24 19:30 ` Antoine Riard
2020-08-25 3:16 ` ZmnSCPxj
2020-09-03 9:00 ` Chris Belcher
2020-09-03 9:45 ` ZmnSCPxj
2020-09-03 10:50 ` Chris Belcher
2020-09-03 23:39 ` ZmnSCPxj
2020-09-05 2:45 ` ZmnSCPxj
2020-09-05 1:10 ` Antoine Riard
2020-09-05 2:29 ` ZmnSCPxj
2020-08-29 22:03 ` Chris Belcher
2020-08-30 13:38 ` ZmnSCPxj
2020-09-05 1:07 ` Antoine Riard
2020-09-06 3:06 ` seid Mohammed
2020-10-03 10:36 ` [bitcoin-dev] Detailed protocol design for routed multi-transaction CoinSwap appendium Chris Belcher
2020-10-03 13:31 ` ZmnSCPxj
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='WtKtWCdqIFVTTqw9-EggdsTIo6ejfP8my868MYyAqO8FUboiXWZUd0hw2PyvEKZNJxqAWJ_9BnOllAGEuUYYcA654amKTC4MSmO3TO4A7pU=@protonmail.com' \
--to=zmnscpxj@protonmail$(echo .)com \
--cc=belcher@riseup$(echo .)net \
--cc=bitcoin-dev@lists$(echo .)linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox