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    async fn run_dkg_g1(&self) -> anyhow::Result<(Vec<G1Projective>, Scalar)>;
48
49    async fn run_dkg_g2(&self) -> anyhow::Result<(Vec<G2Projective>, Scalar)>;
50
51    /// Exchanges a `DkgPeerMsg::Module(Vec<u8>)` with all peers. All peers are
52    /// required to be online and submit a response for this to return
53    /// properly. The caller's message will be included in the returned
54    /// `BTreeMap` under the `PeerId` of this peer. This allows modules to
55    /// exchange arbitrary data during distributed key generation.
56    async fn exchange_bytes(&self, data: Vec<u8>) -> anyhow::Result<BTreeMap<PeerId, Vec<u8>>>;
57}
58
59#[async_trait]
60pub trait PeerHandleOpsExt {
61    async fn exchange_encodable<T: Encodable + Decodable + Send + Sync>(
62        &self,
63        data: T,
64    ) -> anyhow::Result<BTreeMap<PeerId, T>>;
65}
66
67#[async_trait]
68impl<O> PeerHandleOpsExt for O
69where
70    O: PeerHandleOps + Send + Sync + ?Sized,
71{
72    async fn exchange_encodable<T: Encodable + Decodable + Send + Sync>(
73        &self,
74        data: T,
75    ) -> anyhow::Result<BTreeMap<PeerId, T>> {
76        let mut decoded = BTreeMap::new();
77        for (k, bytes) in self.exchange_bytes(data.consensus_encode_to_vec()).await? {
78            decoded.insert(
79                k,
80                T::consensus_decode_whole(&bytes, &ModuleDecoderRegistry::default())?,
81            );
82        }
83        Ok(decoded)
84    }
85}