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