88//! // use sha256 with deterministic nonce generation
99//! let musig = MuSig::<Sha256, Schnorr<Sha256, Deterministic<Sha256>>>::default();
1010//! // create a keylist
11- //! # use schnorr_fun::fun::Scalar;
12- //! # let kp1 = musig.schnorr.new_keypair(Scalar::random(&mut rand::thread_rng()));
11+ //! use schnorr_fun::fun::Scalar;
12+ //! let kp1 = musig.schnorr.new_keypair(Scalar::random(&mut rand::thread_rng()));
13+ //! let public_key1 = kp1.public_key();
14+ //! # let kp2 = musig.schnorr.new_keypair(Scalar::random(&mut rand::thread_rng()));
15+ //! # let public_key2 = kp2.public_key();
1316//! # let kp3 = musig.schnorr.new_keypair(Scalar::random(&mut rand::thread_rng()));
14- //! # let p1_pubkey = kp1.public_key();
15- //! # let p3_pubkey = kp3.public_key();
16- //! # let my_keypair = musig.schnorr.new_keypair(Scalar::random(&mut rand::thread_rng()));
17- //! # let _keylist = musig.new_keylist(vec![
18- //! # Party::Local(kp1),
19- //! # Party::Remote(my_keypair.public_key()),
20- //! # Party::Local(kp3),
21- //! # ]);
17+ //! # let public_key3 = kp3.public_key();
18+ //! // recieve the public keys of all other participants to form the aggregate key.
2219//! let keylist = musig.new_keylist(vec![
23- //! Party::Remote(p1_pubkey) ,
24- //! Party::Local(my_keypair) ,
25- //! Party::Remote(p3_pubkey) ,
20+ //! p1_public_key ,
21+ //! p2_public_key ,
22+ //! p3_public_key ,
2623//! ]);
27- //! let message = Message::plain("my-app", b"chancellor on brink of second bailout for banks");
28- //! // generate our aggregate key
2924//! let agg_key = keylist.agg_public_key();
30- //! // start a MuSig2 session by first exchanging nonces.
31- //! // Since we're using deterministic nonces it's important we only use the session id once
32- //! let my_nonces = musig.gen_nonces(&keylist, b"session-id-1337");
33- //! // send this to the other parties
34- //! let my_public_nonce = my_nonces[0].public();
35- //! # let nonces = musig.gen_nonces(&_keylist, b"session-id-1337");
36- //! # let p1_nonce = nonces[0].public();
37- //! # let p3_nonce = nonces[1].public();
38- //! # let mut _session = musig.start_sign_session_deterministic(&_keylist, my_nonces.iter().map(|n| n.public()), b"session-id-1337", message).unwrap();
39- //! // Once you've got the nonces from the other two (p1_nonce and p3_nonce) you can start the signing session.
40- //! let mut session = musig.start_sign_session(&keylist, my_nonces, [p1_nonce, p3_nonce], message).unwrap();
41- //! // but since we're using deterministic nonce generation we can just remember the session id.
42- //! // You should guarantee that this is not called ever again with the same session id!!!!
43- //! let mut session = musig.start_sign_session_deterministic(&keylist, [p1_nonce, p3_nonce], b"session-id-1337", message).unwrap();
25+ //!
26+ //! // create unique nonce, and send public nonce to other parties
27+ //! let p1_nonce = musig.gen_nonces(&keypair.sk, &keylist, b"session-id-1337");
28+ //! let p1_public_nonce = p1_nonce.public;
29+ //! # let p2_nonce = musig.gen_nonces(&keypair.sk, &keylist, b"session-id-1337");
30+ //! # let p3_nonce = musig.gen_nonces(&keypair.sk, &keylist, b"session-id-1337");
31+ //! let nonces = vec![p1_public_nonce, p2_public_nonce, p3_public_nonce];
32+ //! // Once you've got the nonces from the other two (p2_nonce and p3_nonce) you can start the signing session.
33+ //! let message = Message::plain("my-app", b"chancellor on brink of second bailout for banks");
34+ //! let mut session = musig.start_sign_session(&keylist, nonces, message).unwrap();
4435//! // sign with our (single) local keypair
45- //! let my_sig = musig.sign_all(&keylist, &mut session)[0];
46- //! # let _sigs = musig.sign_all(&_keylist, &mut _session);
47- //! # let p1_sig = _sigs[0];
48- //! # let p3_sig = _sigs[1];
36+ //! let p1_sig = musig.sign(&keylist, 0, kp1.sk, p1_nonce, &session);
37+ //! # let p2_sig = musig.sign(&keylist, 1, kp2.sk, p2_nonce, &session);
38+ //! # let p3_sig = musig.sign(&keylist, 2, kp3.sk, p3_nonce, &session);
4939//! // receive p1_sig and p3_sig from somewhere and check they're valid
50- //! assert!(musig.verify_partial_signature(&keylist, &session, 0, p1_sig ));
40+ //! assert!(musig.verify_partial_signature(&keylist, &session, 1, p2_sig ));
5141//! assert!(musig.verify_partial_signature(&keylist, &session, 2, p3_sig));
5242//! // combine them with ours into the final signature
53- //! let sig = musig.combine_partial_signatures(&keylist, &session, [my_sig, p1_sig , p3_sig]);
43+ //! let sig = musig.combine_partial_signatures(&keylist, &session, [p1_sig, p2_sig , p3_sig]);
5444//! // check it's a valid normal Schnorr signature
55- //! musig.schnorr.verify(&keylist.agg_verification_key() , message, &sig);
45+ //! musig.schnorr.verify(&agg_key , message, &sig);
5646//! ```
5747//!
5848//! ## Description
@@ -108,26 +98,6 @@ impl<H: Tagged, S: Default> Default for MuSig<H, S> {
10898 }
10999}
110100
111- impl < H : Tagged > MuSig < H , ( ) > {
112- /// Creates a MuSig context that can only do key aggregation.
113- ///
114- /// # Example
115- ///
116- /// ```
117- /// # use schnorr_fun::fun::{ XOnly };
118- /// # let key1 = XOnly::random(&mut rand::thread_rng());
119- /// # let key2 = XOnly::random(&mut rand::thread_rng());
120- /// use schnorr_fun::musig::{MuSig, Party};
121- /// use sha2::Sha256;
122- /// let musig = MuSig::<Sha256>::keyagg_only();
123- /// let keylist = musig.new_keylist(vec![Party::Remote(key1), Party::Remote(key2)]);
124- /// println!("{:?}", keylist.agg_public_key())
125- /// ```
126- pub fn keyagg_only ( ) -> Self {
127- Self :: _new ( ( ) )
128- }
129- }
130-
131101impl < H : Tagged , NG > MuSig < H , Schnorr < H , NG > > {
132102 /// Generate a new MuSig context from a Schnorr context.
133103 pub fn new ( schnorr : Schnorr < H , NG > ) -> Self {
@@ -150,8 +120,9 @@ pub struct KeyList {
150120 coefs : Vec < Scalar < Public > > ,
151121 /// The aggregate key
152122 agg_key : Point < EvenY > ,
153- /// The
123+ /// The tweak on the aggregate key
154124 tweak : Scalar < Public , Zero > ,
125+ /// Whether this aggregate key needs negation.
155126 needs_negation : bool ,
156127}
157128
@@ -169,17 +140,31 @@ impl KeyList {
169140 self . parties . iter ( ) . map ( |xonly| * xonly)
170141 }
171142
172- /// * Tweak* the aggregated key with a scalar so that the resulting key is equal to the existing
173- /// key plus `tweak * G`. The tweak mutates the public key while still allowing the original set
174- /// of signers to sign under the new key.
143+ /// Tweak the aggregate MuSig public key with a scalar so that the resulting key is equal to the
144+ /// existing key plus `tweak * G`. The tweak mutates the public key while still allowing
145+ /// the original set of signers to sign under the new key.
175146 ///
176147 /// This is how you embed a taproot commitment into a key.
177148 ///
149+ /// Also updates whether the MuSig KeyList needs negation.
150+ /// XOR of existing MuSig KeyList needs_negation and new tweaked key needs_negation.
151+ /// If both need negation, they will cancel out.
152+ ///
153+ /// Public key
154+ /// X = (b*x) * G
155+ /// where b = 1 or -1
156+ /// For a tweak t: X' = X + t * G.
157+ /// If X' needs negation then we need secret
158+ /// -(b*x + t) = -b*x - t
159+ /// So new b = -b and t = -t.
160+ /// If X' doesn't need negation, leave b as is.
161+ /// i.e. previous needs_negation XOR new needs_negation.
162+ ///
178163 /// ## Return value
179164 ///
180- /// Returns a new keylist with the same parties but a different aggregated public key. In the
181- /// unusual case that the tweak is exactly equal to the negation of the aggregated secret key
182- /// it returns `None`.
165+ /// Returns a new MuSig KeyList with the same parties but a different aggregated public key.
166+ /// In the erroneous case that the tweak is exactly equal to the negation of the aggregate
167+ /// secret key it returns `None`.
183168 pub fn tweak ( & self , tweak : Scalar < impl Secrecy , impl ZeroChoice > ) -> Option < Self > {
184169 let ( agg_key, needs_negation) = g ! ( self . agg_key + tweak * G )
185170 . mark :: < NonZero > ( ) ?
@@ -220,15 +205,15 @@ impl<H: Digest<OutputSize = U32> + Clone, S> MuSig<H, S> {
220205 /// use sha2::Sha256;
221206 /// let musig = MuSig::<Sha256, Schnorr<Sha256, Deterministic<Sha256>>>::default();
222207 /// let my_keypair = musig.schnorr.new_keypair(my_secret_key);
208+ /// let my_public_key = my_keypair.public_key();
223209 /// // Note the keys have to come in the same order on the other side!
224210 /// let keylist = musig.new_keylist(vec![
225- /// Party::Local(my_keypair) ,
226- /// Party::Remote(their_public_key) ,
211+ /// their_public_key ,
212+ /// my_public_key ,
227213 /// ]);
228214 /// ```
229215 pub fn new_keylist ( & self , parties : Vec < XOnly > ) -> KeyList {
230216 let keys = parties. clone ( ) ;
231-
232217 let coeff_hash = {
233218 let L = self . pk_hash . clone ( ) . add ( & keys[ ..] ) . finalize ( ) ;
234219 self . coeff_hash . clone ( ) . add ( L . as_slice ( ) )
@@ -267,6 +252,7 @@ impl<H: Digest<OutputSize = U32> + Clone, S> MuSig<H, S> {
267252}
268253
269254impl < H : Digest < OutputSize = U32 > + Clone , NG : NonceGen > MuSig < H , Schnorr < H , NG > > {
255+ /// TODO
270256 /// Generate nonces for your local keys in keylist.
271257 ///
272258 /// It is very important to carefully consider the implications of your choice of underlying
@@ -340,7 +326,7 @@ pub struct Adaptor {
340326///
341327/// ## Security
342328///
343- /// This struct has **secret nonces** in it up until you call [`clear_secrets`] or [`sign_all `]. If
329+ /// This struct has **secret nonces** in it up until you call [`clear_secrets`] or [`sign `]. If
344330/// a malicious party gains access to it before and you generate a partial signature with this session they
345331/// will be able to recover your secret key. If this is a concern simply avoid serializing this
346332/// struct (until you've cleared it) and recreate it only when you need it.
@@ -358,7 +344,6 @@ pub struct Adaptor {
358344pub struct SignSession < T = Ordinary > {
359345 b : Scalar < Public , Zero > ,
360346 c : Scalar < Public , Zero > ,
361- // local_secret_nonce: NonceKeyPair,
362347 public_nonces : Vec < Nonce > ,
363348 R : Point < EvenY > ,
364349 nonce_needs_negation : bool ,
@@ -368,8 +353,7 @@ pub struct SignSession<T = Ordinary> {
368353impl < H : Digest < OutputSize = U32 > + Clone , NG > MuSig < H , Schnorr < H , NG > > {
369354 /// Start a signing session.
370355 ///
371- /// You must provide you local secret nonces (the public portion must be shared with the other signer(s)).
372- /// If you are using deterministic nonce generations it's possible to use [`start_sign_session_deterministic`] instead.
356+ /// You must provide the public nonces for this signing session in the correct order.
373357 ///
374358 /// ## Return Value
375359 ///
@@ -379,14 +363,10 @@ impl<H: Digest<OutputSize = U32> + Clone, NG> MuSig<H, Schnorr<H, NG>> {
379363 ///
380364 /// # Panics
381365 ///
382- /// Panics if number of local or remote nonces passed in does not align with the parties in
383- /// `keylist`.
384- ///
385- /// [`start_sign_session_deterministic`]: Self::start_sign_session_deterministic
366+ /// Panics if number of nonces does not align with the parties in `keylist`.
386367 pub fn start_sign_session (
387368 & self ,
388369 keylist : & KeyList ,
389- // local_secret_nonce: NonceKeyPair,
390370 nonces : Vec < Nonce > ,
391371 message : Message < ' _ , Public > ,
392372 ) -> Option < SignSession > {
@@ -395,7 +375,6 @@ impl<H: Digest<OutputSize = U32> + Clone, NG> MuSig<H, Schnorr<H, NG>> {
395375 Some ( SignSession {
396376 b,
397377 c,
398- // local_secret_nonce,
399378 public_nonces,
400379 R ,
401380 nonce_needs_negation,
@@ -492,24 +471,18 @@ impl<H: Digest<OutputSize = U32> + Clone, NG> MuSig<H, Schnorr<H, NG>> {
492471 R . 0 [ 1 ] = R . 0 [ 1 ] . conditional_negate ( r_needs_negation) ;
493472 }
494473
495- // // let local_secret_nonce = local_nonce
496-
497- // secret[0].conditional_negate(r_needs_negation);
498- // secret[1].conditional_negate(r_needs_negation);
499-
500474 let c = self
501475 . schnorr
502476 . challenge ( R . to_xonly ( ) , keylist. agg_public_key ( ) , message) ;
503477
504478 Some ( ( b, c, Rs , R , r_needs_negation) )
505479 }
506480
507- /// Generates partial signatures (or partial encrypted signatures depending on `T`) under each of the `Local` entries in `keylist`.
508- ///
509- /// The order of the partial signatures returned is the order of them in the keylist.
481+ /// Generates a partial signature (or partial encrypted signature depending on `T`) for the local_secret_nonce.
510482 ///
483+ /// TODO
511484 /// This can only be called once per session as it clears the session (see also [`clear_secrets`]).
512- /// Calling `sign_all ` again will return an empty vector.
485+ /// Calling `sign ` again will return an empty vector.
513486 ///
514487 /// [`clear_secrets`]: SignSession::clear_secrets
515488 pub fn sign < T > (
@@ -659,7 +632,6 @@ mod test {
659632 keypair3. public_key( ) ,
660633 ] ) ;
661634
662-
663635 for tweak in [ tweak1, tweak2] {
664636 if let Some ( tweak) = tweak {
665637 keylist = keylist. tweak( tweak) . unwrap( ) ;
@@ -732,7 +704,6 @@ mod test {
732704 assert!( musig
733705 . schnorr
734706 . verify( & keylist. agg_verification_key( ) , message, & sig_p3) ) ;
735-
736707 }
737708 }
738709}
0 commit comments