@@ -68,6 +68,11 @@ impl SessionSecretRand {
6868
6969 /// Obtains a reference to the inner bytes of the [`SessionSecretRand`].
7070 pub fn as_bytes ( & self ) -> & [ u8 ; 32 ] { & self . 0 }
71+
72+ /// Obtains a mutable raw pointer to the beginning of the underlying storage.
73+ ///
74+ /// This is a low-level function and not exposed in the public API.
75+ fn as_mut_ptr ( & mut self ) -> * mut u8 { self . 0 . as_mut_ptr ( ) }
7176}
7277
7378/// Cached data related to a key aggregation.
@@ -154,7 +159,7 @@ impl fmt::Display for InvalidTweakErr {
154159/// ```
155160pub fn new_nonce_pair < C : Signing > (
156161 secp : & Secp256k1 < C > ,
157- session_secrand : SessionSecretRand ,
162+ mut session_secrand : SessionSecretRand ,
158163 key_agg_cache : Option < & KeyAggCache > ,
159164 sec_key : Option < SecretKey > ,
160165 pub_key : PublicKey ,
@@ -167,13 +172,19 @@ pub fn new_nonce_pair<C: Signing>(
167172 let msg_ptr = msg. as_ref ( ) . map ( |e| e. as_c_ptr ( ) ) . unwrap_or ( core:: ptr:: null ( ) ) ;
168173 let cache_ptr = key_agg_cache. map ( |e| e. as_ptr ( ) ) . unwrap_or ( core:: ptr:: null ( ) ) ;
169174 unsafe {
175+ // The use of a mutable pointer to `session_secrand`, which is a local variable,
176+ // may seem concerning/wrong. It is ok: this pointer is only mutable because the
177+ // behavior of `secp256k1_musig_nonce_gen` on error is to zero out the secret
178+ // nonce. We guarantee this won't happen, but also if it does, it's harmless
179+ // to zero out a local variable without propagating that change back to the
180+ // caller or anything.
170181 let mut sec_nonce = MaybeUninit :: < ffi:: MusigSecNonce > :: uninit ( ) ;
171182 let mut pub_nonce = MaybeUninit :: < ffi:: MusigPubNonce > :: uninit ( ) ;
172183 if ffi:: secp256k1_musig_nonce_gen (
173184 cx,
174185 sec_nonce. as_mut_ptr ( ) ,
175186 pub_nonce. as_mut_ptr ( ) ,
176- session_secrand. as_bytes ( ) . as_ptr ( ) ,
187+ session_secrand. as_mut_ptr ( ) ,
177188 sk_ptr,
178189 pub_key. as_c_ptr ( ) ,
179190 msg_ptr,
0 commit comments