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