primitives/sharing/unauthenticated/
additive_shares.rs1use std::ops::{Add, SubAssign};
2
3use serde::{de::DeserializeOwned, Serialize};
4
5use crate::{
6 algebra::field::{FieldExtension, SubfieldElement},
7 errors::PrimitiveError,
8 random::{CryptoRngCore, Random},
9 sharing::{PlaintextOps, Reconstructible},
10 types::{Element, HeapArray, PeerIndex, Positive},
11};
12
13pub trait AdditiveShares:
15 Sized + Clone + Random + for<'a> Add<&'a Self, Output = Self> + for<'s> SubAssign<&'s Self>
16{
17 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 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<T: AdditiveShares + Serialize + DeserializeOwned + PartialEq + Send + Sync + 'static>
42 Reconstructible for T
43{
44 type Opening = T;
45 type Value = T;
46
47 fn open_to(&self, _peer_index: PeerIndex) -> Result<Self::Opening, PrimitiveError> {
48 Ok(self.to_owned())
49 }
50
51 fn open_to_all_others(&self) -> impl ExactSizeIterator<Item = Self::Opening> {
52 if true {
53 unimplemented!("No info about number of parties to open to");
54 } else {
55 std::iter::empty()
56 }
57 }
58
59 fn reconstruct(&self, openings: Vec<Self::Opening>) -> Result<Self::Value, PrimitiveError> {
60 Ok(openings
61 .iter()
62 .fold(self.to_owned(), |acc, opening| acc + opening))
63 }
64
65 fn reconstruct_all<S: std::borrow::Borrow<Self>>(
66 shares: Vec<S>,
67 ) -> Result<Self::Value, PrimitiveError> {
68 Ok(Self::from_additive_shares(&shares))
69 }
70}
71
72impl<
73 T: Element
74 + Clone
75 + Random
76 + for<'b> derive_more::SubAssign<&'b T>
77 + for<'b> derive_more::Add<&'b T, Output = T>,
78 M: Positive,
79 > AdditiveShares for HeapArray<T, M>
80{
81}
82
83impl<F: FieldExtension> PlaintextOps<SubfieldElement<F>> for SubfieldElement<F> {
87 #[inline]
88 fn add_plaintext(self, ptx: &Self, is_first_peer: bool) -> Self {
89 if is_first_peer {
90 self + ptx
91 } else {
92 self
93 }
94 }
95
96 #[inline]
97 fn sub_plaintext(self, ptx: &Self, is_first_peer: bool) -> Self {
98 if is_first_peer {
99 self - ptx
100 } else {
101 self
102 }
103 }
104}