phantom-zone/src/bool/noise.rs
src/bool/noise.rsRaw
1use std::cell::RefCell;
2
3mod test {
4 use itertools::{izip, Itertools};
5
6 use crate::{
7 backend::{ArithmeticOps, ModularOpsU64, Modulus},
8 bool::{
9 set_parameter_set, BoolEncoding, BoolEvaluator, BooleanGates, CiphertextModulus,
10 ClientKey, PublicKey, ServerKeyEvaluationDomain, MP_BOOL_PARAMS, SMALL_MP_BOOL_PARAMS,
11 },
12 lwe::{decrypt_lwe, LweSecret},
13 ntt::NttBackendU64,
14 pbs::PbsInfo,
15 random::DefaultSecureRng,
16 rgsw::RlweSecret,
17 utils::Stats,
18 Secret,
19 };
20
21 #[test]
22 fn mp_noise() {
23 // set_parameter_set(&SMALL_MP_BOOL_PARAMS);
24 let mut evaluator = BoolEvaluator::<
25 Vec<Vec<u64>>,
26 NttBackendU64,
27 ModularOpsU64<CiphertextModulus<u64>>,
28 ModularOpsU64<CiphertextModulus<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 server_key_eval_domain = ServerKeyEvaluationDomain::from(&server_key);
88
89 let mut m0 = false;
90 let mut m1 = true;
91
92 let mut c_m0 = evaluator.pk_encrypt(pk.key(), m0);
93 let mut c_m1 = evaluator.pk_encrypt(pk.key(), m1);
94
95 let true_el_encoded = evaluator.parameters().rlwe_q().true_el();
96 let false_el_encoded = evaluator.parameters().rlwe_q().false_el();
97
98 // let mut stats = Stats::new();
99
100 for _ in 0..1000 {
101 let now = std::time::Instant::now();
102 let c_out = evaluator.xor(&c_m0, &c_m1, &server_key_eval_domain);
103 println!("Gate time: {:?}", now.elapsed());
104
105 // mp decrypt
106 // let decryption_shares = cks
107 // .iter()
108 // .map(|c| evaluator.multi_party_decryption_share(&c_out, c))
109 // .collect_vec();
110 // let m_out = evaluator.multi_party_decrypt(&decryption_shares, &c_out);
111 let m_expected = (m0 ^ m1);
112 // assert_eq!(m_expected, m_out, "Expected {m_expected} but got {m_out}");
113
114 // // find noise update
115 // {
116 // let out = decrypt_lwe(
117 // &c_out,
118 // ideal_client_key.sk_rlwe().values(),
119 // evaluator.pbs_info().modop_rlweq(),
120 // );
121
122 // let out_want = {
123 // if m_expected == true {
124 // true_el_encoded
125 // } else {
126 // false_el_encoded
127 // }
128 // };
129 // let diff = evaluator.pbs_info().modop_rlweq().sub(&out, &out_want);
130
131 // stats.add_more(&vec![evaluator
132 // .pbs_info()
133 // .rlwe_q()
134 // .map_element_to_i64(&diff)]);
135 // }
136
137 m1 = m0;
138 m0 = m_expected;
139
140 c_m1 = c_m0;
141 c_m0 = c_out;
142 }
143
144 // println!("log2 std dev {}", stats.std_dev().abs().log2());
145 }
146}