1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2#![doc = include_str!("../README.md")]
3#![no_std]
4
5use core::ops::Deref;
6use std_shims::{vec::Vec, collections::HashMap};
7
8use zeroize::{Zeroize, Zeroizing};
9use rand_core::{RngCore, CryptoRng};
10
11use ciphersuite::{
12 group::ff::{Field, PrimeField},
13 Ciphersuite,
14};
15pub use dkg::*;
16
17pub fn key_gen<R: RngCore + CryptoRng, C: Ciphersuite>(
19 rng: &mut R,
20 threshold: u16,
21 participants: u16,
22) -> Result<HashMap<Participant, ThresholdKeys<C>>, DkgError> {
23 let mut coefficients = Vec::with_capacity(usize::from(participants));
24 for _ in 0 .. threshold.max(1) {
26 coefficients.push(Zeroizing::new(C::F::random(&mut *rng)));
27 }
28
29 fn polynomial<F: PrimeField + Zeroize>(
30 coefficients: &[Zeroizing<F>],
31 l: Participant,
32 ) -> Zeroizing<F> {
33 let l = F::from(u64::from(u16::from(l)));
34 assert!(l != F::ZERO, "zero participant passed to polynomial");
36 let mut share = Zeroizing::new(F::ZERO);
37 for (idx, coefficient) in coefficients.iter().rev().enumerate() {
38 *share += coefficient.deref();
39 if idx != (coefficients.len() - 1) {
40 *share *= l;
41 }
42 }
43 share
44 }
45
46 let group_key = C::generator() * coefficients[0].deref();
47 let mut secret_shares = HashMap::with_capacity(participants as usize);
48 let mut verification_shares = HashMap::with_capacity(participants as usize);
49 for i in 1 ..= participants {
50 let i = Participant::new(i).expect("non-zero u16 wasn't a valid Participant index");
51 let secret_share = polynomial(&coefficients, i);
52 secret_shares.insert(i, secret_share.clone());
53 verification_shares.insert(i, C::generator() * *secret_share);
54 }
55
56 let mut res = HashMap::with_capacity(participants as usize);
57 for (i, secret_share) in secret_shares {
58 let keys = ThresholdKeys::new(
59 ThresholdParams::new(threshold, participants, i)?,
60 Interpolation::Lagrange,
61 secret_share,
62 verification_shares.clone(),
63 )?;
64 debug_assert_eq!(keys.group_key(), group_key);
65 res.insert(i, keys);
66 }
67 Ok(res)
68}