Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: "public" version of secp256k1_musig_partial_sign to get public key of psig #217

Open
instagibbs opened this issue Feb 28, 2023 · 5 comments · May be fixed by #222
Open

Comments

@instagibbs
Copy link
Contributor

@jonasnick told me to post this for visibility. Invented originally by @ajtowns because he was chagrined by my current solution to the problem at hand.

First, a bit of motivation.

In ln-symmetry(eltoo) channels I have sketched out and implemented as well as other channel constructions, there is a desire to keep channel updates at least in the two party case to half a round trip. Alice sends an update with a signature, and Bob can immediately forward any HTLCs required without delay. This improves latency, and simplifies the channel state machine.

These types of channels have two stages of presigned transactions, in the ln-symmetry case, we have two symmetric transactions per channel update:

  1. update transaction, which are posted during the contention period
  2. settlement transaction, which is posted after a relative timeout when update transactions cease to be posted

If Alice wants to send an update to Bob, she cannot send both a signature for the update and settlement transactions, since Bob could take the update transaction to chain, and withhold a signature for the follow-up settlement transaction. The safe course is to send the settlement signature first, wait for Bob to hand his update signature, then respond with her update signature, increasing the RTT to 1.5 instead of 0.5 RTT.

Here's an alternative approach using adaptor signatures that I believe achieves the original goal:

  1. Update transaction has a 2-of-2 OP_CSA script, one key for Alice, one for Bob
  2. Settlement transaction has a 2-party MuSig key
  3. Nonces are preshared always
  4. Alice generates a channel state update, generating unsigned update and settlement transactions
  5. Alice calls secp256k1_musig_partial_simulate on the settlement transaction, which allows Alice to "simulate" partial signing routine for any public key in the session, outputting s*G rather than s since that can be computed for any party.
  6. Alice then uses s*G as the adaptor for her update transaction's signature (1-of-1 MuSig session?)
  7. Alice sends channel update along with her partial sig and presignature to Bob
  8. If Bob goes to chain with the update transaction, he leaks his s, allowing Alice to complete the settlement transaction.

TL;DR: the adapter signature is a fair exchange of Alice's update signature and Bob's settlement partial signature.

@jonasnick
Copy link
Contributor

Thanks for the writeup. I can see why this feature would be useful. What would be important to know is whether you actually want to "simulate" a MuSig partial signature or just a BIP340 signature. It seems like the settlement transaction could just as well use a 2-of-2 CSA script. There are pro's and con's of course to either approach, but I'm wondering why you don't use one approach consistently in both update and settlement transaction. We don't have BIP 340 adaptor sigs right now (#191)

Alice then uses s*G as the adaptor for her update transaction's signature (1-of-1 MuSig session?)

I think Alice can just use a BIP 340 adaptor sig (once there is library support).

@ajtowns
Copy link

ajtowns commented Feb 28, 2023

What would be important to know is whether you actually want to "simulate" a MuSig partial signature or just a BIP340 signature. It seems like the settlement transaction could just as well use a 2-of-2 CSA script.

The idea is that you use "2-of-2 CSA" to spend the funding output via the update tx in order to have an adaptor signature that will reveal a secret if completed while only needing a single communication round, but you use musig2 everywhere else in order to reduce on-chain footprint. Adding the 2-of-2 path for spending the funding output is free -- in normal circumstances the funding output is in the utxo set so doesn't need APO abilities, and we can just do musig2 via the key path. Providing a 2-of-2 CSA path when spending the update tx via the settlement tx would add 32+ witness bytes to every settlement tx (due to going from 1 to 2 tapscripts, which I think would be the most efficient way of doing this).

With two CSA scripts, Alice would calculate Bob's signature for Alice's settlement tx T = tG = RB + H(RB, B, m)B then would give Bob an adaptor signature for Bob's update tx, sG = R + H(R + T, A, m)A. If Bob completes that as (s+t, R+T), Alice calculates t = s+t - s and has (t, RB) as Bob's signature for her settlement tx. Note that RB here is a pre-shared nonce, so I think this would want to be a 1-of-1 musig2 session, effectively?

But aiming for minimal onchain footprint, we change the settlement tx to use musig2, so the signature Alice needs for her settlement tx becomes sG = RA + RB + H(RA + RB, A + B, m)(A+B), and Bob''s contribution is T = tG = RB + H(RA+RB, A+B, m)B. Everything else is the same, the only difference is that instead of being T = R + H(R+X, P, m)P the pubkey is tweaked as well, giving T = R + H(R+X, P+Y, m)P. And the pubkey being tweaked then brings in the xonly complications that musig already deals with.

@jonasnick
Copy link
Contributor

Ok thanks. That explains why musig_partial_simulate is preferable over schnorr_simulate.

I think this would want to be a 1-of-1 musig2 session

Ah, you're calling this a "1-of-1 MuSig2 session" because, similar to MuSig, nonce generation and signing are two separate steps. Using the libsecp-zkp musig module should work for this, but it would preferably be done with a much simpler API.

@ajtowns
Copy link

ajtowns commented Mar 2, 2023

Ok thanks. That explains why musig_partial_simulate is preferable over schnorr_simulate.

👍

I think this would want to be a 1-of-1 musig2 session

Ah, you're calling this a "1-of-1 MuSig2 session" because, similar to MuSig, nonce generation and signing are two separate steps. Using the libsecp-zkp musig module should work for this, but it would preferably be done with a much simpler API.

Well, the key bit is you're committing to a nonce in advance, with a (possible) adversary being able to choose the message for you to sign after knowing your nonce commitment. I guess I'm also calling it "1-of-1 musig2" because I'm hoping it falls under the musig security proof rather than needing its own :)

@jonasnick jonasnick linked a pull request Mar 3, 2023 that will close this issue
@real-or-random
Copy link
Collaborator

Well, the key bit is you're committing to a nonce in advance, with a (possible) adversary being able to choose the message for you to sign after knowing your nonce commitment. I guess I'm also calling it "1-of-1 musig2" because I'm hoping it falls under the musig security proof rather than needing its own :)

Without having understood the entire use case: Yes, sending out the nonce and only then getting the message, is covered by the MuSig2 security proof as "1-of-1" effectively.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants