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