From 663b5f4b509d9fd9f19b8a8219362f5bab8021f1 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 13 May 2023 04:04:14 -0400 Subject: [PATCH] Add a context to MuSig key aggregation --- crypto/dkg/src/musig.rs | 18 ++++++++++++------ crypto/dkg/src/tests/mod.rs | 2 +- crypto/dkg/src/tests/musig.rs | 10 ++++++---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/crypto/dkg/src/musig.rs b/crypto/dkg/src/musig.rs index caeb98c3..4b115328 100644 --- a/crypto/dkg/src/musig.rs +++ b/crypto/dkg/src/musig.rs @@ -37,9 +37,13 @@ fn check_keys(keys: &[C::G]) -> Result> { Ok(keys_len) } -fn binding_factor_transcript(keys: &[C::G]) -> RecommendedTranscript { +fn binding_factor_transcript( + context: &[u8], + keys: &[C::G], +) -> RecommendedTranscript { let mut transcript = RecommendedTranscript::new(b"DKG MuSig v0.5"); - transcript.domain_separate(b"musig_binding_factors"); + transcript.append_message(b"context", context); + transcript.domain_separate(b"keys"); for key in keys { transcript.append_message(b"key", key.to_bytes()); } @@ -47,6 +51,7 @@ fn binding_factor_transcript(keys: &[C::G]) -> RecommendedTransc } fn binding_factor(mut transcript: RecommendedTranscript, i: u16) -> C::F { + transcript.domain_separate(b"participant"); transcript.append_message(b"participant", i.to_le_bytes()); C::hash_to_F(b"DKG-MuSig-binding_factor", &transcript.challenge(b"binding_factor")) } @@ -54,9 +59,9 @@ fn binding_factor(mut transcript: RecommendedTranscript, i: u16) /// The group key resulting from using this library's MuSig key gen. /// /// Creating an aggregate key with a list containing duplicated public keys returns an error. -pub fn musig_key(keys: &[C::G]) -> Result> { +pub fn musig_key(context: &[u8], keys: &[C::G]) -> Result> { let keys_len = check_keys::(keys)?; - let transcript = binding_factor_transcript::(keys); + let transcript = binding_factor_transcript::(context, keys); let mut res = C::G::identity(); for i in 1 ..= keys_len { res += keys[usize::from(i - 1)] * binding_factor::(transcript.clone(), i); @@ -69,6 +74,7 @@ pub fn musig_key(keys: &[C::G]) -> Result> { /// Creating an aggregate key with a list containing duplicated public keys returns an error. #[cfg(feature = "std")] pub fn musig( + context: &[u8], private_key: &Zeroizing, keys: &[C::G], ) -> Result, DkgError<()>> { @@ -89,7 +95,7 @@ pub fn musig( )?; // Calculate the binding factor per-key - let transcript = binding_factor_transcript::(keys); + let transcript = binding_factor_transcript::(context, keys); let mut binding = Vec::with_capacity(keys.len()); for i in 1 ..= keys_len { binding.push(binding_factor::(transcript.clone(), i)); @@ -126,7 +132,7 @@ pub fn musig( verification_shares.insert(*p, bound * lagrange_inv); } debug_assert_eq!(C::generator() * secret_share.deref(), verification_shares[¶ms.i()]); - debug_assert_eq!(musig_key::(keys).unwrap(), group_key); + debug_assert_eq!(musig_key::(context, keys).unwrap(), group_key); Ok(ThresholdCore { params, secret_share, group_key, verification_shares }) } diff --git a/crypto/dkg/src/tests/mod.rs b/crypto/dkg/src/tests/mod.rs index 43aaf9ca..f78489ad 100644 --- a/crypto/dkg/src/tests/mod.rs +++ b/crypto/dkg/src/tests/mod.rs @@ -81,7 +81,7 @@ pub fn musig_key_gen( let mut res = HashMap::new(); for key in keys { - let these_keys = musig_fn::(&key, &pub_keys).unwrap(); + let these_keys = musig_fn::(b"Test MuSig Key Gen", &key, &pub_keys).unwrap(); res.insert(these_keys.params().i(), ThresholdKeys::new(these_keys)); } diff --git a/crypto/dkg/src/tests/musig.rs b/crypto/dkg/src/tests/musig.rs index 0eac8340..bbe47342 100644 --- a/crypto/dkg/src/tests/musig.rs +++ b/crypto/dkg/src/tests/musig.rs @@ -21,18 +21,20 @@ pub fn test_musig(rng: &mut R) { keys.push(key); } + const CONTEXT: &[u8] = b"MuSig Test"; + // Empty signing set - assert!(musig::(&Zeroizing::new(C::F::ZERO), &[]).is_err()); + assert!(musig::(CONTEXT, &Zeroizing::new(C::F::ZERO), &[]).is_err()); // Signing set we're not part of - assert!(musig::(&Zeroizing::new(C::F::ZERO), &[C::generator()]).is_err()); + assert!(musig::(CONTEXT, &Zeroizing::new(C::F::ZERO), &[C::generator()]).is_err()); // Test with n keys { let mut created_keys = HashMap::new(); let mut verification_shares = HashMap::new(); - let group_key = musig_key::(&pub_keys).unwrap(); + let group_key = musig_key::(CONTEXT, &pub_keys).unwrap(); for (i, key) in keys.iter().enumerate() { - let these_keys = musig::(key, &pub_keys).unwrap(); + let these_keys = musig::(CONTEXT, key, &pub_keys).unwrap(); assert_eq!(these_keys.params().t(), PARTICIPANTS); assert_eq!(these_keys.params().n(), PARTICIPANTS); assert_eq!(usize::from(these_keys.params().i().0), i + 1);