Skip to content

More Musig2 followups #798

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

Merged
merged 4 commits into from
Jun 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/cross.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
# - i686-pc-windows-msvc # not supported by cross
- i686-unknown-linux-gnu
# - x86_64-apple-darwin # proprietary apple stuff
- x86_64-pc-windows-gnu
# - x86_64-pc-windows-gnu # seems to be broken 2025-06
# - x86_64-pc-windows-msvc # not supported by cross
- x86_64-unknown-linux-gnu
############ Tier 2 with Host Tools
Expand Down
26 changes: 13 additions & 13 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,19 +253,19 @@ jobs:
- name: "Run test on i686"
run: cargo test --target i686-unknown-linux-gnu

WASM:
name: WASM - stable toolchain
runs-on: ubuntu-latest
strategy:
fail-fast: false
# Note we do not use the recent lock file for wasm testing.
steps:
- name: "Checkout repo"
uses: actions/checkout@v4
- name: "Select toolchain"
uses: dtolnay/rust-toolchain@stable
- name: "Run wasm script"
run: ./contrib/wasm.sh
# WASM:
# name: WASM - stable toolchain
# runs-on: ubuntu-latest
# strategy:
# fail-fast: false
# # Note we do not use the recent lock file for wasm testing.
# steps:
# - name: "Checkout repo"
# uses: actions/checkout@v4
# - name: "Select toolchain"
# uses: dtolnay/rust-toolchain@stable
# - name: "Run wasm script"
# run: ./contrib/wasm.sh

NoStd: # 1 job, run no-std test from script.
name: no-std - nightly toolchain
Expand Down
2 changes: 1 addition & 1 deletion examples/musig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fn main() {
let mut pubkeys_ref: Vec<&PublicKey> = pubkeys.iter().collect();
let pubkeys_ref = pubkeys_ref.as_mut_slice();

secp.musig_sort_pubkeys(pubkeys_ref);
secp.sort_pubkeys(pubkeys_ref);

let mut musig_key_agg_cache = KeyAggCache::new(&secp, pubkeys_ref);

Expand Down
6 changes: 4 additions & 2 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1620,6 +1620,8 @@ impl<'de> serde::Deserialize<'de> for XOnlyPublicKey {
impl<C: Verification> Secp256k1<C> {
/// Sort public keys using lexicographic (of compressed serialization) order.
///
/// This is the canonical way to sort public keys for use with Musig2.
///
/// Example:
///
/// ```rust
Expand All @@ -1636,10 +1638,10 @@ impl<C: Verification> Secp256k1<C> {
/// # let mut pubkeys_ref: Vec<&PublicKey> = pubkeys.iter().collect();
/// # let pubkeys_ref = pubkeys_ref.as_mut_slice();
/// #
/// # secp.musig_sort_pubkeys(pubkeys_ref);
/// # secp.sort_pubkeys(pubkeys_ref);
/// # }
/// ```
pub fn musig_sort_pubkeys(&self, pubkeys: &mut [&PublicKey]) {
pub fn sort_pubkeys(&self, pubkeys: &mut [&PublicKey]) {
let cx = self.ctx().as_ptr();
unsafe {
let mut pubkeys_ref = core::slice::from_raw_parts(
Expand Down
11 changes: 9 additions & 2 deletions src/musig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,13 @@ impl SessionSecretRand {
/// a random number generator, or if that is not available, the output of a
/// stable monotonic counter.
pub fn assume_unique_per_nonce_gen(inner: [u8; 32]) -> Self {
assert_ne!(inner, [0; 32], "session secrets may not be all zero");
// See SecretKey::eq for this "constant-time" algorithm for comparison against zero.
let inner_or = inner.iter().fold(0, |accum, x| accum | *x);
assert!(
unsafe { core::ptr::read_volatile(&inner_or) != 0 },
"session secrets may not be all zero",
);

SessionSecretRand(inner)
}

Expand Down Expand Up @@ -281,6 +287,7 @@ impl KeyAggCache {
/// ensures the same resulting `agg_pk` for the same multiset of pubkeys.
/// This is useful to do before aggregating pubkeys, such that the order of pubkeys
/// does not affect the combined public key.
/// To do this, call [`Secp256k1::sort_pubkeys`].
///
/// # Returns
///
Expand Down Expand Up @@ -604,7 +611,7 @@ impl SecretNonce {
///
/// # Warning:
///
/// Storing and re-creating this structure may leak to nonce reuse, which will leak
/// Storing and re-creating this structure may lead to nonce reuse, which will leak
/// your secret key in two signing sessions, even if neither session is completed.
/// These functions should be avoided if possible and used with care.
///
Expand Down
Loading