Skip to main content

primitives/sharing/unauthenticated/
additive_shares.rs

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