BlockstreamResearch / secp256k1-zkp

A fork of libsecp256k1 with support for advanced and experimental features such as Confidential Assets and MuSig2
MIT License
365 stars 207 forks source link

Question: Is it possible to multiply `secp256k1_musig_secnonce * secp256k1_xonly_pubkey`? #267

Closed ssantos21 closed 1 year ago

ssantos21 commented 1 year ago

I'm trying to implement a blinded MuSig2 protocol as suggested in https://github.com/commerceblock/mercury/blob/master/layer/protocol.md#signature-generation.

The protocol considers the aggregated nonce as R_1 = R1_1 + r2_1.G + b1.P, where R1_1 and R2_1 are public nonces (secp256k1_musig_pubnonce), b1 is a secret nonce (blind factor / secp256k1_musig_secnonce) and P is the aggregated public key (secp256k1_xonly_pubkey).

Is it possible to generate b1.P (instead of b1.G) as a public nonce for secret nonce b1 using secp256k1-zkp lib? secp256k1_musig_nonce_gen doesn't seem to support this.

real-or-random commented 1 year ago

Is it possible to generate b1.P (instead of b1.G) as a public nonce for secret nonce b1 using secp256k1-zkp lib? secp256k1_musig_nonce_gen doesn't seem to support this.

No, you'd need to fork the library. Our implementation supports only MuSig2 as specified in BIP327.

blinded MuSig2

Note that this is not at all an "official" variant of MuSig2. (I'm not even sure it actually resembles MuSig2.) We can't vouch for its security. Blind Schnorr signatures (even in the single-signer case) are vulnerable to Wagner's attack when concurrent signing sessions are possible.

ssantos21 commented 1 year ago

Thanks for the answer.

So I forked this library and added the blinding factor. Regarding the Wagner's attack, as blinded signature is intended to be used on statechain servers, it might be mitigated by the client committing the values of the blinding nonce used (labeled f) and the value of R2 used in a signing session to the server before the server responds with their value of R1.

The scheme is s = (k1 + b⋅k2 + e⋅a⋅d) + f*P mod n , where f is the blinding factor and P is the aggregated public key. And the challenge is e1 = e + f or e1 = e - f depending on the XOR(final nonce parity, aggregated public key parity). The function for this is: secp256k1_blinded_musig_nonce_process

And I also added two new functions so that the server doesn't know the aggregated public key and the key aggregation coefficient. The client sends the secret key negation and keyaggcoef information to the server. secp256k1_musig_get_keyaggcoef_and_negation_seckey secp256k1_blinded_musig_partial_sign