1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2#![doc = include_str!("../README.md")]
3
4use core::fmt::Debug;
5use std::collections::HashMap;
6
7use thiserror::Error;
8
9pub use dkg::{self, Participant, ThresholdParams, ThresholdKeys, ThresholdView};
11
12pub mod curve;
14use curve::Curve;
15
16pub mod algorithm;
18mod nonce;
19pub mod sign;
21
22#[cfg(any(test, feature = "tests"))]
24pub mod tests;
25
26#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)]
28pub enum FrostError {
29 #[error("internal error: {0}")]
30 InternalError(&'static str),
31
32 #[error("invalid participant (0 < participant <= {0}, yet participant is {1})")]
33 InvalidParticipant(u16, Participant),
34 #[error("invalid signing set ({0})")]
35 InvalidSigningSet(&'static str),
36 #[error("invalid participant quantity (expected {0}, got {1})")]
37 InvalidParticipantQuantity(usize, usize),
38 #[error("duplicated participant ({0})")]
39 DuplicatedParticipant(Participant),
40 #[error("missing participant {0}")]
41 MissingParticipant(Participant),
42
43 #[error("invalid preprocess (participant {0})")]
44 InvalidPreprocess(Participant),
45 #[error("invalid share (participant {0})")]
46 InvalidShare(Participant),
47}
48
49pub fn validate_map<T>(
51 map: &HashMap<Participant, T>,
52 included: &[Participant],
53 ours: Participant,
54) -> Result<(), FrostError> {
55 if (map.len() + 1) != included.len() {
56 Err(FrostError::InvalidParticipantQuantity(included.len(), map.len() + 1))?;
57 }
58
59 for included in included {
60 if *included == ours {
61 if map.contains_key(included) {
62 Err(FrostError::DuplicatedParticipant(*included))?;
63 }
64 continue;
65 }
66
67 if !map.contains_key(included) {
68 Err(FrostError::MissingParticipant(*included))?;
69 }
70 }
71
72 Ok(())
73}