-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge #1479: Add module "musig" that implements MuSig2 multi-signatur…
…es (BIP 327) 168c920 build: allow enabling the musig module in cmake (Jonas Nick) f411841 Add module "musig" that implements MuSig2 multi-signatures (BIP 327) (Jonas Nick) 0be7966 util: add constant-time is_zero_array function (Jonas Nick) c8fbdb1 group: add ge_to_bytes_ext and ge_from_bytes_ext (Jonas Nick) 85e224d group: add ge_to_bytes and ge_from_bytes (Jonas Nick) Pull request description: EDIT: based on #1518. Closes #1452. Most of the code is a copy from [libsecp256k1-zkp](https://github.com/BlockstreamResearch/secp256k1-zkp). The API added in this PR is identical with the exception of two modifications: 1. I removed the unused `scratch_space` argument from `secp256k1_musig_pubkey_agg`. This argument was intended to allow using `ecmult_multi` algorithms for key aggregation in the future. But at this point it's unclear whether the `scratch_space` object will remain in its current form (see #1302). 2. Support for adaptor signatures was removed and therefore the `adaptor` argument of `musig_nonce_process` was also removed. In contrast to the module in libsecp256k1-zkp, the module is non-experimental. I slightly cleaned up parts of the module, adjusted the code to the new definition of the VERIFY_CHECK macro and applied some simplifications that were possible because the module is now in the upstream repo (`ge_from_bytes`, `ge_to_bytes`). You can follow the changes I made to the libsecp256k1-zkp module at https://github.com/jonasnick/secp256k1-zkp/commits/musig2-upstream/. ACKs for top commit: sipa: reACK 168c920 real-or-random: reACK 168c920 theStack: re-ACK 168c920 Tree-SHA512: e3a599a8d5a466107b9a86f76582b8fb9dc87ec95416c784c3ef39d1c64686e6c739806ed6ba62c91793eb7fa418a6270cf999027ee7bd3dd85c67bc2c74f677
- Loading branch information
Showing
29 changed files
with
4,493 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ ecdh_example | |
ecdsa_example | ||
schnorr_example | ||
ellswift_example | ||
musig_example | ||
*.exe | ||
*.so | ||
*.a | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
Notes on the musig module API | ||
=========================== | ||
|
||
The following sections contain additional notes on the API of the musig module (`include/secp256k1_musig.h`). | ||
A usage example can be found in `examples/musig.c`. | ||
|
||
## API misuse | ||
|
||
The musig API is designed with a focus on misuse resistance. | ||
However, due to the interactive nature of the MuSig protocol, there are additional failure modes that are not present in regular (single-party) Schnorr signature creation. | ||
While the results can be catastrophic (e.g. leaking of the secret key), it is unfortunately not possible for the musig implementation to prevent all such failure modes. | ||
|
||
Therefore, users of the musig module must take great care to make sure of the following: | ||
|
||
1. A unique nonce per signing session is generated in `secp256k1_musig_nonce_gen`. | ||
See the corresponding comment in `include/secp256k1_musig.h` for how to ensure that. | ||
2. The `secp256k1_musig_secnonce` structure is never copied or serialized. | ||
See also the comment on `secp256k1_musig_secnonce` in `include/secp256k1_musig.h`. | ||
3. Opaque data structures are never written to or read from directly. | ||
Instead, only the provided accessor functions are used. | ||
|
||
## Key Aggregation and (Taproot) Tweaking | ||
|
||
Given a set of public keys, the aggregate public key is computed with `secp256k1_musig_pubkey_agg`. | ||
A plain tweak can be added to the resulting public key with `secp256k1_ec_pubkey_tweak_add` by setting the `tweak32` argument to the hash defined in BIP 32. Similarly, a Taproot tweak can be added with `secp256k1_xonly_pubkey_tweak_add` by setting the `tweak32` argument to the TapTweak hash defined in BIP 341. | ||
Both types of tweaking can be combined and invoked multiple times if the specific application requires it. | ||
|
||
## Signing | ||
|
||
This is covered by `examples/musig.c`. | ||
Essentially, the protocol proceeds in the following steps: | ||
|
||
1. Generate a keypair with `secp256k1_keypair_create` and obtain the public key with `secp256k1_keypair_pub`. | ||
2. Call `secp256k1_musig_pubkey_agg` with the pubkeys of all participants. | ||
3. Optionally add a (Taproot) tweak with `secp256k1_musig_pubkey_xonly_tweak_add` and a plain tweak with `secp256k1_musig_pubkey_ec_tweak_add`. | ||
4. Generate a pair of secret and public nonce with `secp256k1_musig_nonce_gen` and send the public nonce to the other signers. | ||
5. Someone (not necessarily the signer) aggregates the public nonces with `secp256k1_musig_nonce_agg` and sends it to the signers. | ||
6. Process the aggregate nonce with `secp256k1_musig_nonce_process`. | ||
7. Create a partial signature with `secp256k1_musig_partial_sign`. | ||
8. Verify the partial signatures (optional in some scenarios) with `secp256k1_musig_partial_sig_verify`. | ||
9. Someone (not necessarily the signer) obtains all partial signatures and aggregates them into the final Schnorr signature using `secp256k1_musig_partial_sig_agg`. | ||
|
||
The aggregate signature can be verified with `secp256k1_schnorrsig_verify`. | ||
|
||
Steps 1 through 5 above can occur before or after the signers are aware of the message to be signed. | ||
Whenever possible, it is recommended to generate the nonces only after the message is known. | ||
This provides enhanced defense-in-depth measures, protecting against potential API misuse in certain scenarios. | ||
However, it does require two rounds of communication during the signing process. | ||
The alternative, generating the nonces in a pre-processing step before the message is known, eliminates these additional protective measures but allows for non-interactive signing. | ||
Similarly, the API supports an alternative protocol flow where generating the aggregate key (steps 1 to 3) is allowed to happen after exchanging nonces (steps 4 to 5). | ||
|
||
## Verification | ||
|
||
A participant who wants to verify the partial signatures, but does not sign itself may do so using the above instructions except that the verifier skips steps 1, 4 and 7. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.