Skip to content

Commit ff39c4b

Browse files
authored
Random access for presignatures (#933)
* Random access for presignatures * docs
1 parent 9c485ca commit ff39c4b

3 files changed

Lines changed: 12 additions & 24 deletions

File tree

fastcrypto-tbls/src/threshold_schnorr/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ mod tests {
279279
.map(|node| {
280280
generate_partial_signatures(
281281
message,
282-
presigs.get_mut(&node.id).unwrap(),
282+
presigs.get_mut(&node.id).unwrap().next().unwrap(),
283283
&beacon_value,
284284
&merged_shares.get(&node.id).unwrap().my_shares,
285285
&vk,
@@ -459,7 +459,7 @@ mod tests {
459459
.map(|node| {
460460
generate_partial_signatures(
461461
message_2,
462-
presigs.get_mut(&node.id).unwrap(),
462+
presigs.get_mut(&node.id).unwrap().next().unwrap(),
463463
&beacon_value,
464464
&merged_shares_after_rotation
465465
.get(&node.id)
@@ -618,7 +618,7 @@ mod tests {
618618
};
619619
generate_partial_signatures(
620620
message,
621-
presigning,
621+
presigning.next().unwrap(),
622622
&beacon_value,
623623
&my_shares,
624624
&vk_element,
@@ -744,7 +744,7 @@ mod tests {
744744
};
745745
generate_partial_signatures(
746746
message,
747-
presigning,
747+
presigning.next().unwrap(),
748748
&beacon_value,
749749
&my_shares,
750750
&vk_element,

fastcrypto-tbls/src/threshold_schnorr/presigning.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,14 @@ use fastcrypto::error::FastCryptoError::InvalidInput;
99
use fastcrypto::error::FastCryptoResult;
1010
use itertools::Itertools;
1111

12-
/// An iterator that yields presigning tuples (i, t_i, p_i).
12+
/// An iterator that yields presigning tuples (t_i, p_i).
1313
pub struct Presignatures {
1414
secret: Vec<LazyPascalMatrixMultiplier<S>>,
1515
public: LazyPascalMatrixMultiplier<G>,
16-
index: usize,
1716
}
1817

1918
impl Iterator for Presignatures {
20-
type Item = (usize, Vec<S>, G);
19+
type Item = (Vec<S>, G);
2120

2221
fn next(&mut self) -> Option<Self::Item> {
2322
let secret = self
@@ -28,10 +27,7 @@ impl Iterator for Presignatures {
2827
let public = self.public.next();
2928

3029
match (secret, public) {
31-
(Some(s), Some(p)) => {
32-
self.index += 1;
33-
Some((self.index, s, p))
34-
}
30+
(Some(s), Some(p)) => Some((s, p)),
3531
(None, None) => None,
3632
_ => unreachable!(),
3733
}
@@ -126,10 +122,6 @@ impl Presignatures {
126122
);
127123
assert_eq!(public.len(), expected_len);
128124

129-
Ok(Self {
130-
secret,
131-
public,
132-
index: 0,
133-
})
125+
Ok(Self { secret, public })
134126
}
135127
}

fastcrypto-tbls/src/threshold_schnorr/signing.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33

44
use crate::polynomial::{Eval, Poly};
55
use crate::threshold_schnorr::key_derivation::{compute_tweak, derive_verifying_key_internal};
6-
use crate::threshold_schnorr::presigning::Presignatures;
76
use crate::threshold_schnorr::{avss, Address, G, S};
8-
use fastcrypto::error::FastCryptoError::{InputTooShort, OutOfPresigs};
7+
use fastcrypto::error::FastCryptoError::InputTooShort;
98
use fastcrypto::error::{FastCryptoError, FastCryptoResult};
109
use fastcrypto::groups::secp256k1::schnorr::{
1110
bip0340_hash_to_scalar, SchnorrPublicKey, SchnorrSignature, Tag,
1211
};
1312
use fastcrypto::groups::GroupElement;
1413
use itertools::Itertools;
1514

16-
/// Generate partial threshold Schnorr signatures for a given message using a presigning triple.
15+
/// Generate partial threshold Schnorr signatures for a given message using a presigning tuple.
16+
/// The presigning tuple must be taken from a [Presignatures] iterator, the other parties should use the same tuple and one tuple may only be used once.
1717
/// Returns also the public nonce R.
1818
///
1919
/// The signatures produced follow the BIP-0340 standard (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
@@ -22,20 +22,16 @@ use itertools::Itertools;
2222
/// [derive_verifying_key]), and the signature is adjusted accordingly.
2323
/// The signature will be valid for the derived verifying key.
2424
///
25-
/// Returns an `OutOfPresigs` error if the presignatures iterator is exhausted.
2625
/// `GeneralOpaqueError` is returned if the generated nonce R is the identity element (should happen only with negligible probability).
2726
/// `InvalidInput` is returned if the verifying key is the identity element.
2827
pub fn generate_partial_signatures(
2928
message: &[u8],
30-
presignatures: &mut Presignatures,
29+
(mut secret_presigs, public_presig): (Vec<S>, G),
3130
beacon_value: &S,
3231
my_signing_key_shares: &avss::SharesForNode,
3332
verifying_key: &G,
3433
derivation_address: Option<&Address>,
3534
) -> FastCryptoResult<(G, Vec<Eval<S>>)> {
36-
// TODO: Each output from an instance of Presigning has a unique index. Perhaps this is needed for coordination?
37-
let (_, mut secret_presigs, public_presig) = presignatures.next().ok_or(OutOfPresigs)?;
38-
3935
let r_g = public_presig + G::generator() * beacon_value;
4036

4137
// Since both the public_presig and the beacon_value are random, this should happen only with negligible probability.

0 commit comments

Comments
 (0)