primitives/correlated_randomness/triples/
sharing.rs1use itertools::enumerate;
2
3use crate::{
4 algebra::field::FieldExtension,
5 correlated_randomness::triples::{
6 OpenTriple,
7 OpenTriples,
8 Triple,
9 Triples,
10 UnauthenticatedTriple,
11 UnauthenticatedTriples,
12 },
13 errors::PrimitiveError,
14 izip_eq,
15 sharing::{PairwiseAuthShare, Reconstructible, Verifiable, VerifiableWith},
16 types::{PeerIndex, Positive, TryFoldAll},
17};
18
19impl<F: FieldExtension, M: Positive> Reconstructible for Triples<F, M> {
24 type Opening = OpenTriples<F, M>;
25 type Value = UnauthenticatedTriples<F, M>;
26
27 fn open_to(&self, peer_index: PeerIndex) -> Result<OpenTriples<F, M>, PrimitiveError> {
28 Ok(OpenTriples {
29 a: self.a.open_to(peer_index)?,
30 b: self.b.open_to(peer_index)?,
31 c: self.c.open_to(peer_index)?,
32 })
33 }
34
35 fn open_to_all_others(&self) -> impl ExactSizeIterator<Item = OpenTriples<F, M>> {
36 (0..self.a.n_parties() - 1)
37 .map(|peer_index| self.open_to(peer_index).unwrap())
38 .collect::<Vec<_>>()
39 .into_iter()
40 }
41
42 fn reconstruct(&self, openings: Vec<OpenTriples<F, M>>) -> Result<Self::Value, PrimitiveError> {
43 enumerate(izip_eq!(
44 self.a.get_keys(),
45 self.b.get_keys(),
46 self.c.get_keys(),
47 openings
48 ))
49 .try_fold_all(
50 self.get_value(),
51 |mut acc: UnauthenticatedTriples<F, M>,
52 (peer_index, (a_key, b_key, c_key, opening))| {
53 acc.a += opening.a.get_value();
55 acc.b += opening.b.get_value();
56 acc.c += opening.c.get_value();
57 let a_ok = bool::from(PairwiseAuthShare::verify_mac(a_key, opening.a));
59 let b_ok = bool::from(PairwiseAuthShare::verify_mac(b_key, opening.b));
60 let c_ok = bool::from(PairwiseAuthShare::verify_mac(c_key, opening.c));
61 let error = if a_ok && b_ok && c_ok {
62 None
63 } else {
64 Some(PrimitiveError::WrongMAC(format!(
65 "triple MAC mismatch at peer {peer_index}"
66 )))
67 };
68 (acc, error)
69 },
70 )
71 }
72}
73
74impl<F: FieldExtension> Reconstructible for Triple<F> {
75 type Opening = OpenTriple<F>;
76 type Value = UnauthenticatedTriple<F>;
77
78 fn open_to(&self, peer_index: PeerIndex) -> Result<OpenTriple<F>, PrimitiveError> {
79 Ok(OpenTriple {
80 a: self.a.open_to(peer_index)?,
81 b: self.b.open_to(peer_index)?,
82 c: self.c.open_to(peer_index)?,
83 })
84 }
85
86 fn open_to_all_others(&self) -> impl ExactSizeIterator<Item = OpenTriple<F>> {
87 (0..self.a.n_parties() - 1)
88 .map(|peer_index| self.open_to(peer_index).unwrap())
89 .collect::<Vec<_>>()
90 .into_iter()
91 }
92
93 fn reconstruct(&self, openings: Vec<OpenTriple<F>>) -> Result<Self::Value, PrimitiveError> {
94 enumerate(izip_eq!(
95 self.a.get_keys(),
96 self.b.get_keys(),
97 self.c.get_keys(),
98 openings
99 ))
100 .try_fold_all(
101 self.get_value(),
102 |mut acc: UnauthenticatedTriple<F>, (peer_index, (a_key, b_key, c_key, opening))| {
103 acc.a += opening.a.get_value();
105 acc.b += opening.b.get_value();
106 acc.c += opening.c.get_value();
107 let a_ok = bool::from(PairwiseAuthShare::verify_mac(a_key, opening.a));
109 let b_ok = bool::from(PairwiseAuthShare::verify_mac(b_key, opening.b));
110 let c_ok = bool::from(PairwiseAuthShare::verify_mac(c_key, opening.c));
111 let error = if a_ok && b_ok && c_ok {
112 None
113 } else {
114 Some(PrimitiveError::WrongMAC(format!(
115 "triple MAC mismatch at peer {peer_index}"
116 )))
117 };
118 (acc, error)
119 },
120 )
121 }
122}
123
124impl<F: FieldExtension, M: Positive> VerifiableWith for Triples<F, M> {
129 type VerificationData = ();
130 fn verify_with(
131 &self,
132 openings: Vec<OpenTriples<F, M>>,
133 _verification_data: (),
134 ) -> Result<(), PrimitiveError> {
135 let UnauthenticatedTriples { a, b, c } = self.reconstruct(openings)?;
136 if a * &b != c {
137 return Err(PrimitiveError::WrongCorrelation(
138 "Reconstructed Triples do not satisfy a * b = c".to_string(),
139 ));
140 }
141 Ok(())
142 }
143
144 fn verify_from_peer_with(
145 &self,
146 opening: OpenTriples<F, M>,
147 peer_index: PeerIndex,
148 _verification_data: (),
149 ) -> Result<(), PrimitiveError> {
150 self.a.verify_from(opening.a, peer_index)?;
151 self.b.verify_from(opening.b, peer_index)?;
152 self.c.verify_from(opening.c, peer_index)?;
153 Ok(())
154 }
155}
156
157impl<F: FieldExtension> VerifiableWith for Triple<F> {
158 type VerificationData = ();
159 fn verify_with(
160 &self,
161 openings: Vec<OpenTriple<F>>,
162 _verification_data: (),
163 ) -> Result<(), PrimitiveError> {
164 let UnauthenticatedTriple { a, b, c } = self.reconstruct(openings)?;
165 if a * b != c {
166 return Err(PrimitiveError::WrongCorrelation(
167 "Reconstructed Triple does not satisfy a * b = c".to_string(),
168 ));
169 }
170 Ok(())
171 }
172
173 fn verify_from_peer_with(
174 &self,
175 opening: OpenTriple<F>,
176 peer_index: PeerIndex,
177 _verification_data: (),
178 ) -> Result<(), PrimitiveError> {
179 self.a.verify_from(opening.a, peer_index)?;
180 self.b.verify_from(opening.b, peer_index)?;
181 self.c.verify_from(opening.c, peer_index)?;
182 Ok(())
183 }
184}
185
186impl<F: FieldExtension> VerifiableWith for UnauthenticatedTriple<F> {
187 type VerificationData = ();
188 fn verify_with(
189 &self,
190 openings: Vec<UnauthenticatedTriple<F>>,
191 _verification_data: (),
192 ) -> Result<(), PrimitiveError> {
193 let reconstructed = self.reconstruct(openings)?;
194 if reconstructed.a * reconstructed.b != reconstructed.c {
195 return Err(PrimitiveError::WrongCorrelation(
196 "Reconstructed UnauthenticatedTriple does not satisfy a * b = c".to_string(),
197 ));
198 }
199 Ok(())
200 }
201
202 fn verify_all_with(shares: Vec<Self>, _verification_data: ()) -> Result<(), PrimitiveError> {
203 let reconstructed = Self::reconstruct_all(shares)?;
204 if reconstructed.a * reconstructed.b != reconstructed.c {
205 return Err(PrimitiveError::WrongCorrelation(
206 "Reconstructed UnauthenticatedTriple does not satisfy a * b = c".to_string(),
207 ));
208 }
209 Ok(())
210 }
211}
212
213impl<F: FieldExtension, M: Positive> VerifiableWith for UnauthenticatedTriples<F, M> {
214 type VerificationData = ();
215 fn verify_with(
216 &self,
217 openings: Vec<UnauthenticatedTriples<F, M>>,
218 _verification_data: (),
219 ) -> Result<(), PrimitiveError> {
220 let reconstructed = self.reconstruct(openings)?;
221 if reconstructed.a * &reconstructed.b != reconstructed.c {
222 return Err(PrimitiveError::WrongCorrelation(
223 "Reconstructed UnauthenticatedTriples does not satisfy a * b = c".to_string(),
224 ));
225 }
226 Ok(())
227 }
228
229 fn verify_all_with(shares: Vec<Self>, _verification_data: ()) -> Result<(), PrimitiveError> {
230 let reconstructed = Self::reconstruct_all(shares)?;
231 if reconstructed.a * &reconstructed.b != reconstructed.c {
232 return Err(PrimitiveError::WrongCorrelation(
233 "Reconstructed UnauthenticatedTriples does not satisfy a * b = c".to_string(),
234 ));
235 }
236 Ok(())
237 }
238}