1use std::{
2 fmt::Debug,
3 iter::Sum as IterSum,
4 ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
5};
6
7use itertools::{enumerate, izip, Itertools};
8use rayon::prelude::IntoParallelIterator;
9use serde::{Deserialize, Serialize};
10use subtle::{Choice, ConstantTimeEq};
11use typenum::{PartialDiv, Prod, Sum, U1, U2, U3};
12
13use super::FieldShareKeys;
14use crate::{
15 algebra::{
16 field::{FieldExtension, SubfieldElement},
17 ops::transpose::transpose,
18 },
19 errors::{
20 PrimitiveError::{self},
21 VerificationError::MissingKey,
22 },
23 izip_eq,
24 random::{CryptoRngCore, Random, RandomWith},
25 sharing::{
26 authenticated::NParties,
27 unauthenticated::AdditiveShares,
28 FieldShare,
29 FieldShareKey,
30 GlobalFieldKey,
31 Reconstructible,
32 VerifiableWith,
33 VerificationError::MissingOpening,
34 },
35 types::{
36 heap_array::{FieldElements, SubfieldElements},
37 identifiers::PeerIndex,
38 ConditionallySelectable,
39 HeapArray,
40 Positive,
41 },
42 utils::IntoExactSizeIterator,
43};
44
45#[derive(Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
46#[serde(bound = "F: FieldExtension, M: Positive")]
47pub struct OpenFieldShares<F: FieldExtension, M: Positive> {
48 pub(crate) value: SubfieldElements<F, M>,
49 pub(crate) mac: FieldElements<F, M>,
50}
51
52impl<F: FieldExtension, M: Positive> OpenFieldShares<F, M> {
53 pub fn new(value: SubfieldElements<F, M>, mac: FieldElements<F, M>) -> Self {
54 Self { value, mac }
55 }
56
57 pub fn get_value(&self) -> &SubfieldElements<F, M> {
58 &self.value
59 }
60
61 pub fn get_mac(&self) -> &FieldElements<F, M> {
62 &self.mac
63 }
64}
65
66impl<T: FieldExtension, M: Positive> Debug for OpenFieldShares<T, M> {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 f.debug_struct(format!("OpenFieldShares<{}>", M::USIZE).as_str())
69 .field("value", &self.value)
70 .field("mac", &self.mac)
71 .finish()
72 }
73}
74
75#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
89#[serde(bound = "F: FieldExtension, M: Positive")]
90pub struct FieldShares<F, M>
91where
92 F: FieldExtension,
93 M: Positive, {
95 pub(crate) value: SubfieldElements<F, M>,
97 pub(crate) macs: Box<[FieldElements<F, M>]>,
99 pub(crate) keys: Box<[FieldShareKeys<F, M>]>,
101}
102
103impl<F: FieldExtension, M: Positive> FieldShares<F, M> {
104 pub fn try_new(
105 value: SubfieldElements<F, M>,
106 macs: Box<[FieldElements<F, M>]>,
107 keys: Box<[FieldShareKeys<F, M>]>,
108 ) -> Result<Self, PrimitiveError> {
109 if macs.is_empty() {
110 return Err(PrimitiveError::InvalidParameters(
111 "n_parties < 2".to_string(),
112 ));
113 }
114 if macs.len() != keys.len() {
115 return Err(PrimitiveError::SizeError(macs.len(), keys.len()));
116 }
117 Ok(Self { value, macs, keys })
119 }
120
121 fn new(
122 value: SubfieldElements<F, M>,
123 macs: Box<[FieldElements<F, M>]>,
124 keys: Box<[FieldShareKeys<F, M>]>,
125 ) -> Self {
126 Self { value, macs, keys }
127 }
128
129 pub fn get_value(&self) -> &SubfieldElements<F, M> {
130 &self.value
131 }
132
133 pub fn get_value_mut(&mut self) -> &mut SubfieldElements<F, M> {
134 &mut self.value
135 }
136
137 #[inline]
138 pub fn value(self) -> SubfieldElements<F, M> {
139 self.value
140 }
141
142 pub fn get_keys(&self) -> &[FieldShareKeys<F, M>] {
143 &self.keys
144 }
145
146 pub fn get_keys_mut(&mut self) -> &mut [FieldShareKeys<F, M>] {
147 &mut self.keys
148 }
149
150 pub fn get_key(&self, peer: PeerIndex) -> Option<&FieldShareKeys<F, M>> {
151 self.keys.get(peer)
152 }
153
154 pub fn get_macs(&self) -> &[FieldElements<F, M>] {
155 &self.macs
156 }
157
158 pub fn get_mac(&self, index: PeerIndex) -> Option<&FieldElements<F, M>> {
159 self.macs.get(index)
160 }
161
162 pub fn get_alphas(&self) -> impl ExactSizeIterator<Item = GlobalFieldKey<F>> + '_ {
163 self.keys.iter().map(|key| key.get_alpha())
164 }
165
166 pub fn n_parties(&self) -> usize {
167 self.get_macs().len() + 1 }
169
170 pub fn iter(&self) -> FieldSharesIterator<F, M> {
171 self.into_iter()
172 }
173
174 pub fn len(&self) -> usize {
175 self.value.len()
176 }
177
178 pub fn is_empty(&self) -> bool {
179 self.len() == 0
180 }
181}
182
183impl<F: FieldExtension, M: Positive> VerifiableWith for FieldShares<F, M> {
187 type VerificationData = ();
188 #[inline]
190 fn verify_from_peer_with(
191 &self,
192 open_share: &OpenFieldShares<F, M>,
193 from_peer: PeerIndex,
194 _verification_data: (),
195 ) -> Result<(), PrimitiveError> {
196 self.get_key(from_peer)
197 .ok_or(MissingKey(from_peer))?
198 .verify_mac(open_share)
199 .map_err(|e| e.blame(from_peer).add_state(self))
200 }
201
202 #[inline]
204 fn verify_with(
205 &self,
206 open_shares: &[OpenFieldShares<F, M>],
207 _verification_data: (),
208 ) -> Result<(), PrimitiveError> {
209 izip_eq!(open_shares, &self.keys).enumerate().try_for_each(
210 |(from_peer, (open_share, key))| {
211 key.verify_mac(open_share)
212 .map_err(|e| e.blame(from_peer).add_state(self))
213 },
214 )
215 }
216}
217
218impl<F: FieldExtension, M: Positive> Reconstructible for FieldShares<F, M> {
223 type Opening = OpenFieldShares<F, M>;
224 type Secret = SubfieldElements<F, M>;
225
226 fn open_to(&self, for_peer: PeerIndex) -> Result<OpenFieldShares<F, M>, PrimitiveError> {
228 let mac = self
229 .get_mac(for_peer)
230 .ok_or(MissingOpening(for_peer))?
231 .to_owned();
232 Ok(OpenFieldShares::new(self.get_value().to_owned(), mac))
233 }
234
235 fn open_to_all_others(&self) -> impl ExactSizeIterator<Item = OpenFieldShares<F, M>> {
237 self.get_macs()
238 .iter()
239 .map(|mac| OpenFieldShares::new(self.get_value().to_owned(), mac.to_owned()))
240 }
241
242 fn reconstruct(
244 &self,
245 openings: &[OpenFieldShares<F, M>],
246 ) -> Result<Self::Secret, PrimitiveError> {
247 if openings.len() != self.get_keys().len() {
248 return Err(PrimitiveError::SizeError(
249 openings.len(),
250 self.get_keys().len(),
251 ));
252 }
253
254 izip_eq!(openings, self.get_keys()).enumerate().try_fold(
255 self.get_value().to_owned(),
256 |acc, (i, (open_share, key))| {
257 key.verify_mac(open_share)
258 .map_err(|e| e.blame(i).add_state(self))?;
259 Ok(acc + open_share.get_value())
260 },
261 )
262 }
263}
264
265fn compute_macs<F: FieldExtension, M: Positive>(
270 all_unauth_shares: &[SubfieldElements<F, M>],
271 all_keys: &[Box<[FieldShareKeys<F, M>]>],
272) -> Vec<Box<[FieldElements<F, M>]>> {
273 let mut all_key_iters = all_keys.iter().map(|k| k.iter()).collect::<Vec<_>>();
274 enumerate(all_unauth_shares.iter())
275 .map(|(i, my_unauth_share)| {
276 enumerate(all_key_iters.iter_mut())
277 .filter(|(j, _)| *j != i)
278 .map(|(_, keys_iter)| keys_iter.next().unwrap().compute_mac(my_unauth_share))
279 .collect()
280 })
281 .collect()
282}
283
284impl<F: FieldExtension, M: Positive> Random for FieldShares<F, M> {
285 fn random(_rng: impl CryptoRngCore) -> Self {
286 unimplemented!(
287 "Type {} does not support `random` since it needs to know `n_parties`. Use `random_with(..., n_parties)` instead.",
288 std::any::type_name::<Self>()
289 )
290 }
291
292 fn random_n<Container: FromIterator<Self>>(
294 mut rng: impl CryptoRngCore,
295 n_parties: NParties,
296 ) -> Container {
297 let all_unauth_shares: Vec<_> = SubfieldElements::random_n(&mut rng, n_parties);
298 let all_keys = (0..n_parties)
299 .map(|_| FieldShareKeys::<F, M>::random_n(&mut rng, n_parties - 1))
300 .collect::<Vec<_>>();
301 let all_macs = compute_macs(&all_unauth_shares, &all_keys);
302 izip_eq!(all_unauth_shares, all_macs, all_keys)
303 .map(|(value, macs, keys)| FieldShares::new(value, macs, keys))
304 .collect()
305 }
306}
307
308impl<F: FieldExtension, M: Positive> RandomWith<NParties> for FieldShares<F, M> {
309 fn random_with(mut rng: impl CryptoRngCore, n_parties: NParties) -> Self {
311 FieldShares::new(
312 SubfieldElements::<F, M>::random(&mut rng),
313 FieldElements::<F, M>::random_n(&mut rng, n_parties - 1),
314 FieldShareKeys::<F, M>::random_n(&mut rng, n_parties - 1),
315 )
316 }
317}
318
319impl<F: FieldExtension, M: Positive> RandomWith<(NParties, SubfieldElements<F, M>)>
320 for FieldShares<F, M>
321{
322 fn random_with(
324 mut rng: impl CryptoRngCore,
325 n_parties_value: (NParties, SubfieldElements<F, M>),
326 ) -> Self {
327 let (n_parties, value) = n_parties_value;
328 FieldShares::new(
329 value,
330 FieldElements::<F, M>::random_n(&mut rng, n_parties - 1),
331 FieldShareKeys::<F, M>::random_n(&mut rng, n_parties - 1),
332 )
333 }
334}
335
336impl<F: FieldExtension, M: Positive> RandomWith<SubfieldElements<F, M>> for FieldShares<F, M> {
337 fn random_with(_rng: impl CryptoRngCore, _data: SubfieldElements<F, M>) -> Self {
338 unimplemented!(
339 "Type {} does not support `random_with` since it needs to know `n_parties`. Use `random_n_with` instead.",
340 std::any::type_name::<Self>()
341 )
342 }
343
344 fn random_n_with<Container: FromIterator<Self>>(
347 mut rng: impl CryptoRngCore,
348 n_parties: usize,
349 value: SubfieldElements<F, M>,
350 ) -> Container {
351 let all_unauth_shares = value.to_additive_shares(n_parties, &mut rng);
352 let all_keys = (0..n_parties)
353 .map(|_| FieldShareKeys::<F, M>::random_n(&mut rng, n_parties - 1))
354 .collect::<Vec<_>>();
355 let all_macs = compute_macs(&all_unauth_shares, &all_keys);
356 izip_eq!(all_unauth_shares, all_macs, all_keys)
357 .map(|(value, macs, keys)| FieldShares::new(value, macs, keys))
358 .collect()
359 }
360
361 fn random_n_with_each<Container: FromIterator<Self>>(
364 mut rng: impl CryptoRngCore,
365 unauth_shares: impl IntoExactSizeIterator<Item = SubfieldElements<F, M>>,
366 ) -> Container {
367 let all_unauth_shares = unauth_shares.into_iter().collect::<Vec<_>>();
368 let n_parties = all_unauth_shares.len();
369 let all_keys = (0..n_parties)
370 .map(|_| FieldShareKeys::<F, M>::random_n(&mut rng, n_parties - 1))
371 .collect::<Vec<_>>();
372 let all_macs = compute_macs(&all_unauth_shares, &all_keys);
373 izip_eq!(all_unauth_shares, all_macs, all_keys)
374 .map(|(value, macs, keys)| FieldShares::new(value, macs, keys))
375 .collect()
376 }
377}
378
379impl<F: FieldExtension, M: Positive> RandomWith<Vec<GlobalFieldKey<F>>> for FieldShares<F, M> {
380 fn random_with(mut rng: impl CryptoRngCore, alphas: Vec<GlobalFieldKey<F>>) -> Self {
382 let n_other_parties = alphas.len();
383 FieldShares::new(
384 SubfieldElements::random(&mut rng),
385 FieldElements::<F, M>::random_n(&mut rng, n_other_parties),
386 FieldShareKeys::<F, M>::random_n_with_each(&mut rng, alphas),
387 )
388 }
389
390 fn random_n_with_each<Container: FromIterator<Self>>(
392 mut rng: impl CryptoRngCore,
393 all_alphas: impl IntoExactSizeIterator<Item = Vec<GlobalFieldKey<F>>>,
394 ) -> Container {
395 let all_alphas = all_alphas.into_iter();
396 let all_unauth_shares: Vec<_> = SubfieldElements::random_n(&mut rng, all_alphas.len());
397 let all_keys = all_alphas
398 .into_iter()
399 .map(|my_alphas| FieldShareKeys::<F, M>::random_n_with_each(&mut rng, my_alphas))
400 .collect::<Vec<_>>();
401 let all_macs = compute_macs(&all_unauth_shares, &all_keys);
402 izip_eq!(all_unauth_shares, all_macs, all_keys)
403 .map(|(value, macs, keys)| FieldShares::new(value, macs, keys))
404 .collect()
405 }
406}
407
408impl<F: FieldExtension, M: Positive> RandomWith<(SubfieldElements<F, M>, Vec<GlobalFieldKey<F>>)>
409 for FieldShares<F, M>
410{
411 fn random_with(
413 mut rng: impl CryptoRngCore,
414 value_alphas: (SubfieldElements<F, M>, Vec<GlobalFieldKey<F>>),
415 ) -> Self {
416 let (value, alphas) = value_alphas;
417 let n_other_parties = alphas.len();
418 FieldShares::new(
419 value,
420 FieldElements::<F, M>::random_n(&mut rng, n_other_parties),
421 FieldShareKeys::<F, M>::random_n_with_each(&mut rng, alphas),
422 )
423 }
424
425 fn random_n_with_each<Container: FromIterator<Self>>(
427 mut rng: impl CryptoRngCore,
428 unauth_shares_and_alphas: impl IntoIterator<
429 Item = (SubfieldElements<F, M>, Vec<GlobalFieldKey<F>>),
430 >,
431 ) -> Container {
432 let (all_unauth_shares, all_keys): (Vec<_>, Vec<_>) = unauth_shares_and_alphas
433 .into_iter()
434 .map(|(value, my_alphas)| {
435 (
436 value,
437 FieldShareKeys::<F, M>::random_n_with_each(&mut rng, my_alphas),
438 )
439 })
440 .unzip();
441 let all_macs = compute_macs(&all_unauth_shares, &all_keys);
442 izip_eq!(all_unauth_shares, all_macs, all_keys)
443 .map(|(value, macs, keys)| FieldShares::new(value, macs, keys))
444 .collect()
445 }
446}
447
448impl<F: FieldExtension, M: Positive>
449 RandomWith<(SubfieldElements<F, M>, Vec<Vec<GlobalFieldKey<F>>>)> for FieldShares<F, M>
450{
451 fn random_with(
452 _rng: impl CryptoRngCore,
453 _data: (SubfieldElements<F, M>, Vec<Vec<GlobalFieldKey<F>>>),
454 ) -> Self {
455 unimplemented!(
456 "Cannot discern what alpha/global key to use for this peer. Use `random_n_with` instead."
457 );
458 }
459
460 fn random_n_with<Container: FromIterator<Self>>(
463 mut rng: impl CryptoRngCore,
464 n_parties: usize,
465 secret_value_and_alphas: (SubfieldElements<F, M>, Vec<Vec<GlobalFieldKey<F>>>),
466 ) -> Container {
467 let (secret_value, all_alphas) = secret_value_and_alphas;
468 assert_eq!(
469 all_alphas.len(),
470 n_parties,
471 "Number of alphas must match the number of parties"
472 );
473 let all_unauth_shares = secret_value.to_additive_shares(all_alphas.len(), &mut rng);
474 let all_keys = all_alphas
475 .into_iter()
476 .map(|my_alphas| FieldShareKeys::<F, M>::random_n_with_each(&mut rng, my_alphas))
477 .collect::<Vec<_>>();
478 let all_macs = compute_macs(&all_unauth_shares, &all_keys);
479 izip_eq!(all_unauth_shares, all_macs, all_keys)
480 .map(|(value, macs, keys)| FieldShares::new(value, macs, keys))
481 .collect()
482 }
483}
484
485impl<F: FieldExtension, M: Positive> Add for FieldShares<F, M> {
492 type Output = FieldShares<F, M>;
493
494 #[inline]
495 fn add(mut self, other: FieldShares<F, M>) -> Self::Output {
496 self.value += other.value;
497 izip_eq!(&mut self.macs, &other.macs).for_each(|(mac_i, mac_j)| *mac_i += mac_j);
498 izip_eq!(&mut self.keys, &other.keys).for_each(|(key_i, key_j)| *key_i += key_j);
499 self
500 }
501}
502
503impl<F: FieldExtension, M: Positive> Add<FieldShares<F, M>> for &FieldShares<F, M> {
504 type Output = FieldShares<F, M>;
505
506 #[inline]
507 fn add(self, mut other: FieldShares<F, M>) -> Self::Output {
508 other.value += &self.value;
509 izip_eq!(&mut other.macs, &self.macs).for_each(|(mac_i, mac_j)| *mac_i += mac_j);
510 izip_eq!(&mut other.keys, &self.keys).for_each(|(key_i, key_j)| *key_i += key_j);
511 other
512 }
513}
514
515impl<'a, F: FieldExtension, M: Positive> Add<&'a FieldShares<F, M>> for FieldShares<F, M> {
516 type Output = FieldShares<F, M>;
517
518 #[inline]
519 fn add(mut self, other: &'a FieldShares<F, M>) -> Self::Output {
520 self.value += &other.value;
521 izip_eq!(&mut self.macs, &other.macs).for_each(|(mac_i, mac_j)| *mac_i += mac_j);
522 izip_eq!(&mut self.keys, &other.keys).for_each(|(key_i, key_j)| *key_i += key_j);
523 self
524 }
525}
526
527impl<'a, F: FieldExtension, M: Positive> Add<&'a FieldShares<F, M>> for &FieldShares<F, M> {
528 type Output = FieldShares<F, M>;
529
530 #[inline]
531 fn add(self, other: &'a FieldShares<F, M>) -> Self::Output {
532 let mut res = self.clone();
533 res.value += &other.value;
534 izip_eq!(&mut res.macs, &other.macs).for_each(|(mac_i, mac_j)| *mac_i += mac_j);
535 izip_eq!(&mut res.keys, &other.keys).for_each(|(key_i, key_j)| *key_i += key_j);
536 res
537 }
538}
539
540impl<F: FieldExtension, M: Positive> AddAssign for FieldShares<F, M> {
543 #[inline]
544 fn add_assign(&mut self, other: Self) {
545 self.value += other.value;
546 izip_eq!(&mut self.macs, &other.macs).for_each(|(mac_i, mac_j)| *mac_i += mac_j);
547 izip_eq!(&mut self.keys, &other.keys).for_each(|(key_i, key_j)| *key_i += key_j);
548 }
549}
550
551impl<'a, F: FieldExtension, M: Positive> AddAssign<&'a FieldShares<F, M>> for FieldShares<F, M> {
552 #[inline]
553 fn add_assign(&mut self, other: &'a FieldShares<F, M>) {
554 self.value += &other.value;
555 izip_eq!(&mut self.macs, &other.macs).for_each(|(mac_i, mac_j)| *mac_i += mac_j);
556 izip_eq!(&mut self.keys, &other.keys).for_each(|(key_i, key_j)| *key_i += key_j);
557 }
558}
559
560impl<F: FieldExtension, M: Positive> Sub for FieldShares<F, M> {
563 type Output = FieldShares<F, M>;
564
565 #[inline]
566 fn sub(mut self, other: FieldShares<F, M>) -> Self::Output {
567 self.value -= other.value;
568 izip_eq!(&mut self.macs, &other.macs).for_each(|(mac_i, mac_j)| *mac_i -= mac_j);
569 izip_eq!(&mut self.keys, &other.keys).for_each(|(key_i, key_j)| *key_i -= key_j);
570 self
571 }
572}
573
574impl<'a, F: FieldExtension, M: Positive> Sub<&'a FieldShares<F, M>> for FieldShares<F, M> {
575 type Output = FieldShares<F, M>;
576
577 #[inline]
578 fn sub(mut self, other: &'a FieldShares<F, M>) -> Self::Output {
579 self.value -= &other.value;
580 izip_eq!(&mut self.macs, &other.macs).for_each(|(mac_i, mac_j)| *mac_i -= mac_j);
581 izip_eq!(&mut self.keys, &other.keys).for_each(|(key_i, key_j)| *key_i -= key_j);
582 self
583 }
584}
585
586impl<'a, F: FieldExtension, M: Positive> Sub<&'a FieldShares<F, M>> for &FieldShares<F, M> {
587 type Output = FieldShares<F, M>;
588
589 #[inline]
590 fn sub(self, other: &'a FieldShares<F, M>) -> Self::Output {
591 FieldShares {
592 value: &self.value - &other.value,
593 macs: izip_eq!(&self.macs, &other.macs)
594 .map(|(mac_i, mac_j)| mac_i - mac_j)
595 .collect(),
596 keys: izip_eq!(&self.keys, &other.keys)
597 .map(|(key_i, key_j)| key_i - key_j)
598 .collect(),
599 }
600 }
601}
602
603impl<F: FieldExtension, M: Positive> Sub<FieldShares<F, M>> for &FieldShares<F, M> {
604 type Output = FieldShares<F, M>;
605
606 #[inline]
607 fn sub(self, other: FieldShares<F, M>) -> Self::Output {
608 FieldShares {
609 value: &self.value - &other.value,
610 macs: izip_eq!(&self.macs, &other.macs)
611 .map(|(mac_i, mac_j)| mac_i - mac_j)
612 .collect(),
613 keys: izip_eq!(&self.keys, &other.keys)
614 .map(|(key_i, key_j)| key_i - key_j)
615 .collect(),
616 }
617 }
618}
619
620impl<F: FieldExtension, M: Positive> SubAssign for FieldShares<F, M> {
623 #[inline]
624 fn sub_assign(&mut self, other: Self) {
625 self.value -= other.value;
626 izip_eq!(&mut self.macs, &other.macs).for_each(|(mac_i, mac_j)| *mac_i -= mac_j);
627 izip_eq!(&mut self.keys, &other.keys).for_each(|(key_i, key_j)| *key_i -= key_j);
628 }
629}
630
631impl<'a, F: FieldExtension, M: Positive> SubAssign<&'a FieldShares<F, M>> for FieldShares<F, M> {
632 #[inline]
633 fn sub_assign(&mut self, other: &'a FieldShares<F, M>) {
634 self.value -= &other.value;
635 izip_eq!(&mut self.macs, &other.macs).for_each(|(mac_i, mac_j)| *mac_i -= mac_j);
636 izip_eq!(&mut self.keys, &other.keys).for_each(|(key_i, key_j)| *key_i -= key_j);
637 }
638}
639
640impl<F: FieldExtension, M: Positive> Mul<SubfieldElement<F>> for FieldShares<F, M> {
643 type Output = FieldShares<F, M>;
644
645 #[inline]
646 fn mul(mut self, other: SubfieldElement<F>) -> FieldShares<F, M> {
647 self.value *= other;
648 izip_eq!(&mut self.macs).for_each(|mac_i| *mac_i *= other);
649 izip_eq!(&mut self.keys).for_each(|key_i| *key_i *= other);
650 self
651 }
652}
653
654impl<'a, F: FieldExtension, M: Positive> Mul<&'a SubfieldElement<F>> for FieldShares<F, M> {
655 type Output = FieldShares<F, M>;
656
657 #[inline]
658 fn mul(mut self, other: &'a SubfieldElement<F>) -> FieldShares<F, M> {
659 self.value *= other;
660 izip_eq!(&mut self.macs).for_each(|mac_i| *mac_i *= other);
661 izip_eq!(&mut self.keys).for_each(|key_i| *key_i *= other);
662 self
663 }
664}
665
666impl<'a, F: FieldExtension, M: Positive> Mul<&'a SubfieldElements<F, M>> for FieldShares<F, M> {
667 type Output = FieldShares<F, M>;
668
669 #[inline]
670 fn mul(mut self, other: &'a SubfieldElements<F, M>) -> FieldShares<F, M> {
671 self.value *= other;
672 izip_eq!(&mut self.macs).for_each(|mac_i| *mac_i *= other);
673 izip_eq!(&mut self.keys).for_each(|key_i| *key_i *= other);
674 self
675 }
676}
677
678impl<'a, F: FieldExtension, M: Positive> Mul<&'a SubfieldElements<F, M>> for &FieldShares<F, M> {
679 type Output = FieldShares<F, M>;
680
681 #[inline]
682 fn mul(self, other: &'a SubfieldElements<F, M>) -> FieldShares<F, M> {
683 self.clone() * other
684 }
685}
686
687impl<F: FieldExtension, M: Positive> Mul<SubfieldElements<F, M>> for &FieldShares<F, M> {
688 type Output = FieldShares<F, M>;
689
690 #[inline]
691 fn mul(self, other: SubfieldElements<F, M>) -> FieldShares<F, M> {
692 self.clone() * &other
693 }
694}
695
696impl<'a, F: FieldExtension, M: Positive> MulAssign<&'a SubfieldElement<F>> for FieldShares<F, M> {
699 #[inline]
700 fn mul_assign(&mut self, other: &'a SubfieldElement<F>) {
701 self.value *= other;
702 izip_eq!(&mut self.macs).for_each(|mac_i| *mac_i *= other);
703 izip_eq!(&mut self.keys).for_each(|key_i| *key_i *= other);
704 }
705}
706
707impl<'a, F: FieldExtension, M: Positive> MulAssign<&'a SubfieldElements<F, M>>
708 for FieldShares<F, M>
709{
710 #[inline]
711 fn mul_assign(&mut self, other: &'a SubfieldElements<F, M>) {
712 self.value *= other;
713 izip_eq!(&mut self.macs).for_each(|mac_i| *mac_i *= other);
714 izip_eq!(&mut self.keys).for_each(|key_i| *key_i *= other);
715 }
716}
717
718impl<F: FieldExtension, M: Positive> Neg for FieldShares<F, M> {
721 type Output = Self;
722
723 #[inline]
724 fn neg(self) -> Self::Output {
725 FieldShares {
726 value: -self.value,
727 macs: izip_eq!(&self.macs).map(|mac_i| -mac_i).collect(),
728 keys: izip_eq!(&self.keys).map(|key_i| -key_i).collect(),
729 }
730 }
731}
732
733impl<F: FieldExtension, M: Positive> Neg for &FieldShares<F, M> {
734 type Output = FieldShares<F, M>;
735
736 #[inline]
737 fn neg(self) -> Self::Output {
738 FieldShares {
739 value: -&self.value,
740 macs: izip_eq!(&self.macs).map(|mac_i| -mac_i).collect(),
741 keys: izip_eq!(&self.keys).map(|key_i| -key_i).collect(),
742 }
743 }
744}
745
746impl<F: FieldExtension, M: Positive> IterSum for FieldShares<F, M> {
749 fn sum<I: Iterator<Item = Self>>(mut iter: I) -> Self {
750 let first = iter.next().unwrap_or_default();
751 iter.fold(first, |acc, x| acc + x)
752 }
753}
754
755impl<F: FieldExtension, M: Positive> FieldShares<F, M> {
758 #[inline]
761 pub fn add_secret_owned(
762 mut self,
763 constant: &SubfieldElements<F, M>,
764 is_peer_zero: bool,
765 ) -> Self {
766 if is_peer_zero {
767 self.value += constant;
768 } else {
769 let key0 = self.keys.get_mut(0).expect("Missing key 0");
770 key0.betas -= constant.clone() * *key0.alpha;
771 }
772 self
773 }
774
775 #[inline]
778 pub fn add_secret(&self, constant: &SubfieldElements<F, M>, is_peer_zero: bool) -> Self {
779 let result = self.clone();
780 result.add_secret_owned(constant, is_peer_zero)
781 }
782
783 #[inline]
787 pub fn sub_constant_array_owned(
788 mut self,
789 arr: &SubfieldElements<F, M>,
790 is_peer_zero: bool,
791 ) -> Self {
792 if is_peer_zero {
793 self.value -= arr;
794 } else {
795 let key0 = self.keys.get_mut(0).expect("Missing key 0");
796 let alpha = *key0.alpha;
797 izip_eq!(&mut key0.betas, arr).for_each(|(beta, val)| *beta += alpha * val);
798 }
799 self
800 }
801}
802
803impl<F: FieldExtension, M: Positive> ConditionallySelectable for FieldShares<F, M> {
806 #[inline]
807 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
808 FieldShares {
809 value: HeapArray::conditional_select(&a.value, &b.value, choice),
810 macs: izip_eq!(&a.macs, &b.macs)
811 .map(|(a_mac, b_mac)| HeapArray::conditional_select(a_mac, b_mac, choice))
812 .collect::<Vec<_>>()
813 .into(),
814 keys: izip_eq!(&a.keys, &b.keys)
815 .map(|(a_key, b_key)| FieldShareKeys::conditional_select(a_key, b_key, choice))
816 .collect::<Vec<_>>()
817 .into(),
818 }
819 }
820}
821
822impl<F: FieldExtension, M: Positive> ConstantTimeEq for FieldShares<F, M> {
823 #[inline]
824 fn ct_eq(&self, other: &Self) -> Choice {
825 self.value.ct_eq(&other.value) & self.keys.ct_eq(&other.keys) & self.macs.ct_eq(&other.macs)
826 }
827}
828
829impl<F: FieldExtension, M: Positive> FieldShares<F, M> {
832 pub fn dot_product(&self, other: &SubfieldElements<F, M>) -> FieldShare<F> {
834 FieldShare {
835 value: izip_eq!(&self.value, other)
836 .map(|(value_i, other_i)| *value_i * other_i)
837 .sum(),
838 macs: izip_eq!(&self.macs)
839 .map(|mac_i| {
840 izip_eq!(mac_i, other)
841 .map(|(mac_ij, other_i)| *mac_ij * other_i)
842 .sum()
843 })
844 .collect(),
845 keys: izip_eq!(&self.keys)
846 .map(|key_i| {
847 let beta = izip_eq!(&key_i.betas, other)
848 .map(|(key_ij, other_i)| key_ij * other_i)
849 .sum();
850 FieldShareKey {
851 alpha: key_i.alpha.clone(),
852 beta,
853 }
854 })
855 .collect(),
856 }
857 }
858}
859
860impl<F: FieldExtension, M: Positive> FieldShares<F, M> {
865 pub fn split<M1, M2>(self) -> (FieldShares<F, M1>, FieldShares<F, M2>)
867 where
868 M1: Positive,
869 M2: Positive + Add<M1, Output = M>,
870 {
871 let FieldShares { value, macs, keys } = self;
872
873 let (value1, value2) = value.split::<M1, M2>();
874 let (macs1, macs2): (Vec<_>, Vec<_>) = macs
875 .into_vec()
876 .into_iter()
877 .map(|mac| mac.split::<M1, M2>())
878 .collect();
879
880 let (keys1, keys2): (Vec<_>, Vec<_>) = keys
881 .into_vec()
882 .into_iter()
883 .map(|key| key.split::<M1, M2>())
884 .collect();
885
886 (
887 FieldShares::try_new(value1, macs1.into(), keys1.into()).unwrap(),
888 FieldShares::try_new(value2, macs2.into(), keys2.into()).unwrap(),
889 )
890 }
891
892 pub fn split_halves<MDiv2>(self) -> (FieldShares<F, MDiv2>, FieldShares<F, MDiv2>)
894 where
895 MDiv2: Positive + Mul<U2, Output = M>,
896 {
897 let FieldShares { value, macs, keys } = self;
898
899 let (value1, value2) = value.split_halves::<MDiv2>();
900 let (macs1, macs2): (Vec<_>, Vec<_>) = macs
901 .into_vec()
902 .into_iter()
903 .map(|mac| mac.split_halves::<MDiv2>())
904 .collect();
905
906 let (keys1, keys2): (Vec<_>, Vec<_>) = keys
907 .into_vec()
908 .into_iter()
909 .map(|key| key.split_halves::<MDiv2>())
910 .collect();
911
912 (
913 FieldShares::try_new(value1, macs1.into(), keys1.into()).unwrap(),
914 FieldShares::try_new(value2, macs2.into(), keys2.into()).unwrap(),
915 )
916 }
917
918 pub fn merge_halves(this: Self, other: Self) -> FieldShares<F, Prod<M, U2>>
920 where
921 M: Positive + Mul<U2, Output: Positive>,
922 {
923 let FieldShares { value, macs, keys } = this;
924 let FieldShares {
925 value: other_value,
926 macs: other_macs,
927 keys: other_keys,
928 } = other;
929
930 let value = SubfieldElements::merge_halves(value, other_value);
931 let macs = izip_eq!(macs, other_macs)
932 .map(|(mac, other_mac)| FieldElements::merge_halves(mac, other_mac))
933 .collect::<Vec<_>>();
934 let keys = izip_eq!(keys, other_keys)
935 .map(|(key, other_key)| FieldShareKeys::merge_halves(key, other_key))
936 .collect::<Vec<_>>();
937
938 FieldShares::try_new(value, macs.into(), keys.into()).unwrap()
939 }
940
941 pub fn split3<M1, M2, M3>(self) -> (FieldShares<F, M1>, FieldShares<F, M2>, FieldShares<F, M3>)
943 where
944 M1: Positive,
945 M2: Positive + Add<M1>,
946 M3: Positive + Add<Sum<M2, M1>, Output = M>,
947 {
948 let FieldShares { value, macs, keys } = self;
949
950 let (value1, value2, value3) = value.split3::<M1, M2, M3>();
951 let (macs1, macs2, macs3): (Vec<_>, Vec<_>, Vec<_>) = macs
952 .into_vec()
953 .into_iter()
954 .map(|mac| mac.split3::<M1, M2, M3>())
955 .multiunzip();
956
957 let (keys1, keys2, keys3): (Vec<_>, Vec<_>, Vec<_>) = keys
958 .into_vec()
959 .into_iter()
960 .map(|key| key.split3::<M1, M2, M3>())
961 .multiunzip();
962
963 (
964 FieldShares::try_new(value1, macs1.into(), keys1.into()).unwrap(),
965 FieldShares::try_new(value2, macs2.into(), keys2.into()).unwrap(),
966 FieldShares::try_new(value3, macs3.into(), keys3.into()).unwrap(),
967 )
968 }
969
970 pub fn split_thirds<MDiv3>(
972 self,
973 ) -> (
974 FieldShares<F, MDiv3>,
975 FieldShares<F, MDiv3>,
976 FieldShares<F, MDiv3>,
977 )
978 where
979 MDiv3: Positive + Mul<U3, Output = M>,
980 {
981 let FieldShares { value, macs, keys } = self;
982
983 let (value1, value2, value3) = value.split_thirds::<MDiv3>();
984 let (macs1, macs2, macs3): (Vec<_>, Vec<_>, Vec<_>) = macs
985 .into_vec()
986 .into_iter()
987 .map(|mac| mac.split_thirds::<MDiv3>())
988 .multiunzip();
989
990 let (keys1, keys2, keys3): (Vec<_>, Vec<_>, Vec<_>) = keys
991 .into_vec()
992 .into_iter()
993 .map(|key| key.split_thirds::<MDiv3>())
994 .multiunzip();
995
996 (
997 FieldShares::try_new(value1, macs1.into(), keys1.into()).unwrap(),
998 FieldShares::try_new(value2, macs2.into(), keys2.into()).unwrap(),
999 FieldShares::try_new(value3, macs3.into(), keys3.into()).unwrap(),
1000 )
1001 }
1002
1003 pub fn merge_thirds(this: Self, other1: Self, other2: Self) -> FieldShares<F, Prod<M, U3>>
1005 where
1006 M: Positive + Mul<U3, Output: Positive>,
1007 {
1008 let FieldShares {
1009 value: v1,
1010 macs: m1,
1011 keys: k1,
1012 } = this;
1013 let FieldShares {
1014 value: v2,
1015 macs: m2,
1016 keys: k2,
1017 } = other1;
1018 let FieldShares {
1019 value: v3,
1020 macs: m3,
1021 keys: k3,
1022 } = other2;
1023
1024 let value = SubfieldElements::merge_thirds(v1, v2, v3);
1025 let macs = izip_eq!(m1, m2, m3)
1026 .map(|(mac1, mac2, mac3)| FieldElements::merge_thirds(mac1, mac2, mac3))
1027 .collect::<Vec<_>>();
1028 let keys = izip_eq!(k1, k2, k3)
1029 .map(|(key1, key2, key3)| FieldShareKeys::merge_thirds(key1, key2, key3))
1030 .collect::<Vec<_>>();
1031
1032 FieldShares::try_new(value, macs.into(), keys.into()).unwrap()
1033 }
1034}
1035
1036impl<F: FieldExtension> From<FieldShare<F>> for FieldShares<F, U1> {
1043 fn from(share: FieldShare<F>) -> Self {
1044 FieldShares {
1045 value: HeapArray::from(share.value),
1046 macs: share
1047 .macs
1048 .into_vec()
1049 .into_iter()
1050 .map(HeapArray::from)
1051 .collect(),
1052 keys: share
1053 .keys
1054 .into_vec()
1055 .into_iter()
1056 .map(FieldShareKeys::from)
1057 .collect(),
1058 }
1059 }
1060}
1061
1062impl<F: FieldExtension, M: Positive> From<HeapArray<FieldShare<F>, M>> for FieldShares<F, M> {
1065 fn from(shares: HeapArray<FieldShare<F>, M>) -> Self {
1066 let (values, macs, keys): (Vec<_>, Vec<_>, Vec<_>) = shares
1067 .into_iter()
1068 .map(|share| (share.value, share.macs, share.keys))
1069 .multiunzip();
1070 let macs = transpose(macs)
1071 .into_iter()
1072 .map(HeapArray::from_iter)
1073 .collect::<Box<[_]>>();
1074 let keys = transpose(keys)
1075 .into_iter()
1076 .map(|peer_keys| {
1077 let alpha = peer_keys[0].get_alpha();
1078 let betas = peer_keys
1079 .into_iter()
1080 .map(|key| {
1081 let FieldShareKey { alpha: _, beta } = key;
1082 beta
1083 })
1084 .collect::<HeapArray<_, M>>();
1085 FieldShareKeys::new(alpha, betas)
1086 })
1087 .collect::<Box<[_]>>();
1088
1089 FieldShares {
1090 value: HeapArray::from_iter(values),
1091 macs,
1092 keys,
1093 }
1094 }
1095}
1096
1097type SubfieldElementsIterator<F, M> = <SubfieldElements<F, M> as IntoIterator>::IntoIter;
1100type FieldElementsIterator<F, M> = <FieldElements<F, M> as IntoIterator>::IntoIter;
1101
1102#[derive(Default, Clone, Debug)]
1103pub struct FieldSharesIterator<F: FieldExtension, M: Positive> {
1104 index: usize,
1105
1106 value: SubfieldElementsIterator<F, M>,
1107 macs: Vec<FieldElementsIterator<F, M>>,
1108 betas: Vec<FieldElementsIterator<F, M>>,
1109 alphas: Vec<GlobalFieldKey<F>>,
1110}
1111
1112impl<F: FieldExtension, M: Positive> ExactSizeIterator for FieldSharesIterator<F, M> {
1113 fn len(&self) -> usize {
1114 M::to_usize() - self.index
1115 }
1116}
1117
1118impl<F: FieldExtension, M: Positive> Iterator for FieldSharesIterator<F, M> {
1119 type Item = FieldShare<F>;
1120
1121 fn next(&mut self) -> Option<Self::Item> {
1122 if self.index < M::to_usize() {
1123 let value = self.value.next()?;
1124 let macs = self
1125 .macs
1126 .iter_mut()
1127 .map(|mac| mac.next())
1128 .collect::<Option<_>>()?;
1129 let keys = izip!(&mut self.betas, &self.alphas)
1130 .map(|(beta, alpha)| {
1131 beta.next().map(|beta| FieldShareKey {
1132 alpha: alpha.clone(),
1133 beta,
1134 })
1135 })
1136 .collect::<Option<_>>()?;
1137 self.index += 1;
1138 Some(FieldShare::new(value, macs, keys))
1139 } else {
1140 None
1141 }
1142 }
1143}
1144
1145impl<F: FieldExtension, M: Positive> IntoIterator for FieldShares<F, M> {
1146 type Item = FieldShare<F>;
1147 type IntoIter = FieldSharesIterator<F, M>;
1148
1149 fn into_iter(self) -> Self::IntoIter {
1150 let FieldShares { value, macs, keys } = self;
1151 let value = value.into_iter();
1152 let macs = macs
1153 .into_vec()
1154 .into_iter()
1155 .map(|mac| mac.into_iter())
1156 .collect();
1157 let (betas, alphas): (Vec<_>, Vec<_>) = keys
1158 .into_vec()
1159 .into_iter()
1160 .map(|key| (key.betas.into_iter(), key.alpha))
1161 .unzip();
1162
1163 FieldSharesIterator {
1164 index: 0,
1165 value,
1166 macs,
1167 betas,
1168 alphas,
1169 }
1170 }
1171}
1172
1173impl<F: FieldExtension, M: Positive> IntoIterator for &FieldShares<F, M> {
1174 type Item = FieldShare<F>;
1175 type IntoIter = FieldSharesIterator<F, M>;
1176
1177 fn into_iter(self) -> Self::IntoIter {
1178 let value = self.value.clone().into_iter();
1179 let macs = self
1180 .macs
1181 .iter()
1182 .map(|mac| mac.clone().into_iter())
1183 .collect();
1184 let (betas, alphas): (Vec<_>, Vec<_>) = self
1185 .keys
1186 .iter()
1187 .map(|key| (key.betas.clone().into_iter(), key.alpha.clone()))
1188 .unzip();
1189
1190 FieldSharesIterator {
1191 index: 0,
1192 value,
1193 macs,
1194 betas,
1195 alphas,
1196 }
1197 }
1198}
1199
1200impl<F: FieldExtension, N: Positive> FromIterator<FieldShare<F>> for FieldShares<F, N> {
1201 fn from_iter<T: IntoIterator<Item = FieldShare<F>>>(iter: T) -> Self {
1202 let (values, macs, keys): (Vec<_>, Vec<_>, Vec<_>) = iter
1203 .into_iter()
1204 .map(|share| (share.value, share.macs, share.keys))
1205 .multiunzip();
1206 let macs = transpose(macs)
1207 .into_iter()
1208 .map(HeapArray::from_iter)
1209 .collect::<Box<[_]>>();
1210 let keys = transpose(keys)
1211 .into_iter()
1212 .map(|peer_keys| {
1213 let alpha = peer_keys[0].get_alpha();
1214 let betas = peer_keys
1215 .into_iter()
1216 .map(|key| {
1217 let FieldShareKey { alpha: _, beta } = key;
1218 beta
1219 })
1220 .collect::<HeapArray<_, N>>();
1221 FieldShareKeys::new(alpha, betas)
1222 })
1223 .collect::<Box<[_]>>();
1224
1225 FieldShares {
1226 value: HeapArray::from_iter(values),
1227 macs,
1228 keys,
1229 }
1230 }
1231}
1232
1233impl<F: FieldExtension, N: Positive> IntoParallelIterator for FieldShares<F, N> {
1234 type Item = FieldShare<F>;
1235 type Iter = rayon::vec::IntoIter<FieldShare<F>>;
1236
1237 fn into_par_iter(self) -> Self::Iter {
1238 self.into_iter().collect::<Vec<_>>().into_par_iter()
1239 }
1240}
1241
1242pub struct FieldSharesChunks<F: FieldExtension, M: Positive + PartialDiv<CS>, CS: Positive> {
1244 field_shares: FieldSharesIterator<F, M>,
1245 current_chunk: usize,
1246 _chunk_size: std::marker::PhantomData<CS>,
1247}
1248
1249impl<F: FieldExtension, M: Positive + PartialDiv<CS>, CS: Positive> FieldSharesChunks<F, M, CS> {
1250 #[allow(clippy::len_without_is_empty)]
1251 pub fn len(&self) -> usize {
1252 M::USIZE / CS::USIZE - self.current_chunk
1255 }
1256}
1257
1258impl<F: FieldExtension, M: Positive + PartialDiv<CS>, CS: Positive> Iterator
1259 for FieldSharesChunks<F, M, CS>
1260{
1261 type Item = FieldShares<F, CS>;
1262
1263 fn next(&mut self) -> Option<Self::Item> {
1264 if self.current_chunk * CS::to_usize() >= M::to_usize() {
1265 return None;
1266 }
1267
1268 let chunk_shares = self
1269 .field_shares
1270 .by_ref()
1271 .take(CS::to_usize())
1272 .collect::<Vec<_>>();
1273
1274 self.current_chunk += 1;
1275
1276 Some(chunk_shares.into_iter().collect())
1277 }
1278}
1279
1280impl<F: FieldExtension, M: Positive> FieldShares<F, M> {
1281 pub fn chunks<CS: Positive>(&self) -> FieldSharesChunks<F, M, CS>
1284 where
1285 M: PartialDiv<CS>,
1286 {
1287 FieldSharesChunks {
1288 field_shares: self.into_iter(),
1289 current_chunk: 0,
1290 _chunk_size: std::marker::PhantomData,
1291 }
1292 }
1293}
1294
1295#[cfg(test)]
1296mod tests {
1297 use std::ops::Div;
1298
1299 use itertools::enumerate;
1300 use typenum::{Unsigned, U12};
1301
1302 use super::*;
1303 use crate::{
1304 algebra::elliptic_curve::Curve25519Ristretto as C,
1305 random::{self},
1306 sharing::{GlobalScalarKey, ScalarShares, Verifiable},
1307 types::heap_array::curve_arrays::Scalars,
1308 };
1309
1310 pub type M = U12;
1315 pub type Value = Scalars<C, M>;
1316 pub type Constant = Scalars<C, M>;
1317 pub type Share = ScalarShares<C, M>;
1318 pub type GlobalKey = GlobalScalarKey<C>;
1319
1320 pub type Mdiv2 = <M as Div<U2>>::Output;
1322 pub type ShareMdiv2 = ScalarShares<C, Mdiv2>;
1323 pub type Mdiv3 = <M as Div<U3>>::Output;
1324 pub type ShareMdiv3 = ScalarShares<C, Mdiv3>;
1325 pub const N_PARTIES: usize = 3;
1328
1329 #[test]
1330 fn test_open_to() {
1331 let mut rng = random::test_rng();
1332 let local_share = Share::random_with(&mut rng, N_PARTIES);
1333
1334 for i in 0..N_PARTIES - 1 {
1335 let open_share = local_share.open_to(i).unwrap();
1336 assert_eq!(open_share.get_value(), &local_share.value);
1337 assert_eq!(open_share.get_mac(), &local_share.macs[i]);
1338 }
1339 }
1340
1341 #[test]
1342 fn test_random() {
1343 let mut rng = random::test_rng();
1344
1345 let share = Share::random_with(&mut rng, N_PARTIES);
1347 assert_eq!(share.get_macs().len(), N_PARTIES - 1);
1348 assert_eq!(share.get_keys().len(), N_PARTIES - 1);
1349
1350 let value = &Value::random(&mut rng);
1352 let share_with_value = Share::random_with(&mut rng, (N_PARTIES, value.to_owned()));
1353 assert_eq!(share_with_value.get_value(), value);
1354 assert_eq!(share_with_value.get_macs().len(), N_PARTIES - 1);
1355 assert_eq!(share_with_value.get_keys().len(), N_PARTIES - 1);
1356 }
1357
1358 #[test]
1359 fn test_random_vec_and_reconstruct() {
1360 let mut rng = random::test_rng();
1361
1362 let shares: Vec<_> = Share::random_n(&mut rng, N_PARTIES);
1364 assert_eq!(shares.len(), N_PARTIES);
1365 for share in &shares {
1366 assert_eq!(share.get_macs().len(), N_PARTIES - 1);
1367 assert_eq!(share.get_keys().len(), N_PARTIES - 1);
1368 }
1369 let unauthenticated_shares = shares
1370 .iter()
1371 .map(|s| s.get_value().to_owned())
1372 .collect::<Vec<_>>();
1373 let expected = Value::from_additive_shares(&unauthenticated_shares);
1374 let reconstructed = Share::reconstruct_all(&shares).unwrap();
1375 assert_eq!(reconstructed, expected);
1376
1377 let value = &Value::random(&mut rng);
1379 let shares: Vec<_> = Share::random_n_with(&mut rng, N_PARTIES, value.to_owned());
1380 assert_eq!(shares.len(), N_PARTIES);
1381 for share in &shares {
1382 assert_eq!(share.get_macs().len(), N_PARTIES - 1);
1383 assert_eq!(share.get_keys().len(), N_PARTIES - 1);
1384 }
1385 let reconstructed = Share::reconstruct_all(&shares).unwrap();
1386 assert_eq!(reconstructed, value.to_owned());
1387 }
1388
1389 #[test]
1390 fn test_random_vec_with_global_key_and_reconstruct() {
1391 let mut rng = random::test_rng();
1392
1393 let alphas = Vec::<Vec<GlobalKey>>::random_with(&mut rng, N_PARTIES);
1395 let shares_from_alphas: Vec<_> = Share::random_n_with_each(&mut rng, alphas.clone());
1396 assert_eq!(shares_from_alphas.len(), N_PARTIES);
1397 for (share_a, my_alphas) in izip_eq!(&shares_from_alphas, alphas) {
1398 assert_eq!(share_a.get_macs().len(), N_PARTIES - 1);
1399 assert_eq!(share_a.get_keys().len(), N_PARTIES - 1);
1400 assert_eq!(share_a.get_alphas().collect::<Vec<_>>(), my_alphas);
1401 }
1402 let _ = Share::reconstruct_all(&shares_from_alphas).unwrap(); let value = &Value::random(&mut rng);
1406 let alphas = Vec::<Vec<GlobalKey>>::random_with(&mut rng, N_PARTIES);
1407 let shares_from_value_and_alphas: Vec<_> =
1408 Share::random_n_with(&mut rng, N_PARTIES, (value.to_owned(), alphas.clone()));
1409 assert_eq!(shares_from_value_and_alphas.len(), N_PARTIES);
1410 for (share_a, my_alphas) in izip_eq!(&shares_from_value_and_alphas, alphas) {
1411 assert_eq!(share_a.get_macs().len(), N_PARTIES - 1);
1412 assert_eq!(share_a.get_keys().len(), N_PARTIES - 1);
1413 assert_eq!(share_a.get_alphas().collect::<Vec<_>>(), my_alphas);
1414 }
1415 let reconstructed = Share::reconstruct_all(&shares_from_value_and_alphas).unwrap();
1416 assert_eq!(&reconstructed, value);
1417
1418 let value = Value::random(&mut rng);
1420 let unauth_shares = value.to_additive_shares(N_PARTIES, &mut rng);
1421 let alphas = Vec::<Vec<GlobalKey>>::random_with(&mut rng, N_PARTIES);
1422 let shares_from_unauth_and_alphas: Vec<_> =
1423 Share::random_n_with_each(&mut rng, izip_eq!(unauth_shares.clone(), alphas.clone()));
1424 assert_eq!(shares_from_unauth_and_alphas.len(), N_PARTIES);
1425 for (share_a, my_alphas) in izip_eq!(&shares_from_unauth_and_alphas, alphas) {
1426 assert_eq!(share_a.get_macs().len(), N_PARTIES - 1);
1427 assert_eq!(share_a.get_keys().len(), N_PARTIES - 1);
1428 assert_eq!(share_a.get_alphas().collect::<Vec<_>>(), my_alphas);
1429 }
1430 let reconstructed = Share::reconstruct_all(&shares_from_unauth_and_alphas).unwrap();
1431 assert_eq!(reconstructed, value);
1432 }
1433
1434 #[test]
1435 fn test_verify_mac() {
1436 let mut rng = random::test_rng();
1437
1438 let shares: Vec<_> = Share::random_n(&mut rng, N_PARTIES);
1439
1440 enumerate(shares.iter()).for_each(|(i, s_i)| {
1442 enumerate(shares.iter())
1443 .filter(|(j, _)| i != *j)
1444 .for_each(|(j, s_j)| {
1445 let open_share = s_j.open_to(i - (i > j) as usize).unwrap();
1446 s_i.verify_from(&open_share, j - (j > i) as usize).unwrap();
1447 });
1448 });
1449
1450 Share::verify_all(&shares).unwrap();
1452 }
1453
1454 #[test]
1455 fn test_add() {
1456 let mut rng = random::test_rng();
1457
1458 let alphas = Vec::<Vec<GlobalKey>>::random_with(&mut rng, N_PARTIES);
1459 let a = &Value::random(&mut rng);
1460 let b = &Value::random(&mut rng);
1461
1462 let shares_a: Vec<_> =
1463 Share::random_n_with(&mut rng, N_PARTIES, (a.to_owned(), alphas.clone()));
1464 let shares_b: Vec<_> = Share::random_n_with(&mut rng, N_PARTIES, (b.to_owned(), alphas));
1465
1466 let shares_a_ref_plus_b_ref = izip_eq!(&shares_a, &shares_b)
1468 .map(|(share_a, share_b)| share_a + share_b)
1469 .collect::<Vec<_>>();
1470 let reconstructed = Share::reconstruct_all(&shares_a_ref_plus_b_ref).unwrap();
1471 assert_eq!(reconstructed, a + b);
1472
1473 let shares_a_ref_plus_b = izip_eq!(&shares_a, shares_b.clone())
1475 .map(|(share_a, share_b)| share_a + share_b)
1476 .collect::<Vec<_>>();
1477 let reconstructed = Share::reconstruct_all(&shares_a_ref_plus_b).unwrap();
1478 assert_eq!(reconstructed, a + b);
1479
1480 let shares_a_plus_b_ref = izip_eq!(shares_a.clone(), &shares_b)
1482 .map(|(share_a, share_b)| share_a + share_b)
1483 .collect::<Vec<_>>();
1484 let reconstructed = Share::reconstruct_all(&shares_a_plus_b_ref).unwrap();
1485 assert_eq!(reconstructed, a + b);
1486
1487 let shares_a_plus_b = izip_eq!(shares_a.clone(), shares_b.clone())
1489 .map(|(share_a, share_b)| share_a + share_b)
1490 .collect::<Vec<_>>();
1491 let reconstructed = Share::reconstruct_all(&shares_a_plus_b).unwrap();
1492 assert_eq!(reconstructed, a + b);
1493
1494 let mut shares_a_add_assign_b_ref = shares_a.clone();
1496 izip_eq!(&mut shares_a_add_assign_b_ref, &shares_b)
1497 .for_each(|(share_a, share_b)| *share_a += share_b);
1498 let reconstructed = Share::reconstruct_all(&shares_a_add_assign_b_ref).unwrap();
1499 assert_eq!(reconstructed, a + b);
1500
1501 let mut shares_a_add_assign_b = shares_a.clone();
1503 izip_eq!(&mut shares_a_add_assign_b, shares_b)
1504 .for_each(|(share_a, share_b)| *share_a += share_b);
1505 let reconstructed = Share::reconstruct_all(&shares_a_add_assign_b).unwrap();
1506 assert_eq!(reconstructed, a + b);
1507 }
1508
1509 #[test]
1510 fn test_add_secret() {
1511 let mut rng = random::test_rng();
1512
1513 let a = &Value::random(&mut rng);
1514 let k = &Value::random(&mut rng);
1515
1516 let shares_a: Vec<_> = Share::random_n_with(&mut rng, N_PARTIES, a.to_owned());
1517
1518 let shares_a_plus_k_ref = enumerate(shares_a.iter())
1520 .map(|(i, share_a)| share_a.add_secret(k, i == 0))
1521 .collect::<Vec<_>>();
1522 let reconstructed = Share::reconstruct_all(&shares_a_plus_k_ref).unwrap();
1523 assert_eq!(reconstructed, a + k);
1524
1525 let shares_a_plus_k = enumerate(shares_a)
1527 .map(|(i, share_a)| share_a.add_secret_owned(k, i == 0))
1528 .collect::<Vec<_>>();
1529 let reconstructed = Share::reconstruct_all(&shares_a_plus_k).unwrap();
1530 assert_eq!(reconstructed, a + k);
1531 }
1532
1533 #[test]
1534 fn test_mul_constant() {
1535 let mut rng = random::test_rng();
1536
1537 let a = &Value::random(&mut rng);
1538 let k = &Constant::random(&mut rng);
1539
1540 let shares_a: Vec<_> = Share::random_n_with(&mut rng, N_PARTIES, a.to_owned());
1541
1542 let shares_a_times_k_ref = izip_eq!(&shares_a)
1544 .map(|share_a| share_a * k.to_owned())
1545 .collect::<Vec<_>>();
1546 let reconstructed = Share::reconstruct_all(&shares_a_times_k_ref).unwrap();
1547 assert_eq!(reconstructed, a.to_owned() * k);
1548
1549 let shares_a_times_k = izip_eq!(shares_a.clone())
1551 .map(|share_a| share_a * k)
1552 .collect::<Vec<_>>();
1553 let reconstructed = Share::reconstruct_all(&shares_a_times_k).unwrap();
1554 assert_eq!(reconstructed, a * k);
1555
1556 let mut shares_a_times_k_assign = shares_a.clone();
1558 izip_eq!(&mut shares_a_times_k_assign).for_each(|share_a| *share_a *= k);
1559 let reconstructed = Share::reconstruct_all(&shares_a_times_k_assign).unwrap();
1560 assert_eq!(reconstructed, a * k);
1561 }
1562
1563 #[test]
1564 fn test_sub() {
1565 let mut rng = random::test_rng();
1566 let alphas = Vec::<Vec<GlobalKey>>::random_with(&mut rng, N_PARTIES);
1567
1568 let a = &Value::random(&mut rng);
1569 let b = &Value::random(&mut rng);
1570
1571 let shares_a: Vec<_> =
1572 Share::random_n_with(&mut rng, N_PARTIES, (a.to_owned(), alphas.clone()));
1573 let shares_b: Vec<_> = Share::random_n_with(&mut rng, N_PARTIES, (b.to_owned(), alphas));
1574
1575 let shares_a_ref_minus_b_ref = izip_eq!(&shares_a, &shares_b)
1577 .map(|(share_a, share_b)| share_a - share_b)
1578 .collect::<Vec<_>>();
1579
1580 let reconstructed = Share::reconstruct_all(&shares_a_ref_minus_b_ref).unwrap();
1581 assert_eq!(reconstructed, a - b);
1582
1583 let shares_a_ref_minus_b = izip_eq!(&shares_a, shares_b.clone())
1585 .map(|(share_a, share_b)| share_a - share_b)
1586 .collect::<Vec<_>>();
1587 let reconstructed = Share::reconstruct_all(&shares_a_ref_minus_b).unwrap();
1588 assert_eq!(reconstructed, a - b);
1589
1590 let shares_a_minus_b_ref = izip_eq!(shares_a.clone(), &shares_b)
1592 .map(|(share_a, share_b)| share_a - share_b)
1593 .collect::<Vec<_>>();
1594 let reconstructed = Share::reconstruct_all(&shares_a_minus_b_ref).unwrap();
1595 assert_eq!(reconstructed, a - b);
1596
1597 let shares_a_minus_b = izip_eq!(shares_a.clone(), shares_b.clone())
1599 .map(|(share_a, share_b)| share_a - share_b)
1600 .collect::<Vec<_>>();
1601 let reconstructed = Share::reconstruct_all(&shares_a_minus_b).unwrap();
1602 assert_eq!(reconstructed, a - b);
1603
1604 let mut shares_a_sub_assign_b_ref = shares_a.clone();
1606 izip_eq!(&mut shares_a_sub_assign_b_ref, &shares_b)
1607 .for_each(|(share_a, share_b)| *share_a -= share_b);
1608 let reconstructed = Share::reconstruct_all(&shares_a_sub_assign_b_ref).unwrap();
1609 assert_eq!(reconstructed, a - b);
1610
1611 let mut shares_a_sub_assign_b = shares_a.clone();
1613 izip_eq!(&mut shares_a_sub_assign_b, shares_b)
1614 .for_each(|(share_a, share_b)| *share_a -= share_b);
1615 let reconstructed = Share::reconstruct_all(&shares_a_sub_assign_b).unwrap();
1616 assert_eq!(reconstructed, a - b);
1617 }
1618
1619 #[test]
1620 fn test_neg() {
1621 let mut rng = random::test_rng();
1622
1623 let a = Value::random(&mut rng);
1624
1625 let shares_a: Vec<_> = Share::random_n_with(&mut rng, N_PARTIES, a.to_owned());
1626
1627 let shares_a_neg_ref = shares_a.iter().map(|share_a| -share_a).collect::<Vec<_>>();
1629 let reconstructed = Share::reconstruct_all(&shares_a_neg_ref).unwrap();
1630 assert_eq!(reconstructed, -a.to_owned());
1631
1632 let shares_a_neg = shares_a
1634 .into_iter()
1635 .map(|share_a| -share_a)
1636 .collect::<Vec<_>>();
1637 let reconstructed = Share::reconstruct_all(&shares_a_neg).unwrap();
1638 assert_eq!(reconstructed, -a.to_owned());
1639 }
1640
1641 #[test]
1642 fn test_conditional_select() {
1643 let mut rng = random::test_rng();
1644
1645 let shares_a = Share::random_with(&mut rng, N_PARTIES);
1646 let shares_b = Share::random_with(&mut rng, N_PARTIES);
1647
1648 let choice = Choice::from(0u8);
1650 let selected = Share::conditional_select(&shares_a, &shares_b, choice);
1651 assert_eq!(selected, shares_a);
1652
1653 let choice = Choice::from(1u8);
1655 let selected = Share::conditional_select(&shares_a, &shares_b, choice);
1656 assert_eq!(selected, shares_b);
1657 }
1658
1659 #[test]
1660 fn test_ct_eq() {
1661 let mut rng = random::test_rng();
1662
1663 let shares_a = Share::random_with(&mut rng, N_PARTIES);
1664 let shares_b = Share::random_with(&mut rng, N_PARTIES);
1665
1666 assert!(Into::<bool>::into(shares_a.ct_eq(&shares_a.clone())));
1668 assert!(Into::<bool>::into(shares_b.ct_eq(&shares_b.clone())));
1669 assert!(!Into::<bool>::into(shares_a.ct_eq(&shares_b)));
1670 assert!(!Into::<bool>::into(shares_b.ct_eq(&shares_a)));
1671 }
1672
1673 #[test]
1674 fn test_split_halves() {
1675 let m_div2 = Mdiv2::to_usize();
1676
1677 let shares = Share::random_with(&mut random::test_rng(), N_PARTIES);
1678
1679 let (shares1, shares2) = shares.clone().split_halves::<Mdiv2>();
1680
1681 assert_eq!(shares1.get_value().len(), m_div2);
1683 assert_eq!(shares2.get_value().len(), m_div2);
1684
1685 assert_eq!(shares1.get_value().as_ref(), &shares.get_value()[..m_div2]);
1686 assert_eq!(shares2.get_value().as_ref(), &shares.get_value()[m_div2..]);
1687
1688 izip_eq!(&shares1.macs, &shares2.macs, &shares.macs).for_each(|(mac1, mac2, mac)| {
1689 assert_eq!(mac1.as_ref(), &mac[..m_div2]);
1690 assert_eq!(mac2.as_ref(), &mac[m_div2..]);
1691 });
1692 izip_eq!(&shares1.keys, &shares2.keys, &shares.keys).for_each(|(key1, key2, key)| {
1693 assert_eq!(key1.alpha, key.alpha);
1694 assert_eq!(key2.alpha, key.alpha);
1695 assert_eq!(key1.betas.as_ref(), &key.betas[..m_div2]);
1696 assert_eq!(key2.betas.as_ref(), &key.betas[m_div2..]);
1697 });
1698
1699 let merged_shares = ShareMdiv2::merge_halves(shares1, shares2);
1701 assert_eq!(merged_shares, shares);
1702 }
1703
1704 #[test]
1705 fn test_split_thirds() {
1706 let m_div3 = Mdiv3::to_usize();
1707
1708 let shares = Share::random_with(&mut random::test_rng(), N_PARTIES);
1709
1710 let (shares1, shares2, shares3) = shares.clone().split_thirds::<Mdiv3>();
1711
1712 assert_eq!(shares1.get_value().len(), m_div3);
1714 assert_eq!(shares2.get_value().len(), m_div3);
1715 assert_eq!(shares3.get_value().len(), m_div3);
1716
1717 assert_eq!(shares1.get_value().as_ref(), &shares.get_value()[..m_div3]);
1718 assert_eq!(
1719 shares2.get_value().as_ref(),
1720 &shares.get_value()[m_div3..(2 * m_div3)]
1721 );
1722 assert_eq!(
1723 shares3.get_value().as_ref(),
1724 &shares.get_value()[(2 * m_div3)..]
1725 );
1726
1727 izip_eq!(&shares1.macs, &shares2.macs, &shares3.macs, &shares.macs).for_each(
1728 |(mac1, mac2, mac3, mac)| {
1729 assert_eq!(mac1.as_ref(), &mac[..m_div3]);
1730 assert_eq!(mac2.as_ref(), &mac[m_div3..(2 * m_div3)]);
1731 assert_eq!(mac3.as_ref(), &mac[(2 * m_div3)..(3 * m_div3)]);
1732 },
1733 );
1734
1735 izip_eq!(&shares1.keys, &shares2.keys, &shares3.keys, &shares.keys).for_each(
1736 |(key1, key2, key3, key)| {
1737 assert_eq!(key1.alpha, key.alpha);
1738 assert_eq!(key2.alpha, key.alpha);
1739 assert_eq!(key3.alpha, key.alpha);
1740
1741 assert_eq!(key1.betas.as_ref(), &key.betas[..m_div3]);
1742 assert_eq!(key2.betas.as_ref(), &key.betas[m_div3..(2 * m_div3)]);
1743 assert_eq!(key3.betas.as_ref(), &key.betas[(2 * m_div3)..(3 * m_div3)]);
1744 },
1745 );
1746
1747 let merged_shares = ShareMdiv3::merge_thirds(shares1, shares2, shares3);
1749 assert_eq!(merged_shares, shares);
1750 }
1751
1752 #[test]
1753 fn test_into_iter() {
1754 let m = M::to_usize();
1755
1756 let shares = Share::random_with(&mut random::test_rng(), N_PARTIES);
1757
1758 let mut iter = shares.clone().into_iter();
1759 assert_eq!(iter.len(), m);
1760
1761 for i in 0..m {
1762 assert_eq!(iter.len(), m - i);
1763 let share = iter.next().unwrap();
1764 assert_eq!(share.value, shares.get_value()[i]);
1765
1766 for j in 0..N_PARTIES - 1 {
1767 assert_eq!(share.macs[j], shares.macs[j][i]);
1768 assert_eq!(share.keys[j].alpha, shares.keys[j].alpha);
1769 assert_eq!(share.keys[j].beta, shares.keys[j].betas[i]);
1770 }
1771 }
1772 }
1773
1774 #[test]
1775 fn test_from_iterator() {
1776 let mut rng = random::test_rng();
1777 let shares = Share::random_with(&mut rng, N_PARTIES);
1778
1779 let collected: Vec<_> = shares.clone().into_iter().collect();
1780 let from_iterator: Share = collected.into_iter().collect();
1781
1782 assert_eq!(shares, from_iterator);
1783 }
1784
1785 #[test]
1786 #[should_panic]
1787 fn test_from_iterator_unequal_sizes() {
1788 let mut rng = random::test_rng();
1789 let shares = Share::random_with(&mut rng, N_PARTIES);
1790
1791 let mut collected: Vec<_> = shares.clone().into_iter().collect();
1792 collected.pop(); let _ = collected.into_iter().collect::<Share>();
1794 }
1795
1796 #[test]
1797 fn test_chunks() {
1798 type ChunkSize = typenum::U4;
1799 let m = M::to_usize();
1800 let chunk_size = ChunkSize::to_usize();
1801 let n_chunks = m / chunk_size;
1802
1803 let shares = Share::random_with(&mut random::test_rng(), N_PARTIES);
1804 let mut chunks_iter = shares.chunks::<ChunkSize>();
1805
1806 assert_eq!(chunks_iter.len(), n_chunks);
1807
1808 for i in 0..n_chunks {
1809 assert_eq!(chunks_iter.len(), n_chunks - i);
1811 let chunk = chunks_iter.next().unwrap();
1812 assert_eq!(chunk.value.len(), chunk_size);
1813
1814 for j in 0..chunk_size {
1815 assert_eq!(chunk.value[j], shares.get_value()[i * chunk_size + j]);
1816 }
1817
1818 for (mac_chunk, macs) in izip_eq!(&chunk.macs, &shares.macs) {
1819 for j in 0..chunk_size {
1820 assert_eq!(mac_chunk[j], macs[i * chunk_size + j]);
1821 }
1822 }
1823
1824 for (key_chunk, keys) in izip_eq!(&chunk.keys, &shares.keys) {
1825 assert_eq!(key_chunk.alpha, keys.alpha);
1826 for j in 0..chunk_size {
1827 assert_eq!(key_chunk.betas[j], keys.betas[i * chunk_size + j]);
1828 }
1829 }
1830 }
1831
1832 assert!(chunks_iter.next().is_none());
1833 }
1834}