phantom-zone/src/noise.rs
src/noise.rsRaw
1// #[cfg(test)]
2// mod tests {
3// use itertools::{izip, Itertools};
4// use num_traits::zero;
5// use rand::{thread_rng, Rng};
6
7// use crate::{
8// bool::keys::ClientKey,
9// ntt,
10// random::{
11// DefaultSecureRng, RandomFill, RandomFillGaussianInModulus,
12// RandomFillUniformInModulus, },
13// utils::{
14// fill_random_ternary_secret_with_hamming_weight, generate_prime,
15// Stats, TryConvertFrom1, },
16// ArithmeticOps, Decomposer, DefaultDecomposer, ModInit, ModularOpsU64,
17// Ntt, NttBackendU64, NttInit, VectorOps,
18// };
19
20// #[test]
21// fn non_interactive_multi_party() {
22// let logq = 56;
23// let ring_size = 1usize << 11;
24// let q = generate_prime(logq, 2 * ring_size as u64, 1 <<
25// logq).unwrap(); let logb = 1;
26// let d = 56;
27// let decomposer = DefaultDecomposer::new(q, logb, d);
28// let gadget_vec = decomposer.gadget_vector();
29// let mut rng = DefaultSecureRng::new();
30
31// let modop = ModularOpsU64::new(q);
32// let nttop = NttBackendU64::new(&q, ring_size);
33
34// let no_of_parties = 16;
35// let client_secrets = (0..no_of_parties)
36// .into_iter()
37// .map(|_| {
38// let mut sk = vec![0i64; ring_size];
39// fill_random_ternary_secret_with_hamming_weight(&mut sk,
40// ring_size >> 1, &mut rng); sk
41// })
42// .collect_vec();
43
44// let mut s_ideal = vec![0i64; ring_size];
45// client_secrets.iter().for_each(|s| {
46// izip!(s_ideal.iter_mut(), s.iter()).for_each(|(add_to, v)| {
47// *add_to = *add_to + *v;
48// });
49// });
50
51// let sk_poly_ideal = Vec::<u64>::try_convert_from(s_ideal.as_slice(),
52// &q); let mut sk_poly_ideal_eval = sk_poly_ideal.clone();
53// nttop.forward(&mut sk_poly_ideal_eval);
54
55// let mut ksk_seed = [0u8; 32];
56// rng.fill_bytes(&mut ksk_seed);
57
58// // zero encryptions for each party for ksk(u)
59// let client_zero_encs = {
60// client_secrets
61// .iter()
62// .map(|sk| {
63// let sk_poly = Vec::<u64>::try_convert_from(sk.as_slice(),
64// &q); let mut sk_poly_eval = sk_poly.clone();
65// nttop.forward(sk_poly_eval.as_mut_slice());
66
67// let mut zero_encs =
68// vec![vec![0u64; ring_size];
69// decomposer.decomposition_count()]; let mut ksk_prng =
70// DefaultSecureRng::new_seeded(ksk_seed);
71// zero_encs.iter_mut().for_each(|out| {
72// RandomFillUniformInModulus::random_fill( &mut
73// ksk_prng, &q,
74// out.as_mut_slice(),
75// );
76// nttop.forward(out.as_mut_slice());
77// modop.elwise_mul_mut(out.as_mut_slice(),
78// &sk_poly_eval); nttop.backward(out.as_mut_slice());
79
80// let mut error = vec![0u64; ring_size];
81// RandomFillGaussianInModulus::random_fill(&mut rng,
82// &q, &mut error);
83
84// modop.elwise_add_mut(out.as_mut_slice(), &error);
85// });
86// zero_encs
87// })
88// .collect_vec()
89// };
90
91// // main values
92// let main_a = {
93// let mut a = vec![0u64; ring_size];
94// RandomFillUniformInModulus::random_fill(&mut rng, &q, &mut a);
95// a
96// };
97// let main_m = {
98// let mut main_m = vec![0u64; ring_size];
99// RandomFillUniformInModulus::random_fill(&mut rng, &q, &mut
100// main_m); main_m
101// };
102
103// let mut main_u = vec![0i64; ring_size];
104// fill_random_ternary_secret_with_hamming_weight(&mut main_u, ring_size
105// >> 1, &mut rng); let u_main_poly =
106// Vec::<u64>::try_convert_from(main_u.as_slice(), &q); let mut
107// u_main_poly_eval = u_main_poly.clone(); nttop.
108// forward(u_main_poly_eval.as_mut_slice());
109
110// // party 0
111// let (mut party0_ksk_u, mut rlwe_main_m_parta) = {
112// // party 0's secret
113// let sk = client_secrets[0].clone();
114// let sk_poly = Vec::<u64>::try_convert_from(sk.as_slice(), &q);
115// let mut sk_poly_eval = sk_poly.clone();
116// nttop.forward(sk_poly_eval.as_mut_slice());
117
118// // `main_a*u + main_m` with ephemeral key u
119// let mut rlwe_main_m = main_a.clone();
120// nttop.forward(&mut rlwe_main_m);
121// modop.elwise_mul_mut(&mut rlwe_main_m, &u_main_poly_eval);
122// nttop.backward(&mut rlwe_main_m);
123// let mut error = vec![0u64; ring_size];
124// RandomFillGaussianInModulus::random_fill(&mut rng, &q, &mut
125// error); modop.elwise_add_mut(&mut rlwe_main_m, &error);
126// modop.elwise_add_mut(&mut rlwe_main_m, &main_m);
127
128// // Generate KSK(u)
129// let mut ksk_prng = DefaultSecureRng::new_seeded(ksk_seed);
130// let mut ksk_u = vec![vec![0u64; ring_size]; 2 *
131// decomposer.decomposition_count()]; let (ksk_u_a, ksk_u_b) =
132// ksk_u.split_at_mut(decomposer.decomposition_count());
133// izip!(ksk_u_b.iter_mut(), ksk_u_a.iter_mut(), gadget_vec.iter()).for_each( |(row_b, row_a, beta_i)| {
134// // sample a
135// RandomFillUniformInModulus::random_fill(&mut ksk_prng,
136// &q, row_a.as_mut());
137
138// // s_i * a
139// let mut s_i_a = row_a.clone();
140// nttop.forward(&mut s_i_a);
141// modop.elwise_mul_mut(&mut s_i_a, &sk_poly_eval);
142// nttop.backward(&mut s_i_a);
143
144// // \beta * u
145// let mut beta_u = u_main_poly.clone();
146// modop.elwise_scalar_mul_mut(beta_u.as_mut_slice(),
147// beta_i);
148
149// // e
150// RandomFillGaussianInModulus::random_fill(&mut rng, &q,
151// row_b.as_mut_slice()); // e + \beta * u
152// modop.elwise_add_mut(row_b.as_mut_slice(), &beta_u);
153
154// // b = e + \beta * u + a * s_i
155// modop.elwise_add_mut(row_b.as_mut_slice(), &s_i_a);
156// },
157// );
158
159// // send ksk u from s_0 to s_{ideal}
160// ksk_u_b.iter_mut().enumerate().for_each(|(index, out_b)| {
161// // note: skip zero encryption of party 0
162// client_zero_encs.iter().skip(1).for_each(|encs| {
163// modop.elwise_add_mut(out_b, &encs[index]);
164// });
165// });
166
167// // // put ksk in fourier domain
168// // ksk_u
169// // .iter_mut()
170// // .for_each(|r| nttop.forward(r.as_mut_slice()));
171// (ksk_u, rlwe_main_m)
172// };
173
174// // Check ksk_u is correct
175// // {
176// // let (ksk_a, ksk_b) =
177// // party0_ksk_u.split_at_mut(decomposer.decomposition_count());
178// // izip!(
179// // ksk_a.iter(),
180// // ksk_b.iter(),
181// // decomposer.gadget_vector().iter()
182// // )
183// // .for_each(|(row_a, row_b, beta_i)| {
184// // // a * s
185// // let mut sa = row_a.clone();
186// // nttop.forward(&mut sa);
187// // modop.elwise_mul_mut(&mut sa, &sk_poly_ideal_eval);
188// // nttop.backward(&mut sa);
189
190// // // b - a*s
191// // let mut out = sa;
192// // modop.elwise_neg_mut(&mut out);
193// // modop.elwise_add_mut(&mut out, row_b);
194
195// // // beta * u
196// // let mut expected = u_main_poly.clone();
197// // modop.elwise_scalar_mul_mut(&mut expected, beta_i);
198// // assert_eq!(expected, out);
199// // });
200// // }
201
202// // RLWE(0) = main_a * s + e = \sum main_a*s_i + e_i
203// let rlwe_to_switch = {
204// let mut sum = vec![0u64; ring_size];
205// client_secrets.iter().for_each(|sk| {
206// let sk_poly = Vec::<u64>::try_convert_from(sk.as_slice(),
207// &q); let mut sk_poly_eval = sk_poly.clone();
208// nttop.forward(sk_poly_eval.as_mut_slice());
209
210// // a * s
211// let mut rlwe = main_a.clone();
212// nttop.forward(&mut rlwe);
213// modop.elwise_mul_mut(rlwe.as_mut_slice(), &sk_poly_eval);
214// nttop.backward(&mut rlwe);
215// // a * s + e
216// let mut error = vec![0u64; ring_size];
217// RandomFillGaussianInModulus::random_fill(&mut rng, &q, &mut
218// error); modop.elwise_add_mut(&mut rlwe, &error);
219
220// modop.elwise_add_mut(&mut sum, &rlwe);
221// });
222// sum
223// };
224// // {
225// // let mut tmp = main_a.clone();
226// // nttop.forward(&mut tmp);
227// // modop.elwise_mul_mut(&mut tmp, &sk_poly_ideal_eval);
228// // nttop.backward(&mut tmp);
229// // assert_eq!(&rlwe_to_switch, &tmp);
230// // }
231
232// // Key switch \sum decomp<RLWE(0)> * KSK(i)
233// let mut decomp_rlwe = vec![vec![0u64; ring_size];
234// decomposer.decomposition_count()]; rlwe_to_switch.iter().enumerate().
235// for_each(|(ri, el)| { decomposer
236// .decompose_iter(el)
237// .enumerate()
238// .for_each(|(j, d_el)| {
239// decomp_rlwe[j][ri] = d_el;
240// });
241// });
242
243// // put ksk_u and decomp<RLWE(main_a*s_ideal + e)> in fourier domain
244// decomp_rlwe
245// .iter_mut()
246// .for_each(|r| nttop.forward(r.as_mut_slice()));
247// party0_ksk_u
248// .iter_mut()
249// .for_each(|r| nttop.forward(r.as_mut_slice()));
250
251// let (ksk_u_a, ksk_u_b) =
252// party0_ksk_u.split_at(decomposer.decomposition_count()); let mut
253// rlwe_main_m_partb_eval = vec![vec![0u64; ring_size]; 2]; izip!
254// (decomp_rlwe.iter(), ksk_u_a.iter(), ksk_u_b.iter()).for_each(|(o, a, b)| {
255// // A part
256// // rlwe[0] += o*a
257// izip!(rlwe_main_m_partb_eval[0].iter_mut(), o.iter(),
258// a.iter()).for_each( |(r, o, a)| {
259// *r = modop.add(r, &modop.mul(o, a));
260// },
261// );
262
263// // B part
264// // rlwe[1] += o*b
265// izip!(rlwe_main_m_partb_eval[1].iter_mut(), o.iter(),
266// b.iter()).for_each( |(r, o, b)| {
267// *r = modop.add(r, &modop.mul(o, b));
268// },
269// );
270// });
271
272// // construct RLWE_{s_{ideal}}(-sm)
273// nttop.forward(rlwe_main_m_parta.as_mut_slice());
274// modop.elwise_add_mut(&mut rlwe_main_m_partb_eval[0],
275// &rlwe_main_m_parta); let rlwe_main_m_eval = rlwe_main_m_partb_eval;
276
277// // decrypt RLWE_{s_{ideal}}(m) and check
278// let mut neg_s_m_main_out = rlwe_main_m_eval[0].clone();
279// modop.elwise_mul_mut(&mut neg_s_m_main_out, &sk_poly_ideal_eval);
280// modop.elwise_neg_mut(&mut neg_s_m_main_out);
281// modop.elwise_add_mut(&mut neg_s_m_main_out, &rlwe_main_m_eval[1]);
282// nttop.backward(&mut neg_s_m_main_out);
283
284// let mut neg_s_main_m = main_m.clone();
285// nttop.forward(&mut neg_s_main_m);
286// modop.elwise_mul_mut(&mut neg_s_main_m, &sk_poly_ideal_eval);
287// modop.elwise_neg_mut(&mut neg_s_main_m);
288// nttop.backward(&mut neg_s_main_m);
289
290// let mut diff = neg_s_m_main_out.clone();
291// modop.elwise_sub_mut(&mut diff, &neg_s_main_m);
292
293// let mut stat = Stats::new();
294// stat.add_more(&Vec::<i64>::try_convert_from(&diff, &q));
295// println!("Log2 Std: {}", stat.std_dev().abs().log2());
296// }
297// }