arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/noise/gglwe_ct.rs
poulpy-core/src/noise/gglwe_ct.rsRaw
 1use poulpy_hal::{
 2    api::{ScratchAvailable, ScratchOwnedAlloc, ScratchOwnedBorrow, ScratchTakeBasic, VecZnxFillUniform, VecZnxSubScalarInplace},
 3    layouts::{Backend, DataRef, Module, ScalarZnx, ScalarZnxToRef, Scratch, ScratchOwned, ZnxZero},
 4};
 5
 6use crate::decryption::GLWEDecrypt;
 7use crate::layouts::{
 8    GGLWE, GGLWEInfos, GGLWEToRef, GLWEPlaintext, LWEInfos,
 9    prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
10};
11
12impl<D: DataRef> GGLWE<D> {
13    pub fn assert_noise<M, DataSk, DataWant, BE: Backend>(
14        &self,
15        module: &M,
16        sk_prepared: &GLWESecretPrepared<DataSk, BE>,
17        pt_want: &ScalarZnx<DataWant>,
18        max_noise: f64,
19    ) where
20        DataSk: DataRef,
21        DataWant: DataRef,
22        M: GGLWENoise<BE>,
23        Scratch<BE>: ScratchTakeBasic,
24    {
25        module.gglwe_assert_noise(self, sk_prepared, pt_want, max_noise);
26    }
27
28
29}
30
31pub trait GGLWENoise<BE: Backend> {
32    fn gglwe_assert_noise<R, S, P>(&self, res: &R, sk_prepared: &S, pt_want: &P, max_noise: f64)
33    where
34        R: GGLWEToRef,
35        S: GLWESecretPreparedToRef<BE>,
36        P: ScalarZnxToRef,
37        Scratch<BE>: ScratchTakeBasic;    
38}
39
40impl<BE: Backend> GGLWENoise<BE> for Module<BE>
41where
42    Module<BE>: GLWEDecrypt<BE> + VecZnxFillUniform + VecZnxSubScalarInplace,
43    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
44    Scratch<BE>: ScratchAvailable + ScratchTakeBasic,
45{
46    fn gglwe_assert_noise<R, S, P>(&self, res: &R, sk_prepared: &S, pt_want: &P, max_noise: f64)
47    where
48        R: GGLWEToRef,
49        S: GLWESecretPreparedToRef<BE>,
50        P: ScalarZnxToRef,
51        ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
52        Scratch<BE>: ScratchAvailable + ScratchTakeBasic,        
53    {
54        let res: &GGLWE<&[u8]> = &res.to_ref();
55
56        let dsize: usize = res.dsize().into();
57        let base2k: usize = res.base2k().into();
58
59        let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(self.glwe_decrypt_tmp_bytes(res));
60        let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(self, res);
61
62        (0..res.rank_in().into()).for_each(|col_i| {
63            (0..res.dnum().into()).for_each(|row_i| {
64                self.glwe_decrypt(
65                    &res.at(row_i, col_i),
66                    &mut pt,
67                    sk_prepared,
68                    scratch.borrow(),
69                );
70
71                self.vec_znx_sub_scalar_inplace(&mut pt.data, 0, (dsize - 1) + row_i * dsize, pt_want, col_i);
72
73                let noise_have: f64 = pt.data.std(base2k, 0).log2();
74
75                // println!("noise_have: {noise_have}");
76
77                assert!(
78                    noise_have <= max_noise,
79                    "noise_have: {noise_have} > max_noise: {max_noise}"
80                );
81
82                pt.data.zero();
83            });
84        });
85    }
86}