dkg_core/primitives/
group.rs

1use super::{default_threshold, minimum_threshold, DKGError, DKGResult};
2use serde::{de::DeserializeOwned, Deserialize, Serialize};
3use threshold_bls::{group::Curve, poly::Idx};
4
5/// Node is a participant in the DKG protocol. In a DKG protocol, each
6/// participant must be identified both by an index and a public key. At the end
7/// of the protocol, if sucessful, the index is used to verify the validity of
8/// the share this node holds.
9#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
10pub struct Node<C: Curve>(Idx, C::Point, Option<String>);
11
12impl<C: Curve> Node<C> {
13    pub fn new(index: Idx, public: C::Point) -> Self {
14        Self(index, public, None)
15    }
16}
17
18impl<C: Curve> Node<C> {
19    /// Returns the node's index
20    pub fn id(&self) -> Idx {
21        self.0
22    }
23
24    /// Returns the node's public key
25    pub fn key(&self) -> &C::Point {
26        &self.1
27    }
28
29    pub fn set_rpc_endpoint(&mut self, rpc_endpoint: String) {
30        self.2 = Some(rpc_endpoint);
31    }
32
33    pub fn get_rpc_endpoint(&self) -> Option<&String> {
34        self.2.as_ref()
35    }
36}
37
38/// A Group is a collection of Nodes with an associated threshold. A DKG scheme
39/// takes in a group at the beginning of the protocol and outputs a potentially
40/// new group that contains members that succesfully ran the protocol. When
41/// creating a new group using the `from()` or `from_list()`method, the module
42/// sets the threshold to the output of `default_threshold()`.
43#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
44#[serde(bound = "C::Scalar: DeserializeOwned")]
45pub struct Group<C: Curve> {
46    /// The vector of nodes in the group
47    pub nodes: Vec<Node<C>>,
48    /// The minimum number of nodes required to participate in the DKG for this group
49    pub threshold: usize,
50}
51
52impl<C> Group<C>
53where
54    C: Curve,
55{
56    /// Converts a vector of nodes to a group with the default threshold (51%)
57    pub fn from_list(nodes: Vec<Node<C>>) -> Group<C> {
58        let l = nodes.len();
59        Self {
60            nodes,
61            threshold: default_threshold(l),
62        }
63    }
64
65    /// Creates a new group from the provided vector of nodes and threshold.
66    ///
67    /// Valid thresholds are `>= 51% * nodes.len()` and `<= 100% * nodes.len()`
68    pub fn new(nodes: Vec<Node<C>>, threshold: usize) -> DKGResult<Group<C>> {
69        let minimum = minimum_threshold(nodes.len());
70        let maximum = nodes.len();
71
72        // reject invalid thresholds
73        if threshold < minimum || threshold > maximum {
74            return Err(DKGError::InvalidThreshold(threshold, minimum, maximum));
75        }
76
77        Ok(Self { nodes, threshold })
78    }
79
80    /// Returns the number of nodes in the group
81    pub fn len(&self) -> usize {
82        self.nodes.len()
83    }
84
85    /// Checks if the group is empty
86    pub fn is_empty(&self) -> bool {
87        self.nodes.is_empty()
88    }
89
90    /// Gets the index of the node corresponding to the provided public key
91    pub fn index(&self, public: &C::Point) -> Option<Idx> {
92        self.nodes.iter().find(|n| &n.1 == public).map(|n| n.0)
93    }
94
95    pub fn contains_index(&self, idx: Idx) -> bool {
96        self.nodes.iter().any(|n| n.0 == idx)
97    }
98}
99
100impl<C> From<Vec<C::Point>> for Group<C>
101where
102    C: Curve,
103{
104    fn from(list: Vec<C::Point>) -> Self {
105        let thr = default_threshold(list.len());
106
107        let nodes = list
108            .into_iter()
109            .enumerate()
110            .map(|(i, public)| Node::new(i as Idx, public))
111            .collect();
112
113        Self::new(nodes, thr).expect("threshold should be good here")
114    }
115}