primitives/sharing/unauthenticated/
additive_shares.rs1use 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
12pub trait AdditiveShares:
14 Sized + Clone + Random + for<'a> Add<&'a Self, Output = Self> + for<'s> SubAssign<&'s Self>
15{
16 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 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}