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::{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}