bitcoin-teleport / teleport-transactions

CoinSwap implementation
Other
236 stars 70 forks source link

Implement PTLC scripts #37

Open GeneFerneau opened 3 years ago

GeneFerneau commented 3 years ago

Point Time Locked Contracts (PTLC) scripts allow for swaps to look like normal transactions. Especially with Taproot, Schnorr signatures and tapscripts greatly increase the ability to blend into the crowd (enhancing user privacy). PTLCs can also be implemented with ECDSA signatures, though the setup and cryptography are more complex.

PTLCs, by using adaptor signatures, also remove the necessity of manually transferring a secret key (hash_preimage) between the maker and taker. This simplifies, and increases the security of the protocol.

Here is a basic, work-in-progress outline of how a PTLC protocol would work with coinswaps:

CoinSwap PTLC protocol

GeneFerneau commented 3 years ago

I'm currently working on an implementation. This issue is to track progress, and open discussion over the implementation.

chris-belcher commented 2 years ago

If I understand right, your scheme only works if the coinswap addresses are schnorr/taproot addresses.

That would not provide us with a very big anonymity set. I expect adoption of taproot addresses to be very slow (more details here https://gist.github.com/chris-belcher/9144bd57a91c194e332fb5ca371d0964#ecdsa-2p third paragraph).

I think a much better way to use PTLCs is to use schnorr to replace what are currently called contract_redeemscripts in the code. That would mean the coinswap addresses could be ecdsa-2p, but the contract addresses would be schnorr, and so schnorr would only hit the blockchain in the backout situation and not in the normal situation where the coinswap proceeds successfully.

Another thing, do you have any thoughts on the design for how the timelock branch would work in your design? i.e. what happens if one of the parties disappears leaving the coins stuck in the musig address.

GeneFerneau commented 2 years ago

your scheme only works if the coinswap addresses are schnorr/taproot addresses

I only described Schnorr-Taproot for brevity. With some small changes, the scheme also supports ECDSA-2P.

That would not provide us with a very big anonymity set

I agree that Schnorr would be a smaller anonymity set, but also fewer cryptographic assumptions. I think providing both options to users with good explanations of the trade-offs provides more freedom.

Essentially, the partial Musig(2) signature and adaptor signature can be swapped with their equivalent in ECDSA-2P scheme.

so schnorr would only hit the blockchain in the backout situation and not in the normal siguation where the coinswap proceeds successfully

Not sure what you mean, can you expand on the dual ECDSA-2P/Schnorr-Taproot design? My thinking was about supporting both PTLC ECDSA-2P and Schnorr designs, giving an option to the user on which to use.

do you have any thoughts on the design for how the timelock branch would work in your design?

I've thought about it, and have a working branch that is very much a work in progress. Here is the current impl for the tapscript redeemscript

The backout contract uses the timelock key in a very similar way to the current timelock branch in the current contract_redeemscript. There are two TapBranches in the TapScript tree, one using the timelock contract, and one branch that is unspendable (since there is only one spendable condition for the TapScript contract in this case).

Still working on how to encode the taproot contract, since the rust-bitcoin taproot support is still a work in progess, as well. Pretty sure my current encoding is incorrect, so will continue to review the relevant BIPs, and update as taproot support is merged into rust-bitcoin.

what happens if one of the parties disappears leaving the coins stuck in the musig address

If the taker disappears, the maker uses the TapScript spending path, and recovers the funds after the timelock. If the maker disappears, no taker funds have been locked. The recovery conditions should be identical to current redeemscripts.

chris-belcher commented 2 years ago

If routed coinswap has a small anonymity set, then essentially all privacy is lost. This is because if an adversary can identify coinswap addresses then they can completely unmix the whole thing. For more details for why this is true see https://zmnscpxj.github.io/bitcoin/multiswap.html especially the section "Value-based Directionality". That page also interestingly explains why this isn't true for JoinMarket coinjoin. Because coinswap depends so much on having a high anonymity set for coinswap addresses, then I reckon your plan of using schnorr addresses as coinswap addresses is useless. Schnorr/taproot is only useful for the contracts not coinswap addresses. It doesn't provide more freedom, it provides flawed privacy.

I'd recommend you spend your time on learning about and working on ECDSA-2P instead, as that is the only way forward IMO. I've posted my short notes here in case they're helpful https://github.com/bitcoin-teleport/teleport-transactions/issues/39

You design which uses OP_CSV in a tapscript has a downside that it will be visible to everyone when the timelock branch is used, and that can be exploited by an adversary. Such an adversary could pretend to be a taker and open coinswaps with every maker, and then abort the protocol forcing every maker to use the timelock branch to get their money back but also marking their coins with this unusual tapscript locktime. The unusual tapscript makes it much easier to unmix later coinswaps. A better solution is to use nSequence. That field can also act as a relative locktime, and if taproot wallets use it for anti-fee-sniping then there would be a good enough anonymity set. That was the purpose of my BIP proposal (https://gist.github.com/chris-belcher/903feab321bf41055c91eaec46581e89) which has already been implemented in sparrow wallet.

When I talked about ECDSA-2P/Schnorr-Taproot design I just meant a scheme where the coinswap addresses are ecdsa addresses because they use ecdsa-2p, but the contract transactions use schnorr instead of contract_redeemscript, and so use adaptor signatures instead of hashlocks and use nSequence instead of OP_CSV timelocks.

GeneFerneau commented 2 years ago

If routed coinswap has a small anonymity set, then essentially all privacy is lost.

Agreed, but using Schnorr-Taproot would be indistinguishable from all other Schnorr-Taproot transactions in the happy path (keypath spend).

For more details for why this is true see https://zmnscpxj.github.io/bitcoin/multiswap.html

This is a critique of a particular CoinSwap implementation that does little to obfuscate payment amounts. With the tiered, routed CoinSwap protocol you've proposed in your developer notes, this would be less of a problem, no?

After a first reading, I don't see anything in ZmnSCPxj's critique that screams "never use Taproot, anonymity too smol".

Because coinswap depends so much on having a high anonymity set for coinswap addresses, then I reckon your plan of using schnorr addresses as coinswap addresses is useless.

With plans to implement PTLCs for Lightning as well (ostensibly using Taproot), the anonymity set is potentially pretty large. Even with the TapScript timelock spend (revealing the script), we could converge on whatever convention Lightning uses, or some other standard yet to be proposed. Hopefully we can have standard PTLC to increase the anonymity set even more.

There are also very likely to be even more use cases for Taproot transactions, which would make distinguishing CoinSwap addresses even harder.

Hardly seems useless to me. Especially with keypath spends, the majority of the time a script spend path would never even be revealed. Something that is impossible with non-Taproot transactions.

You design which uses OP_CSV in a tapscript has a downside that it will be visible to everyone when the timelock branch is used

Your current design with the contract_redeemscript uses OP_CSV, which is where I took the TapScript impl from, so I don't see your point.

Your script is visible to all from the moment the transaction hits the blockchain, not just when the timelock is used like in a TapScript spend.

When I talked about ECDSA-2P/Schnorr-Taproot design I just meant a scheme where the coinswap addresses are ecdsa addresses because they use ecdsa-2p, but the contract transactions use schnorr instead of contract_redeemscript, and so use adaptor signatures instead of hashlocks and use nSequence instead of OP_CSV timelocks.

I have no idea how you would use ECDSA for the address, but then use Schnorr-Taproot for contract transactions. What does that even mean?

AFAIU, there is no way to mix the two in a single transaction. Are you talking about two separate transactions: one paying to an ECDSA-2p address, and one paying to a Schnorr address?


I'm not anti-ECDSA-2p, and have done work on implementing some of the cryptographic primitives used for the protocol. I think having ECDSA-2p for the short-term definitely has a much larger anonymity set, and is a good thing to use.

We should definitely implement ECDSA-2p PTLC contracts.

Providing a good use-case for Schnorr-Taproot PTLCs in CoinSwap will also help to increase Taproot usage, growing the anonymity set. I know it is somewhat of a chicken-and-egg problem, which is why I want to implement both, and give users the option to choose.

For users with heightened threat models, the reduced anonymity set of Schnorr probably isn't worth it, and they might prefer ECDSA-2p based PTLCs. For those with a lower threat model, the lower anonymity set of Schnorr based PTLCs may be acceptable.

Informing users of the tradeoffs gives them the opportunity to make that choice.

moneyball commented 2 years ago

@chris-belcher is the right way to think about the size of the anon set the # of identical scripts in the UTXO set? What threshold do you feel is needed for taproot scripts to be usable? My hope is that PLTCs are adopted quickly in LN and growth of LN would accelerate timelines for a large anon set using taproot.

chris-belcher commented 2 years ago

The number of lightning channel transactions right now is tiny, only about 0-6 per block. A full block has 2000-3000 transactions. https://txstats.com/dashboard/db/lightning-network?panelId=5&fullscreen&orgId=1

It's a testament to lightning's efficiency that the whole LN ecosystem today can be supported by such a small on-chain footprint.

I remember when segwit was first added to bitcoin, and in the community there were efforts to try to get various big bitcoin users to adopt it. I remember it being like pulling teeth, it seemed to be very difficult to convince exchanges and other places with high volumes to adopt something even if it would save them money on miner fees. And remember taproot provides basically no miner fee savings for single sig users, we would be begging them to switch to taproot just to benefit someone else's privacy, and we've already seen many exchanges are no friends of privacy.

I would like to be wrong about how slowly taproot will be widely adopted. The good thing about ECDSA is it relies on the state of the bitcoin ecosystem today, not on how we hope it will be in future.

My main point from linking ZmnSCPxj's piece is that low anonymity sets arent just an inconvenience, as low anonymity sets allow coinswaps to be completely unmixed. Yes the design uses multiple transactions to try to make amount tracking harder, but with a low anonymity set its not too hard for an adversary to iterate through all the taproot outputs until they find the single combination that adds up to nearly the amount being searched for.

It's not useless, you can work on taproot coinswap addresses if you want. I'm just saying I think the impact will likely be very low and I suggest higher impact things for you to work on, like taproot contract addresses (so that OP_CSV and the like can be hidden all the time) or ECDSA-2P multisig addresses. Yes we can educate users but I believe theres no realistic situation where it makes sense to use the schnorr multisig variant.

I have no idea how you would use ECDSA for the address, but then use Schnorr-Taproot for contract transactions. What does that even mean?

AFAIU, there is no way to mix the two in a single transaction. Are you talking about two separate transactions: one paying to an ECDSA-2p address, and one paying to a Schnorr address?

Yes, its with two transactions. I'll explain:

The coins go into a ECDSA address which is actually a ECDSA-2P 2-of-2 multisig. In the "happy" case the possession of coins is transferred to the other peer using private key handover. In the "unhappy" case one side broadcasts a pre-signed transaction (right called contract_transaction in the codebase) that sends all the money to a new schnorr address, which can be spent either with a pointlock or a timelock. Because the pointlock and timelock-with-nSequence spends looks indistinguishable to single-sig taproot spends, there will never be any unusual fingerprint on-chain such as a OP_CSV opcode. And because the unhappy case is so rare it doesnt matter that other schnorr addresses are rare on the blockchain: in the vast majority of cases only the "happy" case occurs, where only ECDSA addresses are used.

Note I think we should not implement ECDSA-2P adaptor signatures, because we can get the same thing by using schnorr which is much easier. We only need ECDSA-2P 2of2 multisig.

@moneyball At least to a first approximation counting the output script types in recent transactions/blocks is the best way to analyse it I think. Not UTXO set because that only contains unspent outputs, and contains outputs from years ago before LN or coinswap were created, so theres little point for an adversary to search there. I dont know the exact proportion we need, I'd guess about 30-40% of recent transactions, but right now there are only 0-6 LN channel openings in a block, and full blocks have 2000-3000 transactions.

moneyball commented 2 years ago

Thanks for the good thoughts @chris-belcher! I agree the non-LN motivation to adopt taproot will be weaker than segwit, but I think LN will see strong enough growth that overall the adoption of taproot will exhibit similar timeframes as segwit. I'd expect a 2-4 year timeframe for 30-40% of recent transactions being taproot. If you and the contributors to this project agree with that timeframe, then it is a question of what you believe the timeframe for CoinSwap launch and adoption would be. However, if you/other contributors think my estimates are too rosy, or at least simply just too uncertain, then it makes a stronger case for supporting ECDSA.

GeneFerneau commented 2 years ago

The number of lightning channel transactions right now is tiny, only about 0-6 per block. ... I remember when segwit was first added to bitcoin, and in the community there were efforts to try to get various big bitcoin users to adopt it. I remember it being like pulling teeth, it seemed to be very difficult to convince exchanges and other places with high volumes to adopt something even if it would save them money on miner fees.

I may be too optimistic about adoption of Taproot. The new tech is interesting, and has good privacy properties at sufficient adoption levels.

IMHO, the CoinSwap situation has important differences to SegWit adoption, since exchanges likely won't be the target audience (at least not centralised ones). There are a large number of non-institutional Bitcoin users that love privacy tech. The more tools there are using Taproot, the higher adoption will be.

A number of exchanges have also implemented Lightning now, so if PTLCs are adopted for LN, all those exchanges will update to impl Taproot (or be stuck on last version pre-PTLC).

Ultimately, I want to find a way to safely use Taproot for CoinSwaps, even if that's in the medium-to-long-term.

I would like to be wrong about how slowly taproot will be widely adopted.

I'd like to see widespread adoption, too. Agree that short-term (maybe for a long time) ECDSA-2P provides a larger anonymity set.

Thanks for creating the issue linking research resources. Going back over the research papers, and ZenGo X's libraries. Will leave a reply in the related issue.

My main point from linking ZmnSCPxj's piece is that low anonymity sets arent just an inconvenience

Need to re-read the piece again, and look closer at the short-comings. Would be really nice to find a way to slowly increase the number of Taproot users without compromising privacy.

I think your solution of using ECDSA-2P for the key handover CoinSwap addresses, and Taproot for the contract is a good way to accomplish that.

It's not useless, you can work on taproot coinswap addresses if you want

After your last comment, I looked into ECDSA-2P again. Somewhat switching gears to work on ECDSA-2P, still continuing Taproot research.

Yes, its with two transactions. I'll explain:

The coins go into a ECDSA address which is actually a ECDSA-2P 2-of-2 multisig...

Thank you for the in-depth explanation, that makes more sense now.

Tangent: for the key handover, what do you think about encrypting the private key on the wire? I'd like to not leave that up to the transport layer.

Note I think we should not implement ECDSA-2P adaptor signatures...

Agreed

chris-belcher commented 2 years ago

Tangent: for the key handover, what do you think about encrypting the private key on the wire? I'd like to not leave that up to the transport layer.

I thought about this a bit when writing the current codebase. I think it's not needed, because only one private key is ever sent across the wire, while the other private key in the 2of2 multisig is never ever sent. That single private key is useless without the other one, and so there is never a situation where funds are at risk.

GeneFerneau commented 2 years ago

That single private key is useless without the other one, and so there is never a situation where funds are at risk.

Right, but even XORing with a nonce provides at least some protection. Small holes can lead to big problems. Maybe I'm just overengineering things, idk. Can't think of a practical attack at the moment, just intuition about potential attack vectors.

GeneFerneau commented 2 years ago

Updated the original post with a gist of the protocol.

Still working on details. Added input from related discussions.

Will continue to update as discussion progresses.