Skip to content

Commit

Permalink
[cryptography/bls12381] Refactor DKG (Contributor -> Dealer + Player) (
Browse files Browse the repository at this point in the history
  • Loading branch information
patrick-ogrady authored Jan 6, 2025
1 parent 73cb9c8 commit 3fd6245
Show file tree
Hide file tree
Showing 22 changed files with 2,343 additions and 2,511 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion cryptography/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ ed25519-consensus = "2.1.0"
blst = { version = "0.3.13", features = ["no-threads"] }
zeroize = "1.5.7"
rayon = "1.10"
itertools = "0.13.0"

[dev-dependencies]
criterion = { workspace = true }
Expand Down
114 changes: 43 additions & 71 deletions cryptography/src/bls12381/benches/dkg_recovery.rs
Original file line number Diff line number Diff line change
@@ -1,81 +1,53 @@
use commonware_cryptography::bls12381::dkg::utils::threshold;
use commonware_cryptography::bls12381::dkg::{Dealer, Player};
use commonware_cryptography::Ed25519;
use commonware_cryptography::{bls12381::dkg, Scheme};
use commonware_cryptography::Scheme;
use commonware_utils::quorum;
use criterion::{criterion_group, BatchSize, Criterion};
use std::collections::HashMap;
use std::hint::black_box;

/// Concurrency isn't used in DKG recovery, so we set it to 1.
const CONCURRENCY: usize = 1;

fn benchmark_dkg_recovery(c: &mut Criterion) {
let concurrency = 1; // only used in recovery during reshare
for &n in &[5, 10, 20, 50, 100, 250, 500] {
let t = threshold(n).unwrap();
c.bench_function(
&format!("{}/conc={} n={} t={}", module_path!(), concurrency, n, t),
|b| {
b.iter_batched(
|| {
// Create contributors
let mut contributors = (0..n)
.map(|i| Ed25519::from_seed(i as u64).public_key())
.collect::<Vec<_>>();
contributors.sort();

// Create shares
let mut contributor = None;
let mut commitments = HashMap::new();
for i in 0..n {
let me = contributors[i as usize].clone();
let p0 = dkg::contributor::P0::new(
me,
None,
contributors.clone(),
contributors.clone(),
concurrency,
);
let (p1, commitment, shares) = p0.finalize();
if i == 0 {
contributor = p1;
}
commitments.insert(i, (commitment, shares));
}
let mut contributor = contributor.unwrap();

// Distribute commitments
for i in 0..n {
// Get recipient share
let (commitment, _) = commitments.get(&i).unwrap();
let commitment = commitment.clone();

// Send share to contributor
let dealer = contributors[i as usize].clone();
contributor.commitment(dealer, commitment).unwrap();
}

// Convert to p1
let mut contributor = contributor.finalize().unwrap();

// Distribute shares
for i in 0..n {
// Get recipient share
let (_, shares) = commitments.get(&i).unwrap();
let share = shares[0];

// Send share to contributor
let dealer = contributors[i as usize].clone();
contributor.share(dealer, share).unwrap();
}

// Finalize
let commitments = (0..t).collect::<Vec<_>>();
(contributor, commitments)
},
|(contributor, commitments)| {
black_box(contributor.finalize(commitments).unwrap());
},
BatchSize::SmallInput,
);
},
);
let t = quorum(n).unwrap();
c.bench_function(&format!("{}/n={} t={}", module_path!(), n, t), |b| {
b.iter_batched(
|| {
// Create contributors
let mut contributors = (0..n)
.map(|i| Ed25519::from_seed(i as u64).public_key())
.collect::<Vec<_>>();
contributors.sort();

// Create player
let me = contributors[0].clone();
let mut player = Player::new(
me.clone(),
None,
contributors.clone(),
contributors.clone(),
CONCURRENCY,
);

// Create commitments and send shares to player
let mut commitments = HashMap::new();
for (idx, dealer) in contributors.iter().take(t as usize).enumerate() {
let (_, commitment, shares) = Dealer::new(None, contributors.clone());
player
.share(dealer.clone(), commitment.clone(), shares[0])
.unwrap();
commitments.insert(idx as u32, commitment);
}
(player, commitments)
},
|(player, commitments)| {
black_box(player.finalize(commitments, HashMap::new()).unwrap());
},
BatchSize::SmallInput,
);
});
}
}

Expand Down
169 changes: 51 additions & 118 deletions cryptography/src/bls12381/benches/dkg_reshare_recovery.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use commonware_cryptography::{
bls12381::{
dkg::{self, utils::threshold},
primitives::poly,
},
bls12381::dkg::{Dealer, Player},
Ed25519, Scheme,
};
use commonware_utils::quorum;
use criterion::{criterion_group, BatchSize, Criterion};
use std::collections::HashMap;
use std::hint::black_box;
Expand All @@ -22,76 +20,40 @@ fn benchmark_dkg_reshare_recovery(c: &mut Criterion) {
.collect::<Vec<_>>();
contributors.sort();

// Create shares
let t = threshold(n).unwrap();
let mut contributor_shares = HashMap::new();
let mut commitments = Vec::new();
for i in 0..n {
let me = contributors[i as usize].clone();
let p0 =
dkg::contributor::P0::new(me, None, contributors.clone(), contributors.clone(), 1);
let (p1, commitment, shares) = p0.finalize();
contributor_shares.insert(i, (commitment.clone(), shares, p1.unwrap()));
commitments.push(commitment);
}

// Distribute commitments
for i in 0..n {
let dealer = contributors[i as usize].clone();
for j in 0..n {
// Get recipient share
let (commitment, _, _) = contributor_shares.get(&i).unwrap();
let commitment = commitment.clone();

// Send share to recipient
let (_, _, ref mut recipient) = contributor_shares.get_mut(&j).unwrap();
recipient.commitment(dealer.clone(), commitment).unwrap();
}
}

// Convert to p2
let mut p2 = HashMap::new();
for i in 0..n {
let (_, shares, contributor) = contributor_shares.remove(&i).unwrap();
let contributor = contributor.finalize().unwrap();
p2.insert(i, (shares, contributor));
// Create players
let mut players = Vec::with_capacity(n);
for con in &contributors {
let player = Player::new(
con.clone(),
None,
contributors.clone(),
contributors.clone(),
1,
);
players.push(player);
}
let mut contributor_shares = p2;

// Distribute shares
for i in 0..n {
let dealer = contributors[i as usize].clone();
for j in 0..n {
// Get recipient share
let (shares, _) = contributor_shares.get(&i).unwrap();
let share = shares[j as usize];

// Send share to recipient
let (_, recipient) = contributor_shares.get_mut(&j).unwrap();
recipient.share(dealer.clone(), share).unwrap();
// Create commitments and send shares to players
let t = quorum(n as u32).unwrap();
let mut commitments = HashMap::new();
for (dealer_idx, dealer) in contributors.iter().take(t as usize).enumerate() {
let (_, commitment, shares) = Dealer::new(None, contributors.clone());
for (player_idx, player) in players.iter_mut().enumerate() {
player
.share(dealer.clone(), commitment.clone(), shares[player_idx])
.unwrap();
}
commitments.insert(dealer_idx as u32, commitment);
}

// Finalize
let included_commitments = (0..t).collect::<Vec<_>>();
let commitments = commitments[0..t as usize].to_vec();
let mut group: Option<poly::Public> = None;
// Finalize players
let mut outputs = Vec::new();
for i in 0..n {
let (_, contributor) = contributor_shares.remove(&i).unwrap();
let output = contributor
.finalize(included_commitments.clone())
.expect("unable to finalize");
assert_eq!(output.commitments, commitments);
match &group {
Some(group) => {
assert_eq!(output.public, *group);
}
None => {
group = Some(output.public.clone());
}
}
outputs.push(output);
for player in players {
outputs.push(
player
.finalize(commitments.clone(), HashMap::new())
.unwrap(),
);
}

for &concurrency in &[1, 2, 4, 8] {
Expand All @@ -100,59 +62,30 @@ fn benchmark_dkg_reshare_recovery(c: &mut Criterion) {
|b| {
b.iter_batched(
|| {
// Create reshare
let group = group.clone().unwrap();
let mut contributor = None;
// Create player
let me = contributors[0].clone();
let mut player = Player::new(
me.clone(),
Some(outputs[0].public.clone()),
contributors.clone(),
contributors.clone(),
concurrency,
);

// Create commitments and send shares to player
let mut commitments = HashMap::new();
for i in 0..n {
let me = contributors[i as usize].clone();
let share = outputs[i as usize].share;
let p0 = dkg::contributor::P0::new(
me,
Some((group.clone(), share)),
contributors.clone(),
contributors.clone(),
concurrency,
);
let (p1, commitment, shares) = p0.finalize();
if i == 0 {
contributor = p1;
}
commitments.insert(i, (commitment, shares));
for (idx, dealer) in contributors.iter().take(t as usize).enumerate() {
let (_, commitment, shares) =
Dealer::new(Some(outputs[idx].share), contributors.clone());
player
.share(dealer.clone(), commitment.clone(), shares[0])
.unwrap();
commitments.insert(idx as u32, commitment);
}
let mut contributor = contributor.unwrap();

// Distribute commitments
for i in 0..n {
// Get recipient share
let (commitment, _) = commitments.get(&i).unwrap();
let commitment = commitment.clone();

// Send share to contributor
let dealer = contributors[i as usize].clone();
contributor.commitment(dealer, commitment).unwrap();
}

// Convert to p2
let mut contributor = contributor.finalize().unwrap();

// Distribute shares
for i in 0..n {
// Get recipient share
let (_, shares) = commitments.get(&i).unwrap();
let share = shares[0];

// Send share to contributor
let dealer = contributors[i as usize].clone();
contributor.share(dealer, share).unwrap();
}

// Finalize
let commitments = (0..t).collect::<Vec<_>>();
(contributor, commitments)
(player, commitments)
},
|(contributor, commitments)| {
black_box(contributor.finalize(commitments).unwrap());
|(player, commitments)| {
black_box(player.finalize(commitments, HashMap::new()).unwrap());
},
BatchSize::SmallInput,
);
Expand Down
Loading

0 comments on commit 3fd6245

Please sign in to comment.