DKG resharing unit test (#2668)
This commit is contained in:
committed by
GitHub
parent
3ebb24b2c8
commit
bb557985c0
@@ -326,11 +326,6 @@ pub fn try_recover_verification_keys(
|
||||
return Err(DkgError::MismatchedDealings);
|
||||
}
|
||||
|
||||
// currently we expect every dealer to also be a receiver. This restriction might be relaxed in the future
|
||||
if dealings.len() != receivers.len() {
|
||||
return Err(DkgError::MismatchedDealings);
|
||||
}
|
||||
|
||||
let indices = receivers.keys().collect::<Vec<_>>();
|
||||
|
||||
// Compute A0, ..., A_{t-1}
|
||||
|
||||
@@ -254,3 +254,125 @@ fn full_threshold_secret_resharing() {
|
||||
assert_ne!(derived_secrets, reshared_secrets);
|
||||
assert_ne!(recovered_partials, reshared_partials);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // expensive test
|
||||
fn full_threshold_secret_resharing_left_party() {
|
||||
let dummy_seed = [42u8; 32];
|
||||
let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed);
|
||||
let params = setup();
|
||||
|
||||
// the simplest possible case
|
||||
let threshold = 2;
|
||||
|
||||
// the indices are going to get assigned externally, so for test sake, use non-consecutive ones
|
||||
let mut node_indices = vec![15u64, 248, 33521];
|
||||
|
||||
let mut receivers = BTreeMap::new();
|
||||
let mut full_keys = Vec::new();
|
||||
for index in &node_indices {
|
||||
let (dk, pk) = keygen(¶ms, &mut rng);
|
||||
receivers.insert(*index, *pk.public_key());
|
||||
full_keys.push((dk, pk))
|
||||
}
|
||||
|
||||
let first_dealings = node_indices
|
||||
.iter()
|
||||
.map(|&dealer_index| {
|
||||
Dealing::create(&mut rng, ¶ms, dealer_index, threshold, &receivers, None).0
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// recover verification keys
|
||||
let RecoveredVerificationKeys {
|
||||
recovered_master: public_original_master,
|
||||
recovered_partials,
|
||||
} = try_recover_verification_keys(&first_dealings, threshold, &receivers).unwrap();
|
||||
|
||||
let mut derived_secrets = Vec::new();
|
||||
for (i, (ref mut dk, _)) in full_keys.iter_mut().enumerate() {
|
||||
let shares = first_dealings
|
||||
.iter()
|
||||
.map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap())
|
||||
.collect();
|
||||
|
||||
let recovered_secret =
|
||||
combine_shares(shares, &receivers.keys().copied().collect::<Vec<_>>()).unwrap();
|
||||
|
||||
derived_secrets.push(recovered_secret)
|
||||
}
|
||||
|
||||
let original_master = perform_lagrangian_interpolation_at_origin(&[
|
||||
(Scalar::from(node_indices[0]), derived_secrets[0]),
|
||||
(Scalar::from(node_indices[1]), derived_secrets[1]),
|
||||
])
|
||||
.unwrap();
|
||||
|
||||
// one party leaves the process
|
||||
let left_party_index = node_indices.pop().unwrap();
|
||||
receivers.remove(&left_party_index);
|
||||
full_keys.pop();
|
||||
// and another one joins, but we're still over the threshold value of initial parties
|
||||
let join_party_index = 100000;
|
||||
let (dk, pk) = keygen(¶ms, &mut rng);
|
||||
receivers.insert(join_party_index, *pk.public_key());
|
||||
full_keys.push((dk, pk));
|
||||
|
||||
// only initial parties attempt to create resharing dealings!
|
||||
let resharing_dealings = node_indices
|
||||
.iter()
|
||||
.zip(derived_secrets.iter().take(2))
|
||||
.map(|(&dealer_index, prior_secret)| {
|
||||
Dealing::create(
|
||||
&mut rng,
|
||||
¶ms,
|
||||
dealer_index,
|
||||
threshold,
|
||||
&receivers,
|
||||
Some(*prior_secret),
|
||||
)
|
||||
.0
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for (reshared_dealing, prior_vk) in resharing_dealings
|
||||
.iter()
|
||||
.zip(recovered_partials.iter().take(2))
|
||||
{
|
||||
reshared_dealing
|
||||
.verify(¶ms, threshold, &receivers, Some(*prior_vk))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// recover verification keys
|
||||
let RecoveredVerificationKeys {
|
||||
recovered_master: public_reshared_master,
|
||||
recovered_partials: reshared_partials,
|
||||
} = try_recover_verification_keys(&resharing_dealings, threshold, &receivers).unwrap();
|
||||
|
||||
let mut reshared_secrets = Vec::new();
|
||||
for (i, (ref mut dk, _)) in full_keys.iter_mut().enumerate() {
|
||||
let shares = resharing_dealings
|
||||
.iter()
|
||||
.map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap())
|
||||
.collect();
|
||||
|
||||
let recovered_secret = combine_shares(shares, &node_indices).unwrap();
|
||||
|
||||
reshared_secrets.push(recovered_secret)
|
||||
}
|
||||
|
||||
let reshared_master = perform_lagrangian_interpolation_at_origin(&[
|
||||
(Scalar::from(node_indices[0]), reshared_secrets[0]),
|
||||
(Scalar::from(join_party_index), reshared_secrets[2]),
|
||||
])
|
||||
.unwrap();
|
||||
|
||||
// the master secret and public values didn't change
|
||||
assert_eq!(original_master, reshared_master);
|
||||
assert_eq!(public_original_master, public_reshared_master);
|
||||
|
||||
// but partials did
|
||||
assert_ne!(derived_secrets, reshared_secrets);
|
||||
assert_ne!(recovered_partials, reshared_partials);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user