Skip to content

Commit e2e47e5

Browse files
committed
Separate sign_all_but_one for immediate signing
1 parent c2240f3 commit e2e47e5

File tree

1 file changed

+51
-30
lines changed

1 file changed

+51
-30
lines changed

schnorr_fun/src/blind.rs

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)