phantom-zone/src/bool/noise.rs
src/bool/noise.rsRaw
1mod test {
2 use itertools::{izip, Itertools};
3
4 use crate::{
5 backend::{ModularOpsU64, ModulusPowerOf2},
6 bool::{
7 evaluator::{BoolEncoding, BoolEvaluator, BooleanGates},
8 keys::{
9 InteractiveMultiPartyClientKey, PublicKey, ServerKeyEvaluationDomain,
10 ShoupServerKeyEvaluationDomain,
11 },
12 parameters::{CiphertextModulus, SMALL_MP_BOOL_PARAMS},
13 },
14 evaluator::MultiPartyCrs,
15 ntt::NttBackendU64,
16 random::DefaultSecureRng,
17 };
18
19 #[test]
20 fn mp_noise() {
21 // set_parameter_set(&SMALL_MP_BOOL_PARAMS);
22 let mut evaluator = BoolEvaluator::<
23 Vec<Vec<u64>>,
24 NttBackendU64,
25 ModularOpsU64<CiphertextModulus<u64>>,
26 ModulusPowerOf2<CiphertextModulus<u64>>,
27 ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>,
28 >::new(SMALL_MP_BOOL_PARAMS);
29
30 let parties = 2;
31
32 let cr_seed = MultiPartyCrs::random();
33
34 let cks = (0..parties)
35 .into_iter()
36 .map(|_| evaluator.client_key())
37 .collect_vec();
38
39 // construct ideal rlwe sk for meauring noise
40 let mut ideal_rlwe_sk = vec![0i32; evaluator.parameters().rlwe_n().0];
41 cks.iter().for_each(|k| {
42 izip!(
43 ideal_rlwe_sk.iter_mut(),
44 InteractiveMultiPartyClientKey::sk_rlwe(k)
45 )
46 .for_each(|(ideal_i, s_i)| {
47 *ideal_i = *ideal_i + s_i;
48 });
49 });
50 let mut ideal_lwe_sk = vec![0i32; evaluator.parameters().lwe_n().0];
51 cks.iter().for_each(|k| {
52 izip!(
53 ideal_lwe_sk.iter_mut(),
54 InteractiveMultiPartyClientKey::sk_lwe(k)
55 )
56 .for_each(|(ideal_i, s_i)| {
57 *ideal_i = *ideal_i + s_i;
58 });
59 });
60
61 // round 1
62 let pk_shares = cks
63 .iter()
64 .map(|c| evaluator.multi_party_public_key_share(&cr_seed, c))
65 .collect_vec();
66
67 // public key
68 let pk = PublicKey::<Vec<Vec<u64>>, DefaultSecureRng, ModularOpsU64<CiphertextModulus<u64>>>::from(
69 pk_shares.as_slice(),
70 );
71
72 // round 2
73 let server_key_shares = cks
74 .iter()
75 .map(|c| evaluator.multi_party_server_key_share(&cr_seed, &pk.key(), c))
76 .collect_vec();
77
78 let server_key = evaluator.aggregate_multi_party_server_key_shares(&server_key_shares);
79 let runtime_server_key = ShoupServerKeyEvaluationDomain::from(ServerKeyEvaluationDomain::<
80 _,
81 _,
82 DefaultSecureRng,
83 NttBackendU64,
84 >::from(&server_key));
85
86 let mut m0 = false;
87 let mut m1 = true;
88
89 let mut c_m0 = evaluator.pk_encrypt(pk.key(), m0);
90 let mut c_m1 = evaluator.pk_encrypt(pk.key(), m1);
91
92 let true_el_encoded = evaluator.parameters().rlwe_q().true_el();
93 let false_el_encoded = evaluator.parameters().rlwe_q().false_el();
94
95 // let mut stats = Stats::new();
96
97 for _ in 0..1000 {
98 let now = std::time::Instant::now();
99 let c_out = evaluator.xor(&c_m0, &c_m1, &runtime_server_key);
100 println!("Gate time: {:?}", now.elapsed());
101
102 // mp decrypt
103 let decryption_shares = cks
104 .iter()
105 .map(|c| evaluator.multi_party_decryption_share(&c_out, c))
106 .collect_vec();
107 let m_out = evaluator.multi_party_decrypt(&decryption_shares, &c_out);
108 let m_expected = (m0 ^ m1);
109 assert_eq!(m_expected, m_out, "Expected {m_expected} but got {m_out}");
110
111 // // find noise update
112 // {
113 // let out = decrypt_lwe(
114 // &c_out,
115 // ideal_client_key.sk_rlwe().values(),
116 // evaluator.pbs_info().modop_rlweq(),
117 // );
118
119 // let out_want = {
120 // if m_expected == true {
121 // true_el_encoded
122 // } else {
123 // false_el_encoded
124 // }
125 // };
126 // let diff = evaluator.pbs_info().modop_rlweq().sub(&out, &out_want);
127
128 // stats.add_more(&vec![evaluator
129 // .pbs_info()
130 // .rlwe_q()
131 // .map_element_to_i64(&diff)]);
132 // }
133
134 m1 = m0;
135 m0 = m_expected;
136
137 c_m1 = c_m0;
138 c_m0 = c_out;
139 }
140
141 // println!("log2 std dev {}", stats.std_dev().abs().log2());
142 }
143}