1use p256::Scalar;
15
16#[derive(Clone, Debug)]
18pub struct MtaInputs {
19 pub ks: Vec<Scalar>,
20 pub xs: Vec<Scalar>,
21 pub indices: Vec<u64>,
22}
23
24impl MtaInputs {
25 pub fn products(&self) -> (Vec<Vec<Scalar>>, Vec<Vec<Scalar>>) {
29 let n = self.ks.len();
30 let alphas = vec![vec![Scalar::ZERO; n]; n];
31 let mut betas = vec![vec![Scalar::ZERO; n]; n];
32 #[allow(clippy::needless_range_loop)]
35 for i in 0..n {
36 #[allow(clippy::needless_range_loop)]
37 for j in 0..n {
38 if i == j {
39 continue;
40 }
41 betas[j][i] = self.ks[i] * self.xs[j];
42 }
43 }
44 (alphas, betas)
45 }
46}
47
48pub fn party_mta_sum(
51 i: usize,
52 ks: &[Scalar],
53 xs: &[Scalar],
54 alphas: &[Vec<Scalar>],
55 betas: &[Vec<Scalar>],
56) -> Scalar {
57 let n = ks.len();
58 let mut acc = ks[i] * xs[i];
59 for j in 0..n {
60 if j == i {
61 continue;
62 }
63 acc += alphas[j][i];
64 acc += betas[i][j];
65 }
66 acc
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn mta_products_sum_to_ki_xj() {
75 let ks = vec![Scalar::from(2u64), Scalar::from(3u64), Scalar::from(5u64)];
76 let xs = vec![Scalar::from(7u64), Scalar::from(11u64), Scalar::from(13u64)];
77 let inputs = MtaInputs {
78 ks: ks.clone(),
79 xs: xs.clone(),
80 indices: vec![1, 2, 3],
81 };
82 let (alphas, betas) = inputs.products();
83 for i in 0..3 {
84 for j in 0..3 {
85 if i == j {
86 continue;
87 }
88 let sum = alphas[i][j] + betas[j][i];
89 assert_eq!(sum, ks[i] * xs[j], "pair ({}, {})", i, j);
90 }
91 }
92 }
93
94 #[test]
95 fn party_mta_sum_matches_xi_sum_kj() {
96 let ks = vec![Scalar::from(2u64), Scalar::from(3u64), Scalar::from(5u64)];
97 let xs = vec![Scalar::from(7u64), Scalar::from(11u64), Scalar::from(13u64)];
98 let inputs = MtaInputs {
99 ks: ks.clone(),
100 xs: xs.clone(),
101 indices: vec![1, 2, 3],
102 };
103 let (alphas, betas) = inputs.products();
104 let k_sum: Scalar = ks.iter().copied().fold(Scalar::ZERO, |a, b| a + b);
105 for i in 0..3 {
106 let got = party_mta_sum(i, &ks, &xs, &alphas, &betas);
107 assert_eq!(got, xs[i] * k_sum, "party {}", i);
108 }
109 }
110}