arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/noise/ggsw_ct.rs
poulpy-core/src/noise/ggsw_ct.rsRaw
  1use poulpy_hal::{
  2    api::{
  3        ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDftInplace, VecZnxAddScalarInplace, VecZnxBigAddInplace,
  4        VecZnxBigAddSmallInplace, VecZnxBigAlloc, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes,
  5        VecZnxDftAlloc, VecZnxDftApply, VecZnxDftBytesOf, VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, VecZnxNormalizeTmpBytes,
  6        VecZnxSubInplace,
  7    },
  8    layouts::{Backend, DataRef, Module, ScalarZnx, ScratchOwned, VecZnxBig, VecZnxDft, ZnxZero},
  9    oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl},
 10};
 11
 12use crate::layouts::{GGSW, GGSWInfos, GLWE, GLWEInfos, GLWEPlaintext, LWEInfos, prepared::GLWESecretPrepared};
 13
 14impl<D: DataRef> GGSW<D> {
 15    pub fn assert_noise<B, DataSk, DataScalar, F>(
 16        &self,
 17        module: &Module<B>,
 18        sk_prepared: &GLWESecretPrepared<DataSk, B>,
 19        pt_want: &ScalarZnx<DataScalar>,
 20        max_noise: F,
 21    ) where
 22        DataSk: DataRef,
 23        DataScalar: DataRef,
 24        Module<B>: VecZnxDftBytesOf
 25            + VecZnxBigBytesOf
 26            + VecZnxDftApply<B>
 27            + SvpApplyDftToDftInplace<B>
 28            + VecZnxIdftApplyConsume<B>
 29            + VecZnxBigAddInplace<B>
 30            + VecZnxBigAddSmallInplace<B>
 31            + VecZnxBigNormalize<B>
 32            + VecZnxNormalizeTmpBytes
 33            + VecZnxBigAlloc<B>
 34            + VecZnxDftAlloc<B>
 35            + VecZnxBigNormalizeTmpBytes
 36            + VecZnxIdftApplyTmpA<B>
 37            + VecZnxAddScalarInplace
 38            + VecZnxSubInplace,
 39        B: Backend + ScratchOwnedAllocImpl<B> + ScratchOwnedBorrowImpl<B>,
 40        F: Fn(usize) -> f64,
 41    {
 42        let base2k: usize = self.base2k().into();
 43        let dsize: usize = self.dsize().into();
 44
 45        let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(module, self);
 46        let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(module, self);
 47        let mut pt_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(1, self.size());
 48        let mut pt_big: VecZnxBig<Vec<u8>, B> = module.vec_znx_big_alloc(1, self.size());
 49
 50        let mut scratch: ScratchOwned<B> =
 51            ScratchOwned::alloc(GLWE::decrypt_tmp_bytes(module, self) | module.vec_znx_normalize_tmp_bytes());
 52
 53        (0..(self.rank() + 1).into()).for_each(|col_j| {
 54            (0..self.dnum().into()).for_each(|row_i| {
 55                module.vec_znx_add_scalar_inplace(&mut pt.data, 0, (dsize - 1) + row_i * dsize, pt_want, 0);
 56
 57                // mul with sk[col_j-1]
 58                if col_j > 0 {
 59                    module.vec_znx_dft_apply(1, 0, &mut pt_dft, 0, &pt.data, 0);
 60                    module.svp_apply_dft_to_dft_inplace(&mut pt_dft, 0, &sk_prepared.data, col_j - 1);
 61                    module.vec_znx_idft_apply_tmpa(&mut pt_big, 0, &mut pt_dft, 0);
 62                    module.vec_znx_big_normalize(
 63                        base2k,
 64                        &mut pt.data,
 65                        0,
 66                        base2k,
 67                        &pt_big,
 68                        0,
 69                        scratch.borrow(),
 70                    );
 71                }
 72
 73                self.at(row_i, col_j)
 74                    .decrypt(module, &mut pt_have, sk_prepared, scratch.borrow());
 75
 76                module.vec_znx_sub_inplace(&mut pt_have.data, 0, &pt.data, 0);
 77
 78                let std_pt: f64 = pt_have.data.std(base2k, 0).log2();
 79                let noise: f64 = max_noise(col_j);
 80                assert!(std_pt <= noise, "{std_pt} > {noise}");
 81
 82                pt.data.zero();
 83            });
 84        });
 85    }
 86}
 87
 88impl<D: DataRef> GGSW<D> {
 89    pub fn print_noise<B, DataSk, DataScalar>(
 90        &self,
 91        module: &Module<B>,
 92        sk_prepared: &GLWESecretPrepared<DataSk, B>,
 93        pt_want: &ScalarZnx<DataScalar>,
 94    ) where
 95        DataSk: DataRef,
 96        DataScalar: DataRef,
 97        Module<B>: VecZnxDftBytesOf
 98            + VecZnxBigBytesOf
 99            + VecZnxDftApply<B>
100            + SvpApplyDftToDftInplace<B>
101            + VecZnxIdftApplyConsume<B>
102            + VecZnxBigAddInplace<B>
103            + VecZnxBigAddSmallInplace<B>
104            + VecZnxBigNormalize<B>
105            + VecZnxNormalizeTmpBytes
106            + VecZnxBigAlloc<B>
107            + VecZnxDftAlloc<B>
108            + VecZnxBigNormalizeTmpBytes
109            + VecZnxIdftApplyTmpA<B>
110            + VecZnxAddScalarInplace
111            + VecZnxSubInplace,
112        B: Backend + ScratchOwnedAllocImpl<B> + ScratchOwnedBorrowImpl<B>,
113    {
114        let base2k: usize = self.base2k().into();
115        let dsize: usize = self.dsize().into();
116
117        let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(module, self);
118        let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(module, self);
119        let mut pt_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(1, self.size());
120        let mut pt_big: VecZnxBig<Vec<u8>, B> = module.vec_znx_big_alloc(1, self.size());
121
122        let mut scratch: ScratchOwned<B> =
123            ScratchOwned::alloc(GLWE::decrypt_tmp_bytes(module, self) | module.vec_znx_normalize_tmp_bytes());
124
125        (0..(self.rank() + 1).into()).for_each(|col_j| {
126            (0..self.dnum().into()).for_each(|row_i| {
127                module.vec_znx_add_scalar_inplace(&mut pt.data, 0, (dsize - 1) + row_i * dsize, pt_want, 0);
128
129                // mul with sk[col_j-1]
130                if col_j > 0 {
131                    module.vec_znx_dft_apply(1, 0, &mut pt_dft, 0, &pt.data, 0);
132                    module.svp_apply_dft_to_dft_inplace(&mut pt_dft, 0, &sk_prepared.data, col_j - 1);
133                    module.vec_znx_idft_apply_tmpa(&mut pt_big, 0, &mut pt_dft, 0);
134                    module.vec_znx_big_normalize(
135                        base2k,
136                        &mut pt.data,
137                        0,
138                        base2k,
139                        &pt_big,
140                        0,
141                        scratch.borrow(),
142                    );
143                }
144
145                self.at(row_i, col_j)
146                    .decrypt(module, &mut pt_have, sk_prepared, scratch.borrow());
147                module.vec_znx_sub_inplace(&mut pt_have.data, 0, &pt.data, 0);
148
149                let std_pt: f64 = pt_have.data.std(base2k, 0).log2();
150                println!("col: {col_j} row: {row_i}: {std_pt}");
151                pt.data.zero();
152                // println!(">>>>>>>>>>>>>>>>");
153            });
154        });
155    }
156}