use crate::{
examples::enc_test::el_gamal_decrypt,
group::edwards25519::SuiteEd25519,
share::{
self,
dkg::{
self,
pedersen::{
new_dist_key_handler,
structs::{Deal, Response},
Config,
},
},
vss::suite::Suite,
},
sign::dss::DistKeyShare,
Group, Point, Random, Scalar,
};
use super::enc_test::el_gamal_encrypt;
struct Node<SUITE: Suite> {
dkg: dkg::pedersen::DistKeyGenerator<SUITE, &'static [u8]>,
_pub_key: SUITE::POINT,
priv_key: <SUITE::POINT as Point>::SCALAR,
deals: Vec<Deal<SUITE::POINT>>,
resps: Vec<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 n = 7;
let mut nodes = Vec::with_capacity(n);
let mut pub_keys = Vec::with_capacity(n);
for _ in 0..n {
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> {
_pub_key: pub_key,
priv_key,
deals: Vec::new(),
resps: Vec::new(),
secret_share: Default::default(),
dkg: Default::default(),
distributed_public_key: Default::default(),
});
}
for node in nodes.iter_mut() {
let dkg =
dkg::pedersen::new_dist_key_generator(suite, node.priv_key, &pub_keys, n).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 (_, node) in nodes.iter_mut().enumerate() {
for j in all_justifications.clone() {
if j.is_none() {
continue;
}
let justification = j.unwrap();
assert!(
node.dkg.process_justification(&justification).is_ok(),
"dealer misbehaved"
)
}
}
for node in nodes.iter() {
assert!(node.dkg.certified());
assert_eq!(n, node.dkg.qualified_shares().len());
assert_eq!(n, node.dkg.qual().len());
println!("qualified shares: {:?}", node.dkg.qualified_shares());
println!("QUAL: {:?}", node.dkg.qual());
}
let mut shares = Vec::with_capacity(n);
let mut public_key = Default::default();
for node in nodes.iter_mut() {
let distr_key = node.dkg.dist_key_share().unwrap();
shares.push(Some(distr_key.pri_share()));
public_key = distr_key.public();
node.secret_share = distr_key.pri_share();
node.distributed_public_key = public_key;
println!("new distributed public key {public_key:?}");
}
let message = "Hello world".as_bytes();
let secret_key = share::poly::recover_secret(suite, &shares, n, n).unwrap();
let (k, c, remainder) = el_gamal_encrypt(suite, &public_key, message);
assert_eq!(remainder.len(), 0);
let decrypted_message = el_gamal_decrypt(suite, &secret_key, k, c).unwrap();
assert_eq!(message.to_vec(), decrypted_message);
let mut partials = Vec::with_capacity(n);
let mut pub_shares = Vec::with_capacity(n);
for (i, node) in nodes.iter().enumerate() {
let s = suite.point().mul(&node.secret_share.v, Some(&k));
partials.push(suite.point().sub(&c, &s));
pub_shares.push(Some(share::poly::PubShare { i, v: partials[i] }));
}
let res = share::poly::recover_commit(suite, &pub_shares, n, n).unwrap();
let decrypted_message = res.data().unwrap();
assert_eq!(message.to_vec(), decrypted_message);
let a = public_key;
let r = suite.scalar().pick(&mut suite.random_stream());
let m = suite
.point()
.embed(Some(message), &mut suite.random_stream());
let c = suite.point().add(
&suite.point().mul(&r, Some(&a)), &m,
);
let u = suite.point().mul(&r, None);
let p = suite.scalar().pick(&mut suite.random_stream());
let q = suite.point().mul(&p, None);
let mut partials = Vec::with_capacity(n);
let mut pub_shares = Vec::with_capacity(n);
for (i, node) in nodes.iter().enumerate() {
let v = suite.point().add(
&suite.point().mul(&node.secret_share.v, Some(&u)), &suite.point().mul(&node.secret_share.v, Some(&q)), );
partials.push(v);
pub_shares.push(Some(share::poly::PubShare { i, v: partials[i] }));
}
let r_p = share::poly::recover_commit(suite, &pub_shares, n, n).unwrap();
let decrypted_point = suite.point().sub(
&c,
&suite.point().sub(
&r_p,
&suite.point().mul(&p, Some(&a)), ),
);
let decrypted_message = decrypted_point.data().unwrap();
assert_eq!(decrypted_message, message.to_vec());
for node in nodes.iter_mut() {
let share = node.dkg.dist_key_share().unwrap();
let c = Config {
suite,
longterm: node.priv_key,
old_nodes: pub_keys.clone(),
new_nodes: pub_keys.clone(),
share: Some(share),
threshold: n,
old_threshold: n,
public_coeffs: None,
reader: None,
user_reader_only: false,
};
let new_dkg = new_dist_key_handler(c).unwrap();
node.dkg = new_dkg;
}
}