Skip to content

Commit 3233cb9

Browse files
committed
Merge #811: musig: use [u8; 32] rather than Message for musig2 messages
9535f62 musig: use [u8; 32] rather than Message for musig2 messages (Andrew Poelstra) Pull request description: The messages we sign with musig2 do not need to be pre-hashed. They just need to be 32 bytes long. To make this clearer, stop using Message. Fixes #810. ACKs for top commit: tcharding: ACK 9535f62 Tree-SHA512: 5a40c60be15d4c67032d1e5e70e7675a58f76e4a21b6c78d31ef910451de54e0c60065ca6915b5693cfb75fca733422640d804ea90b2acf6613b0c431cf8a09f
2 parents 4045eb8 + 9535f62 commit 3233cb9

File tree

3 files changed

+33
-40
lines changed

3 files changed

+33
-40
lines changed

examples/musig.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use secp256k1::musig::{
44
new_nonce_pair, AggregatedNonce, KeyAggCache, PartialSignature, PublicNonce, Session,
55
SessionSecretRand,
66
};
7-
use secp256k1::{Keypair, Message, PublicKey, Scalar, Secp256k1, SecretKey};
7+
use secp256k1::{Keypair, PublicKey, Scalar, Secp256k1, SecretKey};
88

99
fn main() {
1010
let secp = Secp256k1::new();
@@ -36,8 +36,7 @@ fn main() {
3636

3737
assert_eq!(agg_pk, tweaked_agg_pk.x_only_public_key().0);
3838

39-
let msg_bytes: [u8; 32] = *b"this_could_be_the_hash_of_a_msg!";
40-
let msg = Message::from_digest_slice(&msg_bytes).unwrap();
39+
let msg: &[u8; 32] = b"This message is exactly 32 bytes";
4140

4241
let musig_session_sec_rand1 = SessionSecretRand::from_rng(&mut rng);
4342

@@ -97,5 +96,5 @@ fn main() {
9796

9897
let aggregated_signature = session.partial_sig_agg(partial_sigs_ref);
9998

100-
assert!(aggregated_signature.verify(&secp, &agg_pk, &msg_bytes).is_ok());
99+
assert!(aggregated_signature.verify(&secp, &agg_pk, msg).is_ok());
101100
}

src/musig.rs

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std;
1313

1414
use crate::ffi::{self, CPtr};
1515
use crate::{
16-
from_hex, schnorr, Error, Keypair, Message, PublicKey, Scalar, Secp256k1, SecretKey, Signing,
16+
from_hex, schnorr, Error, Keypair, PublicKey, Scalar, Secp256k1, SecretKey, Signing,
1717
Verification, XOnlyPublicKey,
1818
};
1919

@@ -154,7 +154,7 @@ impl fmt::Display for InvalidTweakErr {
154154
/// for maximal mis-use resistance.
155155
/// * `pub_key`: [`PublicKey`] that we will use to create partial signature. The secnonce
156156
/// output of this function cannot be used to sign for any other public key.
157-
/// * `msg`: Optional [`Message`] that will be signed later on. Provide this for maximal misuse resistance.
157+
/// * `msg`: Optional message that will be signed later on. Provide this for maximal misuse resistance.
158158
/// * `extra_rand`: Additional randomness for mis-use resistance. Provide this for maximal misuse resistance
159159
///
160160
/// Remember that nonce reuse will immediately leak the secret key!
@@ -184,7 +184,7 @@ pub fn new_nonce_pair<C: Signing>(
184184
key_agg_cache: Option<&KeyAggCache>,
185185
sec_key: Option<SecretKey>,
186186
pub_key: PublicKey,
187-
msg: Option<Message>,
187+
msg: Option<&[u8; 32]>,
188188
extra_rand: Option<[u8; 32]>,
189189
) -> (SecretNonce, PublicNonce) {
190190
let cx = secp.ctx().as_ptr();
@@ -596,15 +596,15 @@ impl KeyAggCache {
596596
/// * `session_secrand`: [`SessionSecretRand`] Uniform random identifier for this session. Each call to this
597597
/// function must have a UNIQUE `session_secrand`.
598598
/// * `pub_key`: [`PublicKey`] of the signer creating the nonce.
599-
/// * `msg`: [`Message`] that will be signed later on.
599+
/// * `msg`: message that will be signed later on.
600600
/// * `extra_rand`: Additional randomness for mis-use resistance
601601
///
602602
/// Example:
603603
///
604604
/// ```rust
605605
/// # #[cfg(feature = "std")]
606606
/// # #[cfg(feature = "rand")] {
607-
/// # use secp256k1::{Secp256k1, SecretKey, Keypair, PublicKey, Message};
607+
/// # use secp256k1::{Secp256k1, SecretKey, Keypair, PublicKey};
608608
/// # use secp256k1::musig::{KeyAggCache, SessionSecretRand};
609609
/// # let secp = Secp256k1::new();
610610
/// # let sk1 = SecretKey::new(&mut rand::rng());
@@ -616,9 +616,8 @@ impl KeyAggCache {
616616
/// // The session id must be sampled at random. Read documentation for more details.
617617
/// let session_secrand = SessionSecretRand::from_rng(&mut rand::rng());
618618
///
619-
/// let msg = Message::from_digest_slice(b"Public Message we want to sign!!").unwrap();
620-
///
621619
/// // Provide the current time for mis-use resistance
620+
/// let msg = b"Public message we want to sign!!";
622621
/// let extra_rand : Option<[u8; 32]> = None;
623622
/// let (_sec_nonce, _pub_nonce) = key_agg_cache.nonce_gen(&secp, session_secrand, pub_key1, msg, extra_rand);
624623
/// # }
@@ -628,7 +627,7 @@ impl KeyAggCache {
628627
secp: &Secp256k1<C>,
629628
session_secrand: SessionSecretRand,
630629
pub_key: PublicKey,
631-
msg: Message,
630+
msg: &[u8; 32],
632631
extra_rand: Option<[u8; 32]>,
633632
) -> (SecretNonce, PublicNonce) {
634633
// The secret key here is supplied as NULL. This is okay because we supply the
@@ -900,7 +899,7 @@ impl AggregatedNonce {
900899
/// ```rust
901900
/// # #[cfg(feature = "std")]
902901
/// # #[cfg(feature = "rand")] {
903-
/// # use secp256k1::{Secp256k1, SecretKey, Keypair, PublicKey, Message};
902+
/// # use secp256k1::{Secp256k1, SecretKey, Keypair, PublicKey};
904903
/// # use secp256k1::musig::{AggregatedNonce, KeyAggCache, SessionSecretRand};
905904
/// # let secp = Secp256k1::new();
906905
/// # let sk1 = SecretKey::new(&mut rand::rng());
@@ -911,7 +910,7 @@ impl AggregatedNonce {
911910
/// # let key_agg_cache = KeyAggCache::new(&secp, &[&pub_key1, &pub_key2]);
912911
/// // The session id must be sampled at random. Read documentation for more details.
913912
///
914-
/// let msg = Message::from_digest_slice(b"Public Message we want to sign!!").unwrap();
913+
/// let msg = b"Public message we want to sign!!";
915914
///
916915
/// let session_secrand1 = SessionSecretRand::from_rng(&mut rand::rng());
917916
/// let (_sec_nonce1, pub_nonce1) = key_agg_cache.nonce_gen(&secp, session_secrand1, pub_key1, msg, None);
@@ -1056,14 +1055,14 @@ impl Session {
10561055
/// * `secp` : [`Secp256k1`] context object initialized for signing
10571056
/// * `key_agg_cache`: [`KeyAggCache`] to be used for this session
10581057
/// * `agg_nonce`: [`AggregatedNonce`], the aggregate nonce
1059-
/// * `msg`: [`Message`] that will be signed later on.
1058+
/// * `msg`: message that will be signed later on.
10601059
///
10611060
/// Example:
10621061
///
10631062
/// ```rust
10641063
/// # #[cfg(feature = "std")]
10651064
/// # #[cfg(feature = "rand")] {
1066-
/// # use secp256k1::{Secp256k1, SecretKey, Keypair, PublicKey, Message};
1065+
/// # use secp256k1::{Secp256k1, SecretKey, Keypair, PublicKey};
10671066
/// # use secp256k1::musig::{AggregatedNonce, KeyAggCache, Session, SessionSecretRand};
10681067
/// # let secp = Secp256k1::new();
10691068
/// # let sk1 = SecretKey::new(&mut rand::rng());
@@ -1074,7 +1073,7 @@ impl Session {
10741073
/// # let key_agg_cache = KeyAggCache::new(&secp, &[&pub_key1, &pub_key2]);
10751074
/// // The session id must be sampled at random. Read documentation for more details.
10761075
///
1077-
/// let msg = Message::from_digest_slice(b"Public Message we want to sign!!").unwrap();
1076+
/// let msg = b"Public message we want to sign!!";
10781077
///
10791078
/// // Provide the current time for mis-use resistance
10801079
/// let session_secrand1 = SessionSecretRand::from_rng(&mut rand::rng());
@@ -1100,7 +1099,7 @@ impl Session {
11001099
secp: &Secp256k1<C>,
11011100
key_agg_cache: &KeyAggCache,
11021101
agg_nonce: AggregatedNonce,
1103-
msg: Message,
1102+
msg: &[u8; 32],
11041103
) -> Self {
11051104
let mut session = MaybeUninit::<ffi::MusigSession>::uninit();
11061105

@@ -1199,7 +1198,7 @@ impl Session {
11991198
/// # #[cfg(not(secp256k1_fuzz))]
12001199
/// # #[cfg(feature = "std")]
12011200
/// # #[cfg(feature = "rand")] {
1202-
/// # use secp256k1::{Secp256k1, SecretKey, Keypair, PublicKey, Message};
1201+
/// # use secp256k1::{Secp256k1, SecretKey, Keypair, PublicKey};
12031202
/// # use secp256k1::musig::{AggregatedNonce, KeyAggCache, SessionSecretRand, Session};
12041203
/// # let secp = Secp256k1::new();
12051204
/// # let sk1 = SecretKey::new(&mut rand::rng());
@@ -1210,7 +1209,7 @@ impl Session {
12101209
/// # let key_agg_cache = KeyAggCache::new(&secp, &[&pub_key1, &pub_key2]);
12111210
/// // The session id must be sampled at random. Read documentation for more details.
12121211
///
1213-
/// let msg = Message::from_digest_slice(b"Public Message we want to sign!!").unwrap();
1212+
/// let msg = b"Public message we want to sign!!";
12141213
///
12151214
/// // Provide the current time for mis-use resistance
12161215
/// let session_secrand1 = SessionSecretRand::from_rng(&mut rand::rng());
@@ -1280,7 +1279,7 @@ impl Session {
12801279
///
12811280
/// ```rust
12821281
/// # #[cfg(feature = "rand-std")] {
1283-
/// # use secp256k1::{KeyAggCache, Secp256k1, SecretKey, Keypair, PublicKey, SessionSecretRand, Message, AggregatedNonce, Session};
1282+
/// # use secp256k1::{KeyAggCache, Secp256k1, SecretKey, Keypair, PublicKey, SessionSecretRand, AggregatedNonce, Session};
12841283
/// # let secp = Secp256k1::new();
12851284
/// # let sk1 = SecretKey::new(&mut rand::rng());
12861285
/// # let pub_key1 = PublicKey::from_secret_key(&secp, &sk1);
@@ -1290,7 +1289,7 @@ impl Session {
12901289
/// let key_agg_cache = KeyAggCache::new(&secp, &[pub_key1, pub_key2]);
12911290
/// // The session id must be sampled at random. Read documentation for more details.
12921291
///
1293-
/// let msg = Message::from_digest_slice(b"Public Message we want to sign!!").unwrap();
1292+
/// let msg = b"Public message we want to sign!!";
12941293
///
12951294
/// // Provide the current time for mis-use resistance
12961295
/// let session_secrand1 = SessionSecretRand::from_rng(&mut rand::rng());
@@ -1381,7 +1380,7 @@ mod tests {
13811380
use super::*;
13821381
#[cfg(feature = "std")]
13831382
#[cfg(feature = "rand")]
1384-
use crate::{Message, PublicKey, Secp256k1, SecretKey};
1383+
use crate::{PublicKey, Secp256k1, SecretKey};
13851384

13861385
#[test]
13871386
#[cfg(feature = "std")]
@@ -1490,8 +1489,7 @@ mod tests {
14901489

14911490
let key_agg_cache = KeyAggCache::new(&secp, &[&pubkey1, &pubkey2]);
14921491

1493-
let msg_bytes: [u8; 32] = *b"this_could_be_the_hash_of_a_msg!";
1494-
let msg = Message::from_digest_slice(&msg_bytes).unwrap();
1492+
let msg: &[u8; 32] = b"This message is exactly 32 bytes";
14951493

14961494
// Test nonce generation with KeyAggCache
14971495
let session_secrand1 = SessionSecretRand::from_rng(&mut rng);
@@ -1530,8 +1528,7 @@ mod tests {
15301528

15311529
let key_agg_cache = KeyAggCache::new(&secp, &[&pubkey1, &pubkey2]);
15321530

1533-
let msg_bytes: [u8; 32] = *b"this_could_be_the_hash_of_a_msg!";
1534-
let msg = Message::from_digest_slice(&msg_bytes).unwrap();
1531+
let msg: &[u8; 32] = b"This message is exactly 32 bytes";
15351532

15361533
let session_secrand1 = SessionSecretRand::from_rng(&mut rng);
15371534
let (_, pub_nonce1) = key_agg_cache.nonce_gen(&secp, session_secrand1, pubkey1, msg, None);
@@ -1580,8 +1577,7 @@ mod tests {
15801577
let pubkeys = [&pubkey1, &pubkey2];
15811578
let key_agg_cache = KeyAggCache::new(&secp, &pubkeys);
15821579

1583-
let msg_bytes: [u8; 32] = *b"this_could_be_the_hash_of_a_msg!";
1584-
let msg = Message::from_digest_slice(&msg_bytes).unwrap();
1580+
let msg: &[u8; 32] = b"This message is exactly 32 bytes";
15851581

15861582
let session_secrand1 = SessionSecretRand::from_rng(&mut rng);
15871583
let (sec_nonce1, pub_nonce1) =
@@ -1664,8 +1660,7 @@ mod tests {
16641660
let pubkeys = [&pubkey1, &pubkey2];
16651661
let key_agg_cache = KeyAggCache::new(&secp, &pubkeys);
16661662

1667-
let msg_bytes: [u8; 32] = *b"this_could_be_the_hash_of_a_msg!";
1668-
let msg = Message::from_digest_slice(&msg_bytes).unwrap();
1663+
let msg: &[u8; 32] = b"This message is exactly 32 bytes";
16691664

16701665
let session_secrand1 = SessionSecretRand::from_rng(&mut rng);
16711666
let (sec_nonce1, pub_nonce1) =
@@ -1688,23 +1683,23 @@ mod tests {
16881683
// Test signature verification
16891684
let aggregated_signature = session.partial_sig_agg(&[&partial_sign1, &partial_sign2]);
16901685
let agg_pk = key_agg_cache.agg_pk();
1691-
aggregated_signature.verify(&secp, &agg_pk, &msg_bytes).unwrap();
1686+
aggregated_signature.verify(&secp, &agg_pk, msg).unwrap();
16921687

16931688
// Test assume_valid
16941689
let schnorr_sig = aggregated_signature.assume_valid();
1695-
secp.verify_schnorr(&schnorr_sig, &msg_bytes, &agg_pk).unwrap();
1690+
secp.verify_schnorr(&schnorr_sig, msg, &agg_pk).unwrap();
16961691

16971692
// Test with wrong aggregate (repeated sigs)
16981693
let aggregated_signature = session.partial_sig_agg(&[&partial_sign1, &partial_sign1]);
1699-
aggregated_signature.verify(&secp, &agg_pk, &msg_bytes).unwrap_err();
1694+
aggregated_signature.verify(&secp, &agg_pk, msg).unwrap_err();
17001695
let schnorr_sig = aggregated_signature.assume_valid();
1701-
secp.verify_schnorr(&schnorr_sig, &msg_bytes, &agg_pk).unwrap_err();
1696+
secp.verify_schnorr(&schnorr_sig, msg, &agg_pk).unwrap_err();
17021697

17031698
// Test with swapped sigs -- this will work. Unlike keys, sigs are not ordered.
17041699
let aggregated_signature = session.partial_sig_agg(&[&partial_sign2, &partial_sign1]);
1705-
aggregated_signature.verify(&secp, &agg_pk, &msg_bytes).unwrap();
1700+
aggregated_signature.verify(&secp, &agg_pk, msg).unwrap();
17061701
let schnorr_sig = aggregated_signature.assume_valid();
1707-
secp.verify_schnorr(&schnorr_sig, &msg_bytes, &agg_pk).unwrap();
1702+
secp.verify_schnorr(&schnorr_sig, msg, &agg_pk).unwrap();
17081703
}
17091704

17101705
#[test]
@@ -1724,8 +1719,7 @@ mod tests {
17241719
let pubkeys_ref = pubkeys_ref.as_mut_slice();
17251720

17261721
let key_agg_cache = KeyAggCache::new(&secp, pubkeys_ref);
1727-
let msg_bytes: [u8; 32] = *b"this_could_be_the_hash_of_a_msg!";
1728-
let msg = Message::from_digest_slice(&msg_bytes).unwrap();
1722+
let msg: &[u8; 32] = b"This message is exactly 32 bytes";
17291723

17301724
let session_secrand1 = SessionSecretRand::from_rng(&mut rng);
17311725
let (_, pub_nonce1) = key_agg_cache.nonce_gen(&secp, session_secrand1, pubkey1, msg, None);

src/schnorr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ mod tests {
213213
use super::*;
214214
use crate::schnorr::{Keypair, Signature, XOnlyPublicKey};
215215
use crate::Error::InvalidPublicKey;
216-
use crate::{constants, from_hex, Message, Secp256k1, SecretKey};
216+
use crate::{constants, from_hex, Secp256k1, SecretKey};
217217

218218
#[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
219219
macro_rules! hex_32 {

0 commit comments

Comments
 (0)