Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 19 additions & 18 deletions timeboost-crypto/src/feldman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,51 +302,52 @@ impl<C: CurveGroup> KeyResharing<Self> for FeldmanVss<C> {
old_pp: &FeldmanVssPublicParam<C>,
new_pp: &FeldmanVssPublicParam<C>,
recv_node_idx: usize,
reshares: impl ExactSizeIterator<Item = (usize, C::ScalarField, FeldmanCommitment<C>)> + Clone,
reshares: impl Iterator<Item = (usize, C::ScalarField, FeldmanCommitment<C>)>,
) -> Result<(C::ScalarField, FeldmanCommitment<C>), VssError> {
// input validation
let n = old_pp.n.get();
if reshares.len() == 0 {
return Err(VssError::EmptyReshare);
}
for (idx, _, _) in reshares.clone() {

let mut eval_points = Vec::new();
let mut recv_shares = Vec::new();
let mut row_commitments = Vec::new();

for (idx, share, commitment) in reshares {
if idx >= n {
return Err(VssError::IndexOutOfBound(n - 1, idx));
}
eval_points.push(C::ScalarField::from(idx as u64 + 1));
recv_shares.push(share);
row_commitments.push(commitment);
}

if eval_points.is_empty() {
return Err(VssError::EmptyReshare);
}

let new_n = new_pp.n.get();
let new_t = new_pp.t.get();
if recv_node_idx >= new_n {
return Err(VssError::IndexOutOfBound(new_n - 1, recv_node_idx));
}
for (_, _, row_commitment) in reshares.clone() {
if row_commitment.len() != new_t {
return Err(VssError::InvalidCommitment);
}

if row_commitments.iter().any(|c| c.len() != new_t) {
return Err(VssError::InvalidCommitment);
}

// interpolate reshares to get new secret share
let eval_points: Vec<_> = reshares
.clone()
.map(|(idx, _, _)| C::ScalarField::from(idx as u64 + 1))
.collect();
let recv_reshares: Vec<_> = reshares.clone().map(|(_, share, _)| share).collect();
let new_secret = interpolate::<C>(&eval_points, &recv_reshares)
let new_secret = interpolate::<C>(&eval_points, &recv_shares)
.map_err(|e| VssError::FailedCombine(e.to_string()))?;

// interpolate in the exponent to get new Feldman commitment
let row_commitments: Vec<_> = reshares.map(|(_, _, commitment)| commitment).collect();
let new_commitment = (0..new_t)
.into_par_iter()
.map(|j| {
let j_th_coeffs: Vec<C::Affine> =
row_commitments.iter().map(|row| row[j]).collect();
interpolate_in_exponent::<C>(&eval_points, &j_th_coeffs)
.map_err(|e| VssError::FailedCombine(e.to_string()))
.map(|p| p.into_affine())
})
.collect::<Result<Vec<_>, VssError>>()?;
let new_commitment = C::normalize_batch(&new_commitment);

Ok((new_secret, new_commitment.into()))
}
Expand Down
2 changes: 1 addition & 1 deletion timeboost-crypto/src/traits/dkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub trait KeyResharing<VSS: VerifiableSecretSharing> {
old_pp: &VSS::PublicParam,
new_pp: &VSS::PublicParam,
recv_node_idx: usize,
reshares: impl ExactSizeIterator<Item = (usize, VSS::SecretShare, VSS::Commitment)> + Clone,
reshares: impl Iterator<Item = (usize, VSS::SecretShare, VSS::Commitment)>,
) -> Result<(VSS::Secret, VSS::Commitment), VssError>;
}

Expand Down
2 changes: 1 addition & 1 deletion timeboost-sequencer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ tracing = { workspace = true }
ark-std = { workspace = true }
bs58 = { workspace = true }
futures = { workspace = true }
test-utils = { path = "../test-utils", features = ["ports"]}
test-utils = { path = "../test-utils", features = ["ports"] }
timeboost-utils = { path = "../timeboost-utils" }
44 changes: 27 additions & 17 deletions timeboost-sequencer/src/decrypt.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
use std::result::Result as StdResult;
use std::sync::Arc;

use ark_std::{UniformRand, rand::thread_rng};
use bon::Builder;
use bytes::{BufMut, Bytes, BytesMut};
use cliquenet::overlay::{Data, DataError, NetworkDown, Overlay};
use cliquenet::{
AddressableCommittee, MAX_MESSAGE_SIZE, Network, NetworkError, NetworkMetrics, Role,
};
use rayon::iter::ParallelIterator;
use rayon::prelude::*;

use multisig::{Committee, CommitteeId, PublicKey};
use parking_lot::RwLock;
use rayon::iter::ParallelIterator;
use rayon::prelude::*;
use sailfish::types::{Evidence, Round, RoundNumber};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
use std::result::Result as StdResult;
use std::sync::Arc;
use timeboost_config::DECRYPTER_PORT_OFFSET;
use timeboost_crypto::prelude::{
DkgDecKey, LabeledDkgDecKey, Plaintext, ThresholdCiphertext, ThresholdDecShare,
ThresholdEncError, ThresholdEncScheme, ThresholdScheme, Vess, VssSecret,
};
use timeboost_types::{
AccumulatorMode, DkgAccumulator, DkgBundle, DkgSubset, InclusionList, KeyStore, KeyStoreVec,
ThresholdKey, ThresholdKeyCell,
AccumulatorMode, DkgAccumulator, DkgBundle, DkgSubset, DkgSubsetRef, InclusionList, KeyStore,
KeyStoreVec, ThresholdKey, ThresholdKeyCell,
};
use tokio::spawn;
use tokio::sync::mpsc::{Receiver, Sender, channel};
Expand Down Expand Up @@ -728,21 +728,31 @@ impl Worker {
.ok_or(DecrypterError::NoCommittee(self.current))?;

let prev = (guard.len() == 2).then(|| guard.last().clone());

subsets.insert(src, res.subset.to_owned());
let committee = current.committee();
let threshold: usize = committee.one_honest_threshold().into();

let mut counts = HashMap::new();
for subset in subsets.values() {
*counts.entry(subset).or_insert(0) += 1;
subsets.insert(src, res.subset);

let mut subset_groups: HashMap<DkgSubsetRef, Vec<&PublicKey>> = HashMap::new();
let mut threshold_subset = None;

for (pk, subset) in subsets.iter() {
let pks = subset_groups.entry(subset.as_ref()).or_default();
pks.push(pk);

if pks.len() >= threshold {
threshold_subset = Some((subset.as_ref(), pks[0]));
break;
}
}

if let Some((&subset, _)) = counts.iter().find(|(_, count)| **count >= threshold) {
let acc = DkgAccumulator::from_subset(current.clone(), subset.to_owned());
if let Some((subset_ref, pk)) = threshold_subset {
let subset = subsets.to_owned().remove(pk).expect("subset exists in map");
let acc = DkgAccumulator::from_subset(current.clone(), subset);
let mode = acc.mode().clone();
self.tracker.insert(committee.id(), acc);
let dec_key = subset

let dec_key = subset_ref
.extract_key(current, &self.dkg_sk, prev.as_ref())
.map_err(|e| DecrypterError::Dkg(e.to_string()))?;

Expand Down Expand Up @@ -830,7 +840,7 @@ impl Worker {
if matches!(mode, AccumulatorMode::Dkg) {
if let Some(subset) = acc.try_finalize() {
let dec_key = subset
.extract_key(&key_store.clone(), &self.dkg_sk, None)
.extract_key(&key_store, &self.dkg_sk, None)
.map_err(|e| DecrypterError::Dkg(e.to_string()))?;
self.dec_key.set(dec_key);
self.state = WorkerState::Running;
Expand Down
Loading