use crate::{
encoding::BinaryMarshaler,
group::edwards25519::SuiteEd25519,
share::{self, dkg, vss::suite::Suite},
sign::dss::DistKeyShare,
Group, Point, Random, Scalar,
};
const NUM_NODES: usize = 3;
const THRESHOLD: usize = NUM_NODES;
struct Node<SUITE: Suite> {
dkg: dkg::rabin::DistKeyGenerator<SUITE>,
_pub_key: SUITE::POINT,
priv_key: <SUITE::POINT as Point>::SCALAR,
deals: Vec<dkg::rabin::Deal<SUITE::POINT>>,
resps: Vec<dkg::rabin::Response>,
secret_share: share::poly::PriShare<<SUITE::POINT as Point>::SCALAR>,
distributed_public_key: SUITE::POINT,
}
#[test]
fn test_example_dkg() {
let suite = SuiteEd25519::new_blake3_sha256_ed25519();
let mut nodes = Vec::with_capacity(NUM_NODES);
let mut pub_keys = Vec::with_capacity(NUM_NODES);
for _ in 0..NUM_NODES {
let priv_key = suite.scalar().pick(&mut suite.random_stream());
let pub_key = suite.point().mul(&priv_key, None);
pub_keys.push(pub_key);
nodes.push(Node::<SuiteEd25519> {
dkg: Default::default(),
_pub_key: pub_key,
priv_key,
deals: Vec::new(),
resps: Vec::new(),
secret_share: Default::default(),
distributed_public_key: Default::default(),
});
}
for node in nodes.iter_mut() {
let dkg = dkg::rabin::new_dist_key_generator(
&suite,
&node.priv_key.clone(),
&pub_keys,
THRESHOLD,
)
.unwrap();
node.dkg = dkg;
}
let mut all_deals = Vec::new();
for node in nodes.iter_mut() {
let deals = node.dkg.deals().unwrap();
all_deals.push(deals);
}
for deals in all_deals {
for (i, deal) in deals {
nodes[i].deals.push(deal);
}
}
let mut all_resps = Vec::new();
for (i, node) in nodes.iter_mut().enumerate() {
for deal in node.deals.clone() {
let resp = node.dkg.process_deal(&deal).unwrap();
all_resps.push((i, resp));
}
}
for (i, node) in nodes.iter_mut().enumerate() {
for (j, resp) in all_resps.clone() {
if i == j {
continue;
}
node.resps.push(resp);
}
}
let mut all_justifications = Vec::new();
for node in nodes.iter_mut() {
for resp in node.resps.clone() {
let justification = node.dkg.process_response(&resp).unwrap();
all_justifications.push(justification);
}
}
for (i, node) in nodes.iter_mut().enumerate() {
for j in all_justifications.clone() {
if j.is_none() {
continue;
}
let justification = j.unwrap();
if justification.index == i as u32 {
continue;
}
assert!(
node.dkg.process_justification(&justification).is_ok(),
"dealer misbehaved"
)
}
}
for (i, node) in nodes.iter().enumerate() {
assert!(node.dkg.certified());
assert_eq!(THRESHOLD, node.dkg.qual().len());
println!(
"Qualified nodes (from node {} prospective): {:?}",
i,
node.dkg.qual()
);
}
let mut scs = Vec::new();
for (_, node) in nodes.iter_mut().enumerate() {
let sc = node.dkg.secret_commits().unwrap();
scs.push(sc);
}
let mut ccs = Vec::new();
for sc in scs.iter() {
for node in nodes.iter_mut() {
let cc = node.dkg.process_secret_commits(sc).unwrap();
ccs.push(cc);
}
}
let mut rcs = Vec::new();
for (i, node) in nodes.iter_mut().enumerate() {
for cc in ccs.clone() {
if cc.is_none() {
continue;
}
let complaint = cc.unwrap();
if complaint.index == i as u32 {
continue;
}
let rc = node.dkg.process_complaint_commits(&complaint).unwrap();
rcs.push(rc);
}
}
for rc in rcs.clone() {
for node in nodes.iter_mut() {
node.dkg.process_reconstruct_commits(&rc).unwrap();
}
}
for (i, node) in nodes.iter_mut().enumerate() {
let dks = node.dkg.dist_key_share().unwrap();
node.secret_share = dks.pri_share();
node.distributed_public_key = dks.public();
println!(
"Distributed public key (from node {} prospective): {:?}",
i,
node.distributed_public_key.marshal_binary().unwrap()
);
}
}