Skip to main content

fedimint_server_core/
config.rs

1use std::collections::BTreeMap;
2
3use async_trait::async_trait;
4use bls12_381::{G1Affine, G1Projective, G2Affine, G2Projective, Scalar};
5use fedimint_core::encoding::{Decodable, Encodable};
6use fedimint_core::module::registry::ModuleDecoderRegistry;
7use fedimint_core::{NumPeers, PeerId};
8use group::Curve;
9
10pub fn g1(scalar: &Scalar) -> G1Projective {
11    G1Projective::generator() * scalar
12}
13
14pub fn g2(scalar: &Scalar) -> G2Projective {
15    G2Projective::generator() * scalar
16}
17
18// Offset by 1, since evaluating a poly at 0 reveals the secret
19pub fn scalar(peer: &PeerId) -> Scalar {
20    Scalar::from(peer.to_usize() as u64 + 1)
21}
22pub fn eval_poly_g1(coefficients: &[G1Projective], peer: &PeerId) -> G1Affine {
23    coefficients
24        .iter()
25        .copied()
26        .rev()
27        .reduce(|acc, coefficient| acc * scalar(peer) + coefficient)
28        .expect("We have at least one coefficient")
29        .to_affine()
30}
31
32pub fn eval_poly_g2(coefficients: &[G2Projective], peer: &PeerId) -> G2Affine {
33    coefficients
34        .iter()
35        .copied()
36        .rev()
37        .reduce(|acc, coefficient| acc * scalar(peer) + coefficient)
38        .expect("We have at least one coefficient")
39        .to_affine()
40}
41
42// TODO: this trait is only needed to break the `DkgHandle` impl
43// from it's definition that is still in `fedimint-core`
44#[async_trait]
45pub trait PeerHandleOps {
46    fn num_peers(&self) -> NumPeers;
47
48    async fn run_dkg_g1(&self) -> anyhow::Result<(Vec<G1Projective>, Scalar)>;
49
50    async fn run_dkg_g2(&self) -> anyhow::Result<(Vec<G2Projective>, Scalar)>;
51
52    /// Exchanges a `DkgPeerMsg::Module(Vec<u8>)` with all peers. All peers are
53    /// required to be online and submit a response for this to return
54    /// properly. The caller's message will be included in the returned
55    /// `BTreeMap` under the `PeerId` of this peer. This allows modules to
56    /// exchange arbitrary data during distributed key generation.
57    async fn exchange_bytes(&self, data: Vec<u8>) -> anyhow::Result<BTreeMap<PeerId, Vec<u8>>>;
58}
59
60#[async_trait]
61pub trait PeerHandleOpsExt {
62    async fn exchange_encodable<T: Encodable + Decodable + Send + Sync>(
63        &self,
64        data: T,
65    ) -> anyhow::Result<BTreeMap<PeerId, T>>;
66}
67
68#[async_trait]
69impl<O> PeerHandleOpsExt for O
70where
71    O: PeerHandleOps + Send + Sync + ?Sized,
72{
73    async fn exchange_encodable<T: Encodable + Decodable + Send + Sync>(
74        &self,
75        data: T,
76    ) -> anyhow::Result<BTreeMap<PeerId, T>> {
77        let mut decoded = BTreeMap::new();
78        for (k, bytes) in self.exchange_bytes(data.consensus_encode_to_vec()).await? {
79            decoded.insert(
80                k,
81                T::consensus_decode_whole(&bytes, &ModuleDecoderRegistry::default())?,
82            );
83        }
84        Ok(decoded)
85    }
86}