Improve swap-in protocol with taproot and musig2 #560
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR implements an evolution of our p2swh-based swap-in that uses Musig2 and taproot for better privacy and lower on-chain fees.
Our swap-in protocol becomes
user key + server key OR user refund key + delay
, and is implemented with taproot which provides a clean separation between the mutual use case (handled by the internal key, which is a Musig2 aggregation of the user's and server's key) and the refund case (handled by a taproot script with a single leaf: the refund script).Musig2 requires both parties to generate secret nonces and exchange public nonces before they can compute partial Musig2 signatures, which can then be combined into a single Schnorr signature:
TxComplete
, which includes public nonces for all swap-in inputsTxSignatures
, which includes partial Musig2 signatures for all swap-in inputsNonces are never persisted and their lifecycle is tied to the interactive tx session lifecycle: while the session is alive, it remembers nonces that it sent before i.e if
TxComplete
is sent several times, nonces for the same input id will be re-used. I believe that it is safe since they will be used only once for signing.A specific user refund key is used in the refund script: this allows us to easily rotate swap-in addresses (each time we change th user refund key) and generate a single taproot descriptor that will allow bitcoin core to find and spend (after the refund delay) all swap-in transactions for a given user (i.e for a given phoenix wallet).
This is a first step towards fixing ACINQ/phoenix#403: this new scheme makes swap-in address rotation easy to implement but this is out of the scope of this PR.
Swap-in addresses are now regular
p2tr
addresses, and swap-in transactions become indistinguishable from otherp2tr
transactions.And since spending swap-in inputs requires a single 64 bytes Schnorr transaction (instead of 2 73 bytes DER transaction + a 77 bytes redeem script), the weight of a swap-in input is reduced by 40% for cheaper on-chain fees.