Module elastic_elgamal::dkg

source ·
Expand description

Committed Pedersen’s distributed key generation (DKG).

DKG allows to securely generate shared secret without a need for a trusted dealer. Compare with Feldman’s verifiable secret sharing implemented in the sharing module which requires a trusted dealer.

This implementation is based on Pedersen’s DKG, which was shown by Gennaro et al. to contain a flaw allowing an adversary to bias distribution of the shared public key. We try to prevent this kind of possible attacks by forcing the parties to commit to their public key shares before receiving public shares from other parties.

§Examples

Decentralized key generation for 2-of-3 threshold encryption.

let mut rng = thread_rng();
let params = Params::new(3, 2);

// Initialize participants.
let participants = (0..3).map(|i| {
    ParticipantCollectingCommitments::<Ristretto>::new(params, i, &mut rng)
});
let mut participants: Vec<_> = participants.collect();

// Publish commitments from all participants...
let commitments: Vec<_> = participants
    .iter()
    .map(|participant| participant.commitment())
    .collect();
// ...and consume them from each participant's perspective.
for (i, participant) in participants.iter_mut().enumerate() {
    for (j, &commitment) in commitments.iter().enumerate() {
        if i != j {
            participant.insert_commitment(j, commitment);
        }
    }
}

// Transition all participants to the next stage: exchanging polynomials.
let mut participants: Vec<_> = participants
    .into_iter()
    .map(|participant| participant.finish_commitment_phase())
    .collect();
// Publish each participant's polynomial...
let infos: Vec<_> = participants
    .iter()
    .map(|participant| participant.public_info().into_owned())
    .collect();
// ...and consume them from each participant's perspective.
for (i, participant) in participants.iter_mut().enumerate() {
    for (j, info) in infos.iter().enumerate() {
        if i != j {
            participant.insert_public_polynomial(j, info.clone())?;
        }
    }
}

// Transition all participants to the final phase: exchanging secrets.
let mut participants: Vec<_> = participants
    .into_iter()
    .map(|participant| participant.finish_polynomials_phase())
    .collect();
// Exchange shares (this should happen over secure peer-to-peer channels).
for i in 0..3 {
    for j in 0..3 {
        if i == j { continue; }
        let share = participants[i].secret_share_for_participant(j);
        participants[j].insert_secret_share(i, share)?;
    }
}

// Finalize all participants.
let participants = participants
    .into_iter()
    .map(|participant| participant.complete())
    .collect::<Result<Vec<_>, _>>()?;
// Check that the shared key is the same for all participants.
let expected_key = participants[0].key_set().shared_key();
for participant in &participants {
    assert_eq!(participant.key_set().shared_key(), expected_key);
}

// Participants can then jointly decrypt messages as showcased
// in the example for the `sharing` module.

Structs§

Enums§

  • Errors that can occur during the distributed key generation.