arnaucube
arnaucube/phantom-zonePublic Self-hosted repository
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        ntt::NttBackendU64,
 15        random::DefaultSecureRng,
 16    };
 17
 18    #[test]
 19    fn mp_noise() {
 20        // set_parameter_set(&SMALL_MP_BOOL_PARAMS);
 21        let mut evaluator = BoolEvaluator::<
 22            Vec<Vec<u64>>,
 23            NttBackendU64,
 24            ModularOpsU64<CiphertextModulus<u64>>,
 25            ModulusPowerOf2<CiphertextModulus<u64>>,
 26            ShoupServerKeyEvaluationDomain<Vec<Vec<u64>>>,
 27        >::new(SMALL_MP_BOOL_PARAMS);
 28
 29        let parties = 2;
 30
 31        let mut rng = DefaultSecureRng::new();
 32        let mut pk_cr_seed = [0u8; 32];
 33        let mut bk_cr_seed = [0u8; 32];
 34        rng.fill_bytes(&mut pk_cr_seed);
 35        rng.fill_bytes(&mut bk_cr_seed);
 36
 37        let cks = (0..parties)
 38            .into_iter()
 39            .map(|_| evaluator.client_key())
 40            .collect_vec();
 41
 42        // construct ideal rlwe sk for meauring noise
 43        let mut ideal_rlwe_sk = vec![0i32; evaluator.parameters().rlwe_n().0];
 44        cks.iter().for_each(|k| {
 45            izip!(
 46                ideal_rlwe_sk.iter_mut(),
 47                InteractiveMultiPartyClientKey::sk_rlwe(k)
 48            )
 49            .for_each(|(ideal_i, s_i)| {
 50                *ideal_i = *ideal_i + s_i;
 51            });
 52        });
 53        let mut ideal_lwe_sk = vec![0i32; evaluator.parameters().lwe_n().0];
 54        cks.iter().for_each(|k| {
 55            izip!(
 56                ideal_lwe_sk.iter_mut(),
 57                InteractiveMultiPartyClientKey::sk_lwe(k)
 58            )
 59            .for_each(|(ideal_i, s_i)| {
 60                *ideal_i = *ideal_i + s_i;
 61            });
 62        });
 63
 64        // round 1
 65        let pk_shares = cks
 66            .iter()
 67            .map(|c| evaluator.multi_party_public_key_share(pk_cr_seed, c))
 68            .collect_vec();
 69
 70        // public key
 71        let pk = PublicKey::<Vec<Vec<u64>>, DefaultSecureRng, ModularOpsU64<CiphertextModulus<u64>>>::from(
 72            pk_shares.as_slice(),
 73        );
 74
 75        // round 2
 76        let server_key_shares = cks
 77            .iter()
 78            .map(|c| evaluator.multi_party_server_key_share(bk_cr_seed, &pk.key(), c))
 79            .collect_vec();
 80
 81        let server_key = evaluator.aggregate_multi_party_server_key_shares(&server_key_shares);
 82        let runtime_server_key = ShoupServerKeyEvaluationDomain::from(ServerKeyEvaluationDomain::<
 83            _,
 84            _,
 85            DefaultSecureRng,
 86            NttBackendU64,
 87        >::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, &runtime_server_key);
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}