Skip to main content

primitives/sharing/unauthenticated/
additive_shares.rs

1use std::ops::{Add, SubAssign};
2
3use serde::{de::DeserializeOwned, Serialize};
4
5use crate::{
6    errors::PrimitiveError,
7    random::{CryptoRngCore, Random},
8    sharing::Reconstructible,
9    types::PeerIndex,
10};
11
12/// A trait for additive secret sharing schemes.
13pub trait AdditiveShares:
14    Sized + Clone + Random + for<'a> Add<&'a Self, Output = Self> + for<'s> SubAssign<&'s Self>
15{
16    /// Split a secret into `n` additive shares.
17    fn to_additive_shares(&self, n_parties: usize, mut rng: impl CryptoRngCore) -> Vec<Self> {
18        let mut last_share = self.clone();
19        let mut shares = (0..n_parties - 1)
20            .map(|_| {
21                let share = Self::random(&mut rng);
22                last_share -= &share;
23                share
24            })
25            .collect::<Vec<_>>();
26        shares.push(last_share);
27        shares
28    }
29
30    /// Reconstruct a secret from `n` additive shares.
31    fn from_additive_shares<S: std::borrow::Borrow<Self>>(shares: &[S]) -> Self {
32        let mut shares_iter = shares.iter();
33        let first = shares_iter
34            .next()
35            .expect("At least one share is required for reconstruction.");
36        shares_iter.fold(first.borrow().clone(), |acc, share| acc + share.borrow())
37    }
38}
39
40impl<T: AdditiveShares + Serialize + DeserializeOwned + PartialEq + Send + Sync + 'static>
41    Reconstructible for T
42{
43    type Opening = T;
44    type Secret = T;
45
46    fn open_to(&self, _peer_index: PeerIndex) -> Result<Self::Opening, PrimitiveError> {
47        Ok(self.clone())
48    }
49
50    fn open_to_all_others(&self) -> impl ExactSizeIterator<Item = Self::Opening> {
51        if true {
52            unimplemented!("No info about number of parties to open to");
53        } else {
54            std::iter::empty()
55        }
56    }
57
58    fn reconstruct(&self, openings: &[Self::Opening]) -> Result<Self::Secret, PrimitiveError> {
59        Ok(openings
60            .iter()
61            .fold(self.clone(), |acc, opening| acc + opening))
62    }
63
64    fn reconstruct_all<S: std::borrow::Borrow<Self>>(
65        shares: &[S],
66    ) -> Result<Self::Secret, PrimitiveError> {
67        Ok(Self::from_additive_shares(shares))
68    }
69}