Skip to main content

yip_ca/threshold/
dkg.rs

1use crate::threshold::ThresholdError;
2use frost::keys::dkg::{round1, round2};
3use frost::keys::{KeyPackage, PublicKeyPackage};
4use frost::Identifier;
5use frost_ed25519 as frost;
6use std::collections::BTreeMap;
7
8/// Step 1 of DKG: generate ephemeral polynomial and round 1 broadcast package.
9pub fn dkg_part1(
10    identifier: Identifier,
11    max_signers: u16,
12    min_signers: u16,
13) -> Result<(round1::SecretPackage, round1::Package), ThresholdError> {
14    if min_signers == 0 || min_signers > max_signers {
15        return Err(ThresholdError::InvalidParams(
16            "min_signers must be >= 1 and <= max_signers",
17        ));
18    }
19    let rng = rand::rngs::OsRng;
20    let (secret_package, package) =
21        frost::keys::dkg::part1(identifier, max_signers, min_signers, rng)?;
22    Ok((secret_package, package))
23}
24
25/// Step 2 of DKG: compute secret share packages for all other participants.
26pub fn dkg_part2(
27    secret_package: round1::SecretPackage,
28    round1_packages: &BTreeMap<Identifier, round1::Package>,
29) -> Result<(round2::SecretPackage, BTreeMap<Identifier, round2::Package>), ThresholdError> {
30    let (secret_package, packages) = frost::keys::dkg::part2(secret_package, round1_packages)?;
31    Ok((secret_package, packages))
32}
33
34/// Step 3 of DKG: verify received shares and assemble the final KeyPackage and PublicKeyPackage.
35pub fn dkg_part3(
36    round2_secret_package: &round2::SecretPackage,
37    round1_packages: &BTreeMap<Identifier, round1::Package>,
38    round2_packages: &BTreeMap<Identifier, round2::Package>,
39) -> Result<(KeyPackage, PublicKeyPackage), ThresholdError> {
40    let (key_package, pubkey_package) =
41        frost::keys::dkg::part3(round2_secret_package, round1_packages, round2_packages)?;
42    Ok((key_package, pubkey_package))
43}