1use std::{
2 fmt::Debug,
3 iter::Sum as IterSum,
4 ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
5};
6
7use serde::{Deserialize, Serialize};
8use subtle::{Choice, ConstantTimeEq};
9use typenum::{Prod, Sum, U1, U2, U3};
10use wincode::{SchemaRead, SchemaWrite};
11
12use crate::{
13 algebra::field::{FieldElement, FieldExtension, SubfieldElement},
14 errors::PrimitiveError,
15 izip_eq,
16 random::{CryptoRngCore, Random, RandomWith},
17 sharing::{FieldShareKey, GlobalFieldKey, OpenFieldShares},
18 types::{
19 heap_array::{FieldElements, SubfieldElements},
20 ConditionallySelectable,
21 HeapArray,
22 Positive,
23 },
24};
25
26#[derive(Clone, Default, PartialEq, Eq, Serialize, Deserialize, SchemaRead, SchemaWrite)]
29#[serde(bound = "F: FieldExtension, M: Positive")]
30#[repr(C)]
31pub struct FieldShareKeys<F: FieldExtension, M: Positive> {
32 pub(crate) alpha: GlobalFieldKey<F>, pub(crate) betas: FieldElements<F, M>, }
35
36impl<F: FieldExtension, M: Positive> FieldShareKeys<F, M> {
37 #[inline]
38 pub fn new(alpha: GlobalFieldKey<F>, betas: FieldElements<F, M>) -> Self {
39 FieldShareKeys { alpha, betas }
40 }
41
42 #[inline]
43 pub fn get_alpha(&self) -> GlobalFieldKey<F> {
44 self.alpha.clone()
45 }
46
47 #[inline]
48 pub fn get_alpha_value(&self) -> FieldElement<F> {
49 *self.alpha
50 }
51
52 #[inline]
53 pub fn get_betas(&self) -> &FieldElements<F, M> {
54 &self.betas
55 }
56
57 #[inline]
60 pub fn compute_mac(&self, values: &SubfieldElements<F, M>) -> FieldElements<F, M> {
61 izip_eq!(&self.betas, values)
62 .map(|(beta, value)| (*self.alpha * value) + beta)
63 .collect()
64 }
65
66 #[inline]
67 pub fn verify_mac(&self, open_share: &OpenFieldShares<F, M>) -> Result<(), PrimitiveError> {
68 let computed_macs = self.compute_mac(&open_share.value);
69 bool::from(computed_macs.ct_eq(&open_share.mac))
70 .then_some(())
71 .ok_or_else(|| {
72 PrimitiveError::WrongMAC(serde_json::to_string(&open_share.mac).unwrap())
73 })
74 }
75}
76
77impl<T: FieldExtension, M: Positive> Debug for FieldShareKeys<T, M> {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 f.debug_struct(format!("FieldShareKeys<{}>", M::SIZE).as_str())
80 .field("alpha", &self.alpha)
81 .field("betas", &self.betas)
82 .finish()
83 }
84}
85
86impl<F: FieldExtension, M: Positive> Add for FieldShareKeys<F, M> {
93 type Output = FieldShareKeys<F, M>;
94
95 #[inline]
96 fn add(self, other: FieldShareKeys<F, M>) -> Self::Output {
97 assert_eq!(self.alpha, other.alpha);
98 FieldShareKeys {
99 alpha: self.alpha,
100 betas: self.betas + other.betas,
101 }
102 }
103}
104
105impl<F: FieldExtension, M: Positive> Add<&FieldShareKeys<F, M>> for FieldShareKeys<F, M> {
106 type Output = FieldShareKeys<F, M>;
107
108 #[inline]
109 fn add(self, other: &FieldShareKeys<F, M>) -> Self::Output {
110 assert_eq!(self.alpha, other.alpha);
111 FieldShareKeys {
112 alpha: self.alpha,
113 betas: self.betas + &other.betas,
114 }
115 }
116}
117
118impl<F: FieldExtension, M: Positive> Add<FieldShareKeys<F, M>> for &FieldShareKeys<F, M> {
119 type Output = FieldShareKeys<F, M>;
120
121 #[inline]
122 fn add(self, other: FieldShareKeys<F, M>) -> Self::Output {
123 assert_eq!(self.alpha, other.alpha);
124 FieldShareKeys {
125 alpha: other.alpha,
126 betas: other.betas + &self.betas,
127 }
128 }
129}
130
131impl<F: FieldExtension, M: Positive> AddAssign for FieldShareKeys<F, M> {
134 #[inline]
135 fn add_assign(&mut self, other: Self) {
136 assert_eq!(self.alpha, other.alpha);
137 self.betas += other.betas;
138 }
139}
140
141impl<'a, F: FieldExtension, M: Positive> AddAssign<&'a FieldShareKeys<F, M>>
142 for FieldShareKeys<F, M>
143{
144 #[inline]
145 fn add_assign(&mut self, other: &'a FieldShareKeys<F, M>) {
146 assert_eq!(self.alpha, other.alpha);
147 self.betas += &other.betas;
148 }
149}
150
151impl<F: FieldExtension, M: Positive> Sub for FieldShareKeys<F, M> {
154 type Output = FieldShareKeys<F, M>;
155
156 #[inline]
157 fn sub(self, other: FieldShareKeys<F, M>) -> Self::Output {
158 assert_eq!(self.alpha, other.alpha);
159 FieldShareKeys {
160 alpha: self.alpha,
161 betas: self.betas - other.betas,
162 }
163 }
164}
165
166impl<F: FieldExtension, M: Positive> Sub<&FieldShareKeys<F, M>> for FieldShareKeys<F, M> {
167 type Output = FieldShareKeys<F, M>;
168
169 #[inline]
170 fn sub(self, other: &FieldShareKeys<F, M>) -> Self::Output {
171 assert_eq!(self.alpha, other.alpha);
172 FieldShareKeys {
173 alpha: self.alpha,
174 betas: self.betas - &other.betas,
175 }
176 }
177}
178
179impl<F: FieldExtension, M: Positive> Sub<FieldShareKeys<F, M>> for &FieldShareKeys<F, M> {
180 type Output = FieldShareKeys<F, M>;
181
182 #[inline]
183 fn sub(self, other: FieldShareKeys<F, M>) -> Self::Output {
184 assert_eq!(self.alpha, other.alpha);
185 FieldShareKeys {
186 alpha: other.alpha,
187 betas: &self.betas - other.betas,
188 }
189 }
190}
191
192impl<F: FieldExtension, M: Positive> Sub<&FieldShareKeys<F, M>> for &FieldShareKeys<F, M> {
193 type Output = FieldShareKeys<F, M>;
194
195 #[inline]
196 fn sub(self, other: &FieldShareKeys<F, M>) -> Self::Output {
197 assert_eq!(self.alpha, other.alpha);
198 FieldShareKeys {
199 alpha: self.alpha.clone(),
200 betas: &self.betas - &other.betas,
201 }
202 }
203}
204
205impl<F: FieldExtension, M: Positive> SubAssign for FieldShareKeys<F, M> {
208 #[inline]
209 fn sub_assign(&mut self, other: Self) {
210 assert_eq!(self.alpha, other.alpha);
211 self.betas -= other.betas;
212 }
213}
214
215impl<'a, F: FieldExtension, M: Positive> SubAssign<&'a FieldShareKeys<F, M>>
216 for FieldShareKeys<F, M>
217{
218 #[inline]
219 fn sub_assign(&mut self, other: &'a FieldShareKeys<F, M>) {
220 assert_eq!(self.alpha, other.alpha);
221 self.betas -= &other.betas;
222 }
223}
224
225impl<F: FieldExtension, M: Positive> Mul<FieldElements<F, M>> for FieldShareKeys<F, M> {
228 type Output = FieldShareKeys<F, M>;
229
230 #[inline]
231 fn mul(mut self, other: FieldElements<F, M>) -> Self::Output {
232 izip_eq!(&mut self.betas, other).for_each(|(beta, value)| *beta *= value);
233 self
234 }
235}
236
237impl<'a, F: FieldExtension, M: Positive> Mul<&'a FieldElements<F, M>> for FieldShareKeys<F, M> {
238 type Output = FieldShareKeys<F, M>;
239
240 #[inline]
241 fn mul(mut self, other: &'a FieldElements<F, M>) -> Self::Output {
242 izip_eq!(&mut self.betas, other).for_each(|(beta, value)| *beta *= value);
243 self
244 }
245}
246
247impl<F: FieldExtension, M: Positive> Mul<SubfieldElements<F, M>> for FieldShareKeys<F, M> {
248 type Output = FieldShareKeys<F, M>;
249
250 #[inline]
251 fn mul(mut self, other: SubfieldElements<F, M>) -> Self::Output {
252 izip_eq!(&mut self.betas, other).for_each(|(beta, value)| *beta *= value);
253 self
254 }
255}
256
257impl<'a, F: FieldExtension, M: Positive> Mul<&'a SubfieldElements<F, M>> for FieldShareKeys<F, M> {
258 type Output = FieldShareKeys<F, M>;
259
260 #[inline]
261 fn mul(mut self, other: &'a SubfieldElements<F, M>) -> Self::Output {
262 izip_eq!(&mut self.betas, other).for_each(|(beta, value)| *beta *= value);
263 self
264 }
265}
266
267impl<F: FieldExtension, M: Positive> Mul<FieldElement<F>> for FieldShareKeys<F, M> {
270 type Output = FieldShareKeys<F, M>;
271
272 #[inline]
273 fn mul(self, other: FieldElement<F>) -> Self::Output {
274 FieldShareKeys {
275 betas: self.betas * other,
276 ..self
277 }
278 }
279}
280
281impl<'a, F: FieldExtension, M: Positive> Mul<&'a FieldElement<F>> for FieldShareKeys<F, M> {
282 type Output = FieldShareKeys<F, M>;
283
284 #[inline]
285 fn mul(self, other: &'a FieldElement<F>) -> Self::Output {
286 FieldShareKeys {
287 betas: self.betas * other,
288 ..self
289 }
290 }
291}
292
293impl<F: FieldExtension, M: Positive> Mul<SubfieldElement<F>> for FieldShareKeys<F, M> {
294 type Output = FieldShareKeys<F, M>;
295
296 #[inline]
297 fn mul(self, other: SubfieldElement<F>) -> Self::Output {
298 FieldShareKeys {
299 betas: self.betas * other,
300 ..self
301 }
302 }
303}
304
305impl<'a, F: FieldExtension, M: Positive> Mul<&'a SubfieldElement<F>> for FieldShareKeys<F, M> {
306 type Output = FieldShareKeys<F, M>;
307
308 #[inline]
309 fn mul(self, other: &'a SubfieldElement<F>) -> Self::Output {
310 FieldShareKeys {
311 betas: self.betas * other,
312 ..self
313 }
314 }
315}
316
317impl<F: FieldExtension, M: Positive> MulAssign for FieldShareKeys<F, M> {
320 #[inline]
321 fn mul_assign(&mut self, other: Self) {
322 self.betas *= other.betas;
323 }
324}
325
326impl<F: FieldExtension, M: Positive> MulAssign<FieldElement<F>> for FieldShareKeys<F, M> {
327 #[inline]
328 fn mul_assign(&mut self, other: FieldElement<F>) {
329 izip_eq!(&mut self.betas).for_each(|beta| *beta *= other)
330 }
331}
332
333impl<'a, F: FieldExtension, M: Positive> MulAssign<&'a FieldElement<F>> for FieldShareKeys<F, M> {
334 #[inline]
335 fn mul_assign(&mut self, other: &'a FieldElement<F>) {
336 izip_eq!(&mut self.betas).for_each(|beta| *beta *= other)
337 }
338}
339
340impl<F: FieldExtension, M: Positive> MulAssign<SubfieldElement<F>> for FieldShareKeys<F, M> {
341 #[inline]
342 fn mul_assign(&mut self, other: SubfieldElement<F>) {
343 izip_eq!(&mut self.betas).for_each(|beta| *beta *= other)
344 }
345}
346
347impl<'a, F: FieldExtension, M: Positive> MulAssign<&'a SubfieldElement<F>>
348 for FieldShareKeys<F, M>
349{
350 #[inline]
351 fn mul_assign(&mut self, other: &'a SubfieldElement<F>) {
352 izip_eq!(&mut self.betas).for_each(|beta| *beta *= other)
353 }
354}
355
356impl<'a, F: FieldExtension, M: Positive> MulAssign<&'a SubfieldElements<F, M>>
359 for FieldShareKeys<F, M>
360{
361 #[inline]
362 fn mul_assign(&mut self, other: &'a SubfieldElements<F, M>) {
363 izip_eq!(&mut self.betas, other).for_each(|(beta, other)| *beta *= other);
364 }
365}
366
367impl<F: FieldExtension, M: Positive> Neg for FieldShareKeys<F, M> {
370 type Output = FieldShareKeys<F, M>;
371
372 #[inline]
373 fn neg(self) -> Self::Output {
374 FieldShareKeys {
375 alpha: self.alpha,
376 betas: -self.betas,
377 }
378 }
379}
380
381impl<F: FieldExtension, M: Positive> Neg for &FieldShareKeys<F, M> {
382 type Output = FieldShareKeys<F, M>;
383
384 #[inline]
385 fn neg(self) -> Self::Output {
386 FieldShareKeys {
387 alpha: self.alpha.clone(),
388 betas: -self.betas.clone(),
389 }
390 }
391}
392
393impl<F: FieldExtension, M: Positive> IterSum for FieldShareKeys<F, M> {
395 fn sum<I: Iterator<Item = Self>>(mut iter: I) -> Self {
396 let first = iter.next().unwrap_or_default();
397 iter.fold(first, |acc, x| acc + x)
398 }
399}
400
401impl<F: FieldExtension, M: Positive> FieldShareKeys<F, M> {
404 #[inline]
405 pub fn add_secret_owned(mut self, constant: SubfieldElement<F>) -> Self {
406 self.betas -= *self.alpha * constant;
407 self
408 }
409
410 #[inline]
411 pub fn add_secret(&self, constant: SubfieldElement<F>) -> Self {
412 let mut result = self.clone();
413 result.betas -= *result.alpha * constant;
414 result
415 }
416
417 #[inline]
418 pub fn add_constant_array(&self, constant: SubfieldElements<F, M>) -> Self {
419 let mut result = self.clone();
420 result.betas -= constant
421 .iter()
422 .map(|c| *result.alpha * c)
423 .collect::<FieldElements<F, M>>();
424 result
425 }
426
427 #[inline]
428 pub fn add_constant_array_owned(&mut self, constant: &SubfieldElements<F, M>) {
429 izip_eq!(&mut self.betas, constant).for_each(|(beta, c)| *beta -= *self.alpha * c);
430 }
431}
432
433impl<F: FieldExtension, M: Positive> Random for FieldShareKeys<F, M> {
438 fn random(mut rng: impl CryptoRngCore) -> Self {
439 FieldShareKeys {
440 alpha: GlobalFieldKey::random(&mut rng),
441 betas: FieldElements::random(&mut rng),
442 }
443 }
444}
445
446impl<F: FieldExtension, M: Positive> RandomWith<GlobalFieldKey<F>> for FieldShareKeys<F, M> {
447 fn random_with(mut rng: impl CryptoRngCore, alpha: GlobalFieldKey<F>) -> Self {
449 FieldShareKeys {
450 alpha,
451 betas: FieldElements::random(&mut rng),
452 }
453 }
454}
455
456impl<F: FieldExtension, M: Positive> FieldShareKeys<F, M> {
461 pub fn split<M1, M2>(self) -> (FieldShareKeys<F, M1>, FieldShareKeys<F, M2>)
463 where
464 M1: Positive,
465 M2: Positive + Add<M1, Output = M>,
466 {
467 let FieldShareKeys { alpha, betas } = self;
468
469 let (betas1, betas2) = betas.split::<M1, M2>();
470 (
471 FieldShareKeys::new(alpha.clone(), betas1),
472 FieldShareKeys::new(alpha, betas2),
473 )
474 }
475
476 pub fn split_halves<MDiv2>(self) -> (FieldShareKeys<F, MDiv2>, FieldShareKeys<F, MDiv2>)
478 where
479 MDiv2: Positive + Mul<U2, Output = M>,
480 {
481 let FieldShareKeys { alpha, betas } = self;
482
483 let (betas1, betas2) = betas.split_halves::<MDiv2>();
484 (
485 FieldShareKeys::new(alpha.clone(), betas1),
486 FieldShareKeys::new(alpha, betas2),
487 )
488 }
489
490 pub fn merge_halves(this: Self, other: Self) -> FieldShareKeys<F, Prod<M, U2>>
492 where
493 M: Positive + Mul<U2, Output: Positive>,
494 {
495 assert_eq!(this.alpha, other.alpha);
496 FieldShareKeys {
497 alpha: this.alpha,
498 betas: FieldElements::merge_halves(this.betas, other.betas),
499 }
500 }
501
502 pub fn split3<M1, M2, M3>(
504 self,
505 ) -> (
506 FieldShareKeys<F, M1>,
507 FieldShareKeys<F, M2>,
508 FieldShareKeys<F, M3>,
509 )
510 where
511 M1: Positive,
512 M2: Positive + Add<M1>,
513 M3: Positive + Add<Sum<M2, M1>, Output = M>,
514 {
515 let FieldShareKeys { alpha, betas } = self;
516
517 let (betas1, betas2, betas3) = betas.split3::<M1, M2, M3>();
518 (
519 FieldShareKeys::new(alpha.clone(), betas1),
520 FieldShareKeys::new(alpha.clone(), betas2),
521 FieldShareKeys::new(alpha, betas3),
522 )
523 }
524
525 pub fn split_thirds<MDiv3>(
527 self,
528 ) -> (
529 FieldShareKeys<F, MDiv3>,
530 FieldShareKeys<F, MDiv3>,
531 FieldShareKeys<F, MDiv3>,
532 )
533 where
534 MDiv3: Positive + Mul<U3, Output = M>,
535 {
536 let FieldShareKeys { alpha, betas } = self;
537
538 let (betas1, betas2, betas3) = betas.split_thirds::<MDiv3>();
539 (
540 FieldShareKeys::new(alpha.clone(), betas1),
541 FieldShareKeys::new(alpha.clone(), betas2),
542 FieldShareKeys::new(alpha, betas3),
543 )
544 }
545
546 pub fn merge_thirds(first: Self, second: Self, third: Self) -> FieldShareKeys<F, Prod<M, U3>>
548 where
549 M: Positive + Mul<U3, Output: Positive>,
550 {
551 assert_eq!(first.alpha, second.alpha);
552 assert_eq!(first.alpha, third.alpha);
553 FieldShareKeys {
554 alpha: first.alpha,
555 betas: FieldElements::merge_thirds(first.betas, second.betas, third.betas),
556 }
557 }
558}
559
560impl<F: FieldExtension, M: Positive> ConstantTimeEq for FieldShareKeys<F, M> {
563 #[inline]
564 fn ct_eq(&self, other: &Self) -> Choice {
565 self.alpha.ct_eq(&other.alpha) & self.betas.ct_eq(&other.betas)
566 }
567}
568
569impl<F: FieldExtension, M: Positive> ConditionallySelectable for FieldShareKeys<F, M> {
570 #[inline]
571 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
572 FieldShareKeys {
573 alpha: GlobalFieldKey::conditional_select(&a.alpha, &b.alpha, choice),
574 betas: HeapArray::conditional_select(&a.betas, &b.betas, choice),
575 }
576 }
577}
578
579impl<F: FieldExtension> From<FieldShareKey<F>> for FieldShareKeys<F, U1> {
586 fn from(key: FieldShareKey<F>) -> Self {
587 FieldShareKeys {
588 alpha: key.alpha,
589 betas: HeapArray::from(key.beta),
590 }
591 }
592}
593
594pub struct FieldShareKeysIterator<F, M>
597where
598 F: FieldExtension,
599 M: Positive,
600{
601 keys: FieldShareKeys<F, M>,
602 index: usize,
603}
604
605impl<F: FieldExtension, M: Positive> Iterator for FieldShareKeysIterator<F, M> {
606 type Item = FieldShareKey<F>;
607
608 fn next(&mut self) -> Option<Self::Item> {
609 if self.index < M::to_usize() {
610 let key = FieldShareKey {
611 alpha: self.keys.alpha.clone(),
612 beta: self.keys.betas[self.index],
613 };
614 self.index += 1;
615 Some(key)
616 } else {
617 None
618 }
619 }
620}
621
622impl<F: FieldExtension, M: Positive> ExactSizeIterator for FieldShareKeysIterator<F, M> {
623 fn len(&self) -> usize {
624 M::to_usize()
625 }
626}
627
628impl<F: FieldExtension, M: Positive> IntoIterator for FieldShareKeys<F, M> {
629 type Item = FieldShareKey<F>;
630 type IntoIter = FieldShareKeysIterator<F, M>;
631
632 fn into_iter(self) -> Self::IntoIter {
633 FieldShareKeysIterator::<F, M> {
634 keys: self,
635 index: 0,
636 }
637 }
638}
639
640pub struct FieldShareKeyRef<'a, F>
641where
642 F: FieldExtension,
643{
644 pub alpha: GlobalFieldKey<F>,
645 pub beta: &'a FieldElement<F>,
646}
647
648impl<'a, F> From<FieldShareKeyRef<'a, F>> for FieldShareKey<F>
649where
650 F: FieldExtension,
651{
652 fn from(val: FieldShareKeyRef<'a, F>) -> Self {
653 FieldShareKey {
654 alpha: val.alpha,
655 beta: *val.beta,
656 }
657 }
658}
659
660pub struct FieldShareKeysRefIterator<'a, F, M>
661where
662 F: FieldExtension,
663 M: Positive,
664{
665 keys: &'a FieldShareKeys<F, M>,
666 index: usize,
667}
668
669impl<F: FieldExtension, M: Positive> ExactSizeIterator for FieldShareKeysRefIterator<'_, F, M> {
670 fn len(&self) -> usize {
671 M::to_usize()
672 }
673}
674
675impl<'a, F: FieldExtension, M: Positive> Iterator for FieldShareKeysRefIterator<'a, F, M> {
676 type Item = FieldShareKeyRef<'a, F>;
677
678 fn next(&mut self) -> Option<Self::Item> {
679 if self.index < M::to_usize() {
680 let key = FieldShareKeyRef {
681 alpha: self.keys.alpha.clone(),
682 beta: &self.keys.betas[self.index],
683 };
684 self.index += 1;
685 Some(key)
686 } else {
687 None
688 }
689 }
690}
691
692impl<'a, F: FieldExtension, M: Positive> IntoIterator for &'a FieldShareKeys<F, M> {
693 type Item = FieldShareKeyRef<'a, F>;
694 type IntoIter = FieldShareKeysRefIterator<'a, F, M>;
695
696 fn into_iter(self) -> Self::IntoIter {
697 FieldShareKeysRefIterator {
698 keys: self,
699 index: 0,
700 }
701 }
702}
703
704#[cfg(test)]
705mod tests {
706 use typenum::U10;
707
708 use super::*;
709 use crate::algebra::elliptic_curve::{Curve25519Ristretto as C, ScalarAsExtension};
710
711 pub type FrExt = ScalarAsExtension<C>;
712
713 #[test]
714 fn test_addition() {
715 let alpha = GlobalFieldKey::new(FrExt::from(3u32));
716 let key1 = FieldShareKeys {
717 alpha: alpha.clone(),
718 betas: HeapArray::<_, U10>::from_fn(|_| FrExt::from(10u32)),
719 };
720 let key2 = FieldShareKeys {
721 alpha: alpha.clone(),
722 betas: HeapArray::<_, U10>::from_fn(|_| FrExt::from(7u32)),
723 };
724 let expected_result = FieldShareKeys {
725 alpha,
726 betas: HeapArray::<_, U10>::from_fn(|_| FrExt::from(17u32)),
727 };
728 assert_eq!(key1 + key2, expected_result);
729 }
730
731 #[test]
732 fn test_subtraction() {
733 let alpha = GlobalFieldKey::new(FrExt::from(3u32));
734 let key1 = FieldShareKeys {
735 alpha: alpha.clone(),
736 betas: HeapArray::<_, U10>::from_fn(|_| FrExt::from(10u32)),
737 };
738 let key2 = FieldShareKeys {
739 alpha: alpha.clone(),
740 betas: HeapArray::<_, U10>::from_fn(|_| FrExt::from(7u32)),
741 };
742 let expected_result = FieldShareKeys {
743 alpha,
744 betas: HeapArray::<_, U10>::from_fn(|_| FrExt::from(3u32)),
745 };
746 assert_eq!(key1 - key2, expected_result);
747 }
748
749 #[test]
750 fn test_multiplication() {
751 let alpha = GlobalFieldKey::new(FrExt::from(3u32));
752 let key = FieldShareKeys {
753 alpha: alpha.clone(),
754 betas: HeapArray::<_, U10>::from_fn(|_| FrExt::from(10u32)),
755 };
756 let scalar = FrExt::from(3u32);
757 let expected_result = FieldShareKeys {
758 alpha,
759 betas: HeapArray::<_, U10>::from_fn(|_| FrExt::from(30u32)),
760 };
761 assert_eq!(key * scalar, expected_result);
762 }
763
764 #[test]
765 fn test_negation() {
766 let key = FieldShareKeys {
767 alpha: GlobalFieldKey::new(FrExt::from(5u32)),
768 betas: HeapArray::<_, U10>::from_fn(|_| FrExt::from(10u32)),
769 };
770 let expected_result = FieldShareKeys {
771 alpha: GlobalFieldKey::new(FrExt::from(5u32)),
772 betas: -HeapArray::<_, U10>::from_fn(|_| FrExt::from(10u32)),
773 };
774 assert_eq!(-key, expected_result);
775 }
776}