@@ -390,17 +390,63 @@ where
390390 /// Returns a scalar of the unblinded signature
391391 pub fn sign_single ( & mut self , sig_request : SignatureRequest ) -> Option < Scalar < Public , Zero > > {
392392 let secret_nonce = self . use_secret_nonce ( sig_request. public_nonce ) ;
393- match secret_nonce {
393+ let signature_response = match secret_nonce {
394394 Some ( secret_nonce) => {
395395 let sig = s ! ( secret_nonce + sig_request. blind_challenge * self . secret) . public ( ) ;
396- Some ( sig) //.secret().non_zero()
396+ Some ( sig)
397397 }
398398 // Did not expect this nonce
399399 None => None ,
400- }
400+ } ;
401+ // Store this signature
402+ self . already_signed
403+ . insert ( sig_request. public_nonce , signature_response) ;
404+ signature_response
401405 }
402406
403- /// Sign multiple blind schnorr signatures concurrently once enough have been requested
407+ /// Sign all the signature requests immediately, except for one
408+ ///
409+ /// # Returns
410+ ///
411+ /// A vector of scalar signature options
412+ pub fn sign_all_but_one < R : RngCore > (
413+ & mut self ,
414+ rng : & mut R ,
415+ ) -> Vec < Option < Scalar < Public , Zero > > > {
416+ // Choose an index to skip signing request
417+ let skip_i = rng. gen_range ( 0 ..self . signature_requests . len ( ) as u32 ) ;
418+
419+ // Sign all the signature requests but don't store one (given there is more than one)
420+ let signatures = self
421+ . signature_requests
422+ . clone ( )
423+ . into_iter ( )
424+ . enumerate ( )
425+ . map ( |( i, sig_request) | {
426+ let sig_response = if self . max_sessions > 1 && i as u32 == skip_i {
427+ // For one out of the N sessions, drop the signature.
428+ // ⚠ IMPORTANT: Overwrite the stored signature for this nonce
429+ self . already_signed . insert ( sig_request. public_nonce , None ) ;
430+ assert ! ( self
431+ . already_signed
432+ . get( & sig_request. public_nonce)
433+ . expect( "history has to have None written for this nonce" )
434+ . is_none( ) ) ;
435+ None
436+ } else {
437+ // Otherwise, sign and store the signature
438+ self . sign_single ( sig_request. clone ( ) )
439+ } ;
440+ sig_response
441+ } )
442+ . collect ( ) ;
443+
444+ // Clear our signature requests
445+ self . signature_requests = vec ! [ ] ;
446+ signatures
447+ }
448+
449+ /// Pass signature request in for signing, batches until max_sessions requests have been made.
404450 ///
405451 /// Does not do any signing until max_session number of [`SignatureRequest`]s have been requested.
406452 /// Then sign them all but randomly disconnect (return None) one of the N sessions.
@@ -421,32 +467,7 @@ where
421467 if self . max_sessions > 1 && self . signature_requests . len ( ) < self . max_sessions {
422468 vec ! [ ]
423469 } else {
424- // Choose an index to skip signing request
425- let skip_i = rng. gen_range ( 0 ..self . signature_requests . len ( ) as u32 ) ;
426-
427- // Sign all the signature requests but don't store one (given there is more than one)
428- let signatures = self
429- . signature_requests
430- . clone ( )
431- . into_iter ( )
432- . enumerate ( )
433- . map ( |( i, sig_req) | {
434- let sig = self . sign_single ( sig_req. clone ( ) ) ;
435- let response = if self . max_sessions > 1 && i as u32 == skip_i {
436- // Maybe don't return the signature
437- None
438- } else {
439- sig
440- } ;
441- // Store signature (or None) for this public nonce
442- self . already_signed . insert ( sig_req. public_nonce , response) ;
443- response
444- } )
445- . collect ( ) ;
446-
447- // Clear our signature requests
448- self . signature_requests = vec ! [ ] ;
449- signatures
470+ self . sign_all_but_one ( rng)
450471 }
451472 }
452473}
0 commit comments