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