Skip to content

Commit

Permalink
Switch to BTreeMap for round accumulators
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Jan 6, 2024
1 parent b4d5300 commit 1441e96
Show file tree
Hide file tree
Showing 13 changed files with 605 additions and 363 deletions.
135 changes: 126 additions & 9 deletions synedrion/src/cggmp21/protocols/generic.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use alloc::collections::{BTreeMap, BTreeSet};
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt::Debug;
Expand All @@ -6,7 +7,7 @@ use rand_core::CryptoRngCore;
use serde::{Deserialize, Serialize};

use super::common::PartyIdx;
use crate::tools::collections::{HoleRange, HoleVec};
use crate::tools::collections::{HoleRange, HoleVec, HoleVecAccum};

/// A round that sends out a broadcast.
pub(crate) trait BroadcastRound: BaseRound {
Expand Down Expand Up @@ -111,19 +112,93 @@ pub(crate) trait BaseRound {
const ROUND_NUM: u8;
// TODO (#78): find a way to derive it from `ROUND_NUM`
const NEXT_ROUND_NUM: Option<u8>;

fn num_parties(&self) -> usize;
fn party_idx(&self) -> PartyIdx;
}

pub(crate) trait Round: BroadcastRound + DirectRound + BaseRound + Finalizable {}

impl<R: BroadcastRound + DirectRound + BaseRound + Finalizable> Round for R {}

#[allow(clippy::enum_variant_names)]
pub(crate) enum FinalizationRequirement {
AllBroadcasts,
AllDms,
AllBroadcastsAndDms,
}

pub(crate) trait Round: BroadcastRound + DirectRound + BaseRound {}
pub(crate) trait Finalizable: BroadcastRound + DirectRound {
fn requirement() -> FinalizationRequirement;

impl<R: BroadcastRound + DirectRound + BaseRound> Round for R {}
fn can_finalize<'a>(
&self,
bc_payloads: impl Iterator<Item = &'a PartyIdx>,
dm_payloads: impl Iterator<Item = &'a PartyIdx>,
dm_artifacts: impl Iterator<Item = &'a PartyIdx>,
) -> bool {
match Self::requirement() {
FinalizationRequirement::AllBroadcasts => {
contains_all_except(bc_payloads, self.num_parties(), self.party_idx())
}
FinalizationRequirement::AllDms => {
contains_all_except(dm_payloads, self.num_parties(), self.party_idx())
&& contains_all_except(dm_artifacts, self.num_parties(), self.party_idx())
}
FinalizationRequirement::AllBroadcastsAndDms => {
contains_all_except(bc_payloads, self.num_parties(), self.party_idx())
&& contains_all_except(dm_payloads, self.num_parties(), self.party_idx())
&& contains_all_except(dm_artifacts, self.num_parties(), self.party_idx())
}
}
}

fn missing_payloads<'a>(
&self,
bc_payloads: impl Iterator<Item = &'a PartyIdx>,
dm_payloads: impl Iterator<Item = &'a PartyIdx>,
dm_artifacts: impl Iterator<Item = &'a PartyIdx>,
) -> BTreeSet<PartyIdx> {
match Self::requirement() {
FinalizationRequirement::AllBroadcasts => {
missing_payloads(bc_payloads, self.num_parties(), self.party_idx())
}
FinalizationRequirement::AllDms => {
let mut missing =
missing_payloads(dm_payloads, self.num_parties(), self.party_idx());
missing.append(&mut missing_payloads(
dm_artifacts,
self.num_parties(),
self.party_idx(),
));
missing
}
FinalizationRequirement::AllBroadcastsAndDms => {
let mut missing =
missing_payloads(bc_payloads, self.num_parties(), self.party_idx());
missing.append(&mut missing_payloads(
dm_payloads,
self.num_parties(),
self.party_idx(),
));
missing.append(&mut missing_payloads(
dm_artifacts,
self.num_parties(),
self.party_idx(),
));
missing
}
}
}
}

pub(crate) trait FinalizableToResult: Round + BaseRound<Type = ToResult> {
fn finalize_to_result(
self,
rng: &mut impl CryptoRngCore,
bc_payloads: Option<HoleVec<<Self as BroadcastRound>::Payload>>,
dm_payloads: Option<HoleVec<<Self as DirectRound>::Payload>>,
dm_artifacts: Option<HoleVec<<Self as DirectRound>::Artifact>>,
bc_payloads: BTreeMap<PartyIdx, <Self as BroadcastRound>::Payload>,
dm_payloads: BTreeMap<PartyIdx, <Self as DirectRound>::Payload>,
dm_artifacts: BTreeMap<PartyIdx, <Self as DirectRound>::Artifact>,
) -> Result<<Self::Result as ProtocolResult>::Success, FinalizeError<Self::Result>>;
}

Expand All @@ -132,9 +207,9 @@ pub(crate) trait FinalizableToNextRound: Round + BaseRound<Type = ToNextRound> {
fn finalize_to_next_round(
self,
rng: &mut impl CryptoRngCore,
bc_payloads: Option<HoleVec<<Self as BroadcastRound>::Payload>>,
dm_payloads: Option<HoleVec<<Self as DirectRound>::Payload>>,
dm_artifacts: Option<HoleVec<<Self as DirectRound>::Artifact>>,
bc_payloads: BTreeMap<PartyIdx, <Self as BroadcastRound>::Payload>,
dm_payloads: BTreeMap<PartyIdx, <Self as DirectRound>::Payload>,
dm_artifacts: BTreeMap<PartyIdx, <Self as DirectRound>::Artifact>,
) -> Result<Self::NextRound, FinalizeError<Self::Result>>;
}

Expand Down Expand Up @@ -177,3 +252,45 @@ pub(crate) fn all_parties_except(num_parties: usize, party_idx: PartyIdx) -> Vec
.map(PartyIdx::from_usize)
.collect()
}

fn contains_all_except<'a>(
party_idxs: impl Iterator<Item = &'a PartyIdx>,
num_parties: usize,
party_idx: PartyIdx,
) -> bool {
let set = party_idxs.cloned().collect::<BTreeSet<_>>();
for idx in HoleRange::new(num_parties, party_idx.as_usize()) {
if !set.contains(&PartyIdx::from_usize(idx)) {
return false;
}
}
true
}

fn missing_payloads<'a>(
party_idxs: impl Iterator<Item = &'a PartyIdx>,
num_parties: usize,
party_idx: PartyIdx,
) -> BTreeSet<PartyIdx> {
let set = party_idxs.cloned().collect::<BTreeSet<_>>();
let mut missing = BTreeSet::new();
for idx in HoleRange::new(num_parties, party_idx.as_usize()) {
let party_idx = PartyIdx::from_usize(idx);
if !set.contains(&party_idx) {
missing.insert(party_idx);
}
}
missing
}

pub(crate) fn try_to_holevec<T>(
payloads: BTreeMap<PartyIdx, T>,
num_parties: usize,
party_idx: PartyIdx,
) -> Option<HoleVec<T>> {
let mut accum = HoleVecAccum::new(num_parties, party_idx.as_usize());
for (idx, elem) in payloads.into_iter() {
accum.insert(idx.as_usize(), elem)?;
}
accum.finalize()
}
26 changes: 13 additions & 13 deletions synedrion/src/cggmp21/protocols/interactive_signing.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use alloc::boxed::Box;
use alloc::collections::BTreeMap;
use core::marker::PhantomData;

use rand_core::CryptoRngCore;
Expand All @@ -13,7 +14,6 @@ use super::signing::{self, SigningResult};
use super::wrappers::{wrap_finalize_error, ResultWrapper, RoundWrapper};
use crate::cggmp21::params::SchemeParams;
use crate::curve::{RecoverableSignature, Scalar};
use crate::tools::collections::HoleVec;

/// Possible results of the merged Presigning and Signing protocols.
#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -127,9 +127,9 @@ impl<P: SchemeParams> FinalizableToNextRound for Round1<P> {
fn finalize_to_next_round(
self,
rng: &mut impl CryptoRngCore,
bc_payloads: Option<HoleVec<<Self as BroadcastRound>::Payload>>,
dm_payloads: Option<HoleVec<<Self as DirectRound>::Payload>>,
dm_artifacts: Option<HoleVec<<Self as DirectRound>::Artifact>>,
bc_payloads: BTreeMap<PartyIdx, <Self as BroadcastRound>::Payload>,
dm_payloads: BTreeMap<PartyIdx, <Self as DirectRound>::Payload>,
dm_artifacts: BTreeMap<PartyIdx, <Self as DirectRound>::Artifact>,
) -> Result<Self::NextRound, FinalizeError<Self::Result>> {
let round = self
.round
Expand Down Expand Up @@ -163,9 +163,9 @@ impl<P: SchemeParams> FinalizableToNextRound for Round2<P> {
fn finalize_to_next_round(
self,
rng: &mut impl CryptoRngCore,
bc_payloads: Option<HoleVec<<Self as BroadcastRound>::Payload>>,
dm_payloads: Option<HoleVec<<Self as DirectRound>::Payload>>,
dm_artifacts: Option<HoleVec<<Self as DirectRound>::Artifact>>,
bc_payloads: BTreeMap<PartyIdx, <Self as BroadcastRound>::Payload>,
dm_payloads: BTreeMap<PartyIdx, <Self as DirectRound>::Payload>,
dm_artifacts: BTreeMap<PartyIdx, <Self as DirectRound>::Artifact>,
) -> Result<Self::NextRound, FinalizeError<Self::Result>> {
let round = self
.round
Expand Down Expand Up @@ -199,9 +199,9 @@ impl<P: SchemeParams> FinalizableToNextRound for Round3<P> {
fn finalize_to_next_round(
self,
rng: &mut impl CryptoRngCore,
bc_payloads: Option<HoleVec<<Self as BroadcastRound>::Payload>>,
dm_payloads: Option<HoleVec<<Self as DirectRound>::Payload>>,
dm_artifacts: Option<HoleVec<<Self as DirectRound>::Artifact>>,
bc_payloads: BTreeMap<PartyIdx, <Self as BroadcastRound>::Payload>,
dm_payloads: BTreeMap<PartyIdx, <Self as DirectRound>::Payload>,
dm_artifacts: BTreeMap<PartyIdx, <Self as DirectRound>::Artifact>,
) -> Result<Self::NextRound, FinalizeError<Self::Result>> {
let presigning_data = self
.round
Expand Down Expand Up @@ -250,9 +250,9 @@ impl<P: SchemeParams> FinalizableToResult for Round4<P> {
fn finalize_to_result(
self,
rng: &mut impl CryptoRngCore,
bc_payloads: Option<HoleVec<<Self as BroadcastRound>::Payload>>,
dm_payloads: Option<HoleVec<<Self as DirectRound>::Payload>>,
dm_artifacts: Option<HoleVec<<Self as DirectRound>::Artifact>>,
bc_payloads: BTreeMap<PartyIdx, <Self as BroadcastRound>::Payload>,
dm_payloads: BTreeMap<PartyIdx, <Self as DirectRound>::Payload>,
dm_artifacts: BTreeMap<PartyIdx, <Self as DirectRound>::Artifact>,
) -> Result<<Self::Result as ProtocolResult>::Success, FinalizeError<Self::Result>> {
self.round
.finalize_to_result(rng, bc_payloads, dm_payloads, dm_artifacts)
Expand Down
Loading

0 comments on commit 1441e96

Please sign in to comment.