diff --git a/.github/workflows/cross.yml b/.github/workflows/cross.yml index 2d421f7fe..cf56da346 100644 --- a/.github/workflows/cross.yml +++ b/.github/workflows/cross.yml @@ -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 diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b8746b806..1ce314a97 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -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 diff --git a/examples/musig.rs b/examples/musig.rs index 0f432bf5f..374d8b0db 100644 --- a/examples/musig.rs +++ b/examples/musig.rs @@ -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); diff --git a/src/key.rs b/src/key.rs index b2e6b6874..9cf29200b 100644 --- a/src/key.rs +++ b/src/key.rs @@ -1620,6 +1620,8 @@ impl<'de> serde::Deserialize<'de> for XOnlyPublicKey { impl Secp256k1 { /// Sort public keys using lexicographic (of compressed serialization) order. /// + /// This is the canonical way to sort public keys for use with Musig2. + /// /// Example: /// /// ```rust @@ -1636,10 +1638,10 @@ impl Secp256k1 { /// # 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( diff --git a/src/musig.rs b/src/musig.rs index 7fd28b84f..96380614e 100644 --- a/src/musig.rs +++ b/src/musig.rs @@ -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) } @@ -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 /// @@ -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. ///