Skip to content

Commit

Permalink
make embedding of public and private shares configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
xoloki committed Dec 2, 2024
1 parent 38cf8ee commit 8e411c1
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 51 deletions.
8 changes: 6 additions & 2 deletions src/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,9 @@ impl Signable for DkgPrivateBegin {
}
for signer_id in &self.signer_ids {
hasher.update(signer_id.to_be_bytes());
self.dkg_public_shares[signer_id].hash(hasher);
if let Some(shares) = self.dkg_public_shares.get(signer_id) {
shares.hash(hasher);
}
}
}
}
Expand Down Expand Up @@ -246,7 +248,9 @@ impl Signable for DkgEndBegin {
}
for signer_id in &self.signer_ids {
hasher.update(signer_id.to_be_bytes());
self.dkg_private_shares[signer_id].hash(hasher);
if let Some(shares) = self.dkg_private_shares.get(signer_id) {
shares.hash(hasher);
}
}
}
}
Expand Down
150 changes: 118 additions & 32 deletions src/state_machine/coordinator/fire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,16 +424,19 @@ impl<Aggregator: AggregatorTrait> Coordinator<Aggregator> {
.keys()
.flat_map(|signer_id| self.config.signer_key_ids[signer_id].clone())
.collect::<Vec<u32>>();

let dkg_public_shares = if self.config.embed_public_private_shares {
self.dkg_public_shares
.iter()
.map(|(id, share)| (*id, share.clone()))
.collect()
} else {
Default::default()
};
let dkg_begin = DkgPrivateBegin {
dkg_id: self.current_dkg_id,
key_ids: active_key_ids,
signer_ids: self.dkg_public_shares.keys().cloned().collect(),
dkg_public_shares: self
.dkg_public_shares
.iter()
.map(|(id, share)| (*id, share.clone()))
.collect(),
dkg_public_shares,
};
let dkg_private_begin_msg = Packet {
sig: dkg_begin
Expand Down Expand Up @@ -463,16 +466,20 @@ impl<Aggregator: AggregatorTrait> Coordinator<Aggregator> {
.keys()
.flat_map(|signer_id| self.config.signer_key_ids[signer_id].clone())
.collect::<Vec<u32>>();
let dkg_private_shares = if self.config.embed_public_private_shares {
self.dkg_private_shares
.iter()
.map(|(id, share)| (*id, share.clone()))
.collect()
} else {
Default::default()
};

let dkg_end_begin = DkgEndBegin {
dkg_id: self.current_dkg_id,
key_ids: active_key_ids,
signer_ids: self.dkg_private_shares.keys().cloned().collect(),
dkg_private_shares: self
.dkg_private_shares
.iter()
.map(|(id, share)| (*id, share.clone()))
.collect(),
dkg_private_shares,
};
let dkg_end_begin_msg = Packet {
sig: dkg_end_begin
Expand Down Expand Up @@ -1525,17 +1532,27 @@ pub mod test {

#[test]
fn missing_public_keys_dkg_v1() {
missing_public_keys_dkg::<v1::Aggregator, v1::Signer>(10, 1);
missing_public_keys_dkg::<v1::Aggregator, v1::Signer>(10, 1, false);
}
#[test]
fn missing_public_keys_dkg_v1_embed() {
missing_public_keys_dkg::<v1::Aggregator, v1::Signer>(10, 1, true);
}

#[test]
fn missing_public_keys_dkg_v2() {
missing_public_keys_dkg::<v2::Aggregator, v2::Signer>(10, 1);
missing_public_keys_dkg::<v2::Aggregator, v2::Signer>(10, 1, false);
}

#[test]
fn missing_public_keys_dkg_v2_embed() {
missing_public_keys_dkg::<v2::Aggregator, v2::Signer>(10, 1, true);
}

fn missing_public_keys_dkg<Aggregator: AggregatorTrait, SignerType: SignerTrait>(
num_signers: u32,
keys_per_signer: u32,
embed_public_private_shares: bool,
) -> (Vec<FireCoordinator<Aggregator>>, Vec<Signer<SignerType>>) {
let timeout = Duration::from_millis(1024);
let expire = Duration::from_millis(1280);
Expand All @@ -1548,6 +1565,7 @@ pub mod test {
Some(timeout),
Some(timeout),
Some(timeout),
embed_public_private_shares,
);

// Start a DKG round where we will not allow all signers to recv DkgBegin, so they will not respond with DkgPublicShares
Expand Down Expand Up @@ -1606,17 +1624,28 @@ pub mod test {

#[test]
fn minimum_signers_dkg_v1() {
minimum_signers_dkg::<v1::Aggregator, v1::Signer>(10, 2);
minimum_signers_dkg::<v1::Aggregator, v1::Signer>(10, 2, false);
}

#[test]
fn minimum_signers_dkg_v2() {
minimum_signers_dkg::<v2::Aggregator, v2::Signer>(10, 2);
minimum_signers_dkg::<v2::Aggregator, v2::Signer>(10, 2, false);
}

#[test]
fn minimum_signers_dkg_v1_embed() {
minimum_signers_dkg::<v1::Aggregator, v1::Signer>(10, 2, true);
}

#[test]
fn minimum_signers_dkg_v2_embed() {
minimum_signers_dkg::<v2::Aggregator, v2::Signer>(10, 2, true);
}

fn minimum_signers_dkg<Aggregator: AggregatorTrait, SignerType: SignerTrait>(
num_signers: u32,
keys_per_signer: u32,
embed_public_private_shares: bool,
) -> (Vec<FireCoordinator<Aggregator>>, Vec<Signer<SignerType>>) {
let timeout = Duration::from_millis(1024);
let expire = Duration::from_millis(1280);
Expand All @@ -1629,6 +1658,7 @@ pub mod test {
Some(timeout),
Some(timeout),
Some(timeout),
embed_public_private_shares,
);

// Start a DKG round where we will not allow all signers to recv DkgBegin, so they will not respond with DkgPublicShares
Expand Down Expand Up @@ -1761,15 +1791,27 @@ pub mod test {

#[test]
fn insufficient_signers_dkg_v1() {
insufficient_signers_dkg::<v1::Aggregator, v1::Signer>();
insufficient_signers_dkg::<v1::Aggregator, v1::Signer>(false);
}

#[test]
fn insufficient_signers_dkg_v2() {
insufficient_signers_dkg::<v2::Aggregator, v2::Signer>();
insufficient_signers_dkg::<v2::Aggregator, v2::Signer>(false);
}

#[test]
fn insufficient_signers_dkg_v1_embed() {
insufficient_signers_dkg::<v1::Aggregator, v1::Signer>(true);
}

fn insufficient_signers_dkg<Aggregator: AggregatorTrait, Signer: SignerTrait>() {
#[test]
fn insufficient_signers_dkg_v2_embed() {
insufficient_signers_dkg::<v2::Aggregator, v2::Signer>(true);
}

fn insufficient_signers_dkg<Aggregator: AggregatorTrait, Signer: SignerTrait>(
embed_public_private_shares: bool,
) {
let timeout = Duration::from_millis(1024);
let expire = Duration::from_millis(1280);
let num_signers = 10;
Expand All @@ -1782,6 +1824,7 @@ pub mod test {
Some(timeout),
Some(timeout),
Some(timeout),
embed_public_private_shares,
);

// Start a DKG round where we will not allow all signers to recv DkgBegin, so they will not respond with DkgPublicShares
Expand Down Expand Up @@ -2210,20 +2253,35 @@ pub mod test {

#[test]
fn minimum_signers_sign_v1() {
minimum_signers_sign::<v1::Aggregator, v1::Signer>();
minimum_signers_sign::<v1::Aggregator, v1::Signer>(false);
}

#[test]
fn minimum_signers_sign_v2() {
minimum_signers_sign::<v2::Aggregator, v2::Signer>();
minimum_signers_sign::<v2::Aggregator, v2::Signer>(false);
}

#[test]
fn minimum_signers_sign_v1_embed() {
minimum_signers_sign::<v1::Aggregator, v1::Signer>(true);
}

fn minimum_signers_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>() {
#[test]
fn minimum_signers_sign_v2_embed() {
minimum_signers_sign::<v2::Aggregator, v2::Signer>(true);
}

fn minimum_signers_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>(
embed_public_private_shares: bool,
) {
let num_signers = 10;
let keys_per_signer = 2;

let (mut coordinators, mut signers) =
minimum_signers_dkg::<Aggregator, Signer>(num_signers, keys_per_signer);
let (mut coordinators, mut signers) = minimum_signers_dkg::<Aggregator, Signer>(
num_signers,
keys_per_signer,
embed_public_private_shares,
);
let config = coordinators.first().unwrap().get_config();

// Figure out how many signers we can remove and still be above the threshold
Expand Down Expand Up @@ -2294,20 +2352,35 @@ pub mod test {

#[test]
fn missing_public_keys_sign_v1() {
missing_public_keys_sign::<v1::Aggregator, v1::Signer>();
missing_public_keys_sign::<v1::Aggregator, v1::Signer>(false);
}

#[test]
fn minimum_missing_public_keys_sign_v2() {
missing_public_keys_sign::<v2::Aggregator, v2::Signer>();
fn missing_public_keys_sign_v2() {
missing_public_keys_sign::<v2::Aggregator, v2::Signer>(false);
}

fn missing_public_keys_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>() {
#[test]
fn missing_public_keys_sign_v1_embed() {
missing_public_keys_sign::<v1::Aggregator, v1::Signer>(true);
}

#[test]
fn missing_public_keys_sign_v2_embed() {
missing_public_keys_sign::<v2::Aggregator, v2::Signer>(true);
}

fn missing_public_keys_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>(
embed_public_private_shares: bool,
) {
let num_signers = 10;
let keys_per_signer = 2;

let (mut coordinators, mut signers) =
minimum_signers_dkg::<Aggregator, Signer>(num_signers, keys_per_signer);
let (mut coordinators, mut signers) = minimum_signers_dkg::<Aggregator, Signer>(
num_signers,
keys_per_signer,
embed_public_private_shares,
);

// Let us also remove that signers public key from the config including all of its key ids
let mut removed_signer = signers.pop().expect("Failed to pop signer");
Expand Down Expand Up @@ -2381,15 +2454,27 @@ pub mod test {

#[test]
fn insufficient_signers_sign_v1() {
insufficient_signers_sign::<v1::Aggregator, v1::Signer>();
insufficient_signers_sign::<v1::Aggregator, v1::Signer>(false);
}

#[test]
fn insufficient_signers_sign_v2() {
insufficient_signers_sign::<v2::Aggregator, v2::Signer>();
insufficient_signers_sign::<v2::Aggregator, v2::Signer>(false);
}

#[test]
fn insufficient_signers_sign_v1_embed() {
insufficient_signers_sign::<v1::Aggregator, v1::Signer>(true);
}

#[test]
fn insufficient_signers_sign_v2_embed() {
insufficient_signers_sign::<v2::Aggregator, v2::Signer>(true);
}

fn insufficient_signers_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>() {
fn insufficient_signers_sign<Aggregator: AggregatorTrait, Signer: SignerTrait>(
embed_public_private_shares: bool,
) {
let num_signers = 5;
let keys_per_signer = 2;
let (mut coordinators, mut signers) =
Expand All @@ -2401,6 +2486,7 @@ pub mod test {
None,
Some(Duration::from_millis(128)),
Some(Duration::from_millis(128)),
embed_public_private_shares,
);
let config = coordinators.first().unwrap().get_config();

Expand Down
22 changes: 16 additions & 6 deletions src/state_machine/coordinator/frost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,13 +229,18 @@ impl<Aggregator: AggregatorTrait> Coordinator<Aggregator> {
"DKG Round {}: Starting Private Share Distribution",
self.current_dkg_id
);
let dkg_public_shares = if self.config.embed_public_private_shares {
(0..self.config.num_signers)
.map(|id| (id, self.dkg_public_shares[&id].clone()))
.collect()
} else {
Default::default()
};
let dkg_begin = DkgPrivateBegin {
dkg_id: self.current_dkg_id,
key_ids: (1..self.config.num_keys + 1).collect(),
signer_ids: (0..self.config.num_signers).collect(),
dkg_public_shares: (0..self.config.num_signers)
.map(|id| (id, self.dkg_public_shares[&id].clone()))
.collect(),
dkg_public_shares,
};
let dkg_private_begin_msg = Packet {
sig: dkg_begin
Expand All @@ -254,13 +259,18 @@ impl<Aggregator: AggregatorTrait> Coordinator<Aggregator> {
"DKG Round {}: Starting DKG End Distribution",
self.current_dkg_id
);
let dkg_private_shares = if self.config.embed_public_private_shares {
(0..self.config.num_signers)
.map(|id| (id, self.dkg_private_shares[&id].clone()))
.collect()
} else {
Default::default()
};
let dkg_begin = DkgEndBegin {
dkg_id: self.current_dkg_id,
key_ids: (0..self.config.num_keys).collect(),
signer_ids: (0..self.config.num_signers).collect(),
dkg_private_shares: (0..self.config.num_signers)
.map(|id| (id, self.dkg_private_shares[&id].clone()))
.collect(),
dkg_private_shares,
};
let dkg_end_begin_msg = Packet {
sig: dkg_begin.sign(&self.config.message_private_key).expect(""),
Expand Down
Loading

0 comments on commit 8e411c1

Please sign in to comment.