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

Add Musig2 module #716

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Conversation

jlest01
Copy link

@jlest01 jlest01 commented Jul 29, 2024

This PR adds a musig module based on bitcoin-core/secp256k1#1479.
The structure is based on @sanket1729's BlockstreamResearch/rust-secp256k1-zkp#48, but I removed the code related to adaptor signatures.

There is an example file in examples/musig.rs and can be run with cargo run --example musig --features "rand std".
The ffi functions were added to secp256k1-sys/src/lib.rs and the API level functions to the new src/musig.rs file.

Copy link
Collaborator

@Kixunil Kixunil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!!! I would wait until the upstream PR merges (and releases) before merging this but I'm looking forward to it. I gave it a quick look anyway.

// - Key agg cache is valid
// - extra input is 32 bytes
// This can only happen when the session id is all zeros
Err(MusigNonceGenError::ZeroSession)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this should be just panic. It can only happen if someone passes wrong value to dangerous ID creation function.

src/musig.rs Outdated Show resolved Hide resolved
src/musig.rs Outdated Show resolved Hide resolved
src/musig.rs Outdated Show resolved Hide resolved
@tcharding
Copy link
Member

This is a 10 thousand line diff, is something commited that shouldn't be?

@apoelstra
Copy link
Member

It updates the vendored library to bring in the upstream MuSig PR.

@jlest01
Copy link
Author

jlest01 commented Aug 29, 2024

It updates the vendored library to bring in the upstream MuSig PR.

Yes. For now, only the last three commits matter for review purposes.
The others will be discarded when the upstream MuSig PR is merged.

@tcharding
Copy link
Member

Cool, thanks. To clarify this is going to wait till upstream merges before being considered for merge, right? What sort of review are you chasing?

@Kixunil
Copy link
Collaborator

Kixunil commented Aug 30, 2024

@tcharding I will definitely not ack this until it's upstream is released. However I appreciate the experiment/demo.

@jlest01 jlest01 force-pushed the musig2-module branch 3 times, most recently from 0a2361b to 86e2b28 Compare August 30, 2024 22:13
@jlest01
Copy link
Author

jlest01 commented Aug 31, 2024

To clarify this is going to wait till upstream merges before being considered for merge, right? What sort of review are you chasing?

Yes, the idea is to wait for the upstream PR to be merged.
Regarding the review, I mean that the last three commits are the ones that are intended to be merged.

impl MusigSecNonce {
pub fn new() -> Self {
MusigSecNonce([0; MUSIG_SECNONCE_LEN])
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this highly misleading? If it's all-zeros it's not a nonce and thus broken. Where would one need it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as here: #716 (comment)

MusigSecNonce([0; MUSIG_SECNONCE_LEN])
}

/// Don't use this. Refer to the documentation of wrapper APIs in the crate.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation of these methods is intended for the higher-level API implementors not for for end consumers so it should rather properly describe what's going on here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks.

impl_raw_debug!(MusigPubNonce);

impl MusigPubNonce {
pub fn new() -> Self {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks also broken.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as here: #716 (comment)

fn default() -> Self {
Self::new()
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks to me that none of these Defaults should exist. People should just use arrays or MaybeUninit<T> to represent the uninitialized state.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you suggesting something like this ?

let key_agg_cache = MaybeUninit::<ffi::MusigKeyAggCache>::uninit();
let mut key_agg_cache = key_agg_cache.assume_init();

This will cause UB (without MaybeUninit::write).
The reason for pub fn new() is that the internal array is private (ex: pub struct MusigKeyAggCache([c_uchar; MUSIG_KEYAGG_LEN]);), which is consistent with the other structs in the code.


#[repr(C)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MusigPartialSignature([c_uchar; MUSIG_PART_SIG_LEN]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FTR these struct declarations looked wrong but are indeed correct based on the current API.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think they should be changed?

src/musig.rs Outdated
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub enum ParseError {
/// Length mismatch
ArgLenMismatch {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually name these InvalidLength.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks.

@sanket1729
Copy link
Member

Upstream was released yesterday

@apoelstra
Copy link
Member

Can you rebase and format each commit with the nightly formatter? That should fix CI.

@jlest01
Copy link
Author

jlest01 commented Nov 7, 2024

Can you rebase and format each commit with the nightly formatter? That should fix CI.

Yes, done. Thanks.

@tcharding
Copy link
Member

tcharding commented Nov 11, 2024

Patch 1 can be removed now, right? Then your shellcheck CI fail should disappear.

@jlest01
Copy link
Author

jlest01 commented Nov 12, 2024

@tcharding Thanks. But due to the difference in the upstream codebase, secp256k1-sys/vendor-libsecp.sh still needed to be updated.

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 this pull request may close these issues.

5 participants