arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/tests/test_suite/encryption/gglwe_ct.rs
poulpy-core/src/tests/test_suite/encryption/gglwe_ct.rsRaw
  1use poulpy_hal::{
  2    api::{ScratchAvailable, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxFillUniform},
  3    layouts::{Backend, Module, Scratch, ScratchOwned},
  4    source::Source,
  5};
  6
  7use crate::{
  8    GGLWECompressedEncryptSk, GGLWEEncryptSk, GGLWEKeyswitch, GLWESwitchingKeyCompressedEncryptSk, GLWESwitchingKeyEncryptSk,
  9    ScratchTakeCore,
 10    decryption::GLWEDecrypt,
 11    encryption::SIGMA,
 12    layouts::{
 13        GGLWE, GGLWECompressed, GGLWEInfos, GGLWELayout, GLWESecret, GLWESecretPreparedFactory, GLWESwitchingKey,
 14        GLWESwitchingKeyCompressed, GLWESwitchingKeyDecompress, LWEInfos,
 15        prepared::{GGLWEPreparedFactory, GLWESecretPrepared},
 16    },
 17    noise::GGLWENoise,
 18};
 19
 20pub fn test_gglwe_switching_key_encrypt_sk<BE: Backend>(module: &Module<BE>)
 21where
 22    Module<BE>: GGLWEEncryptSk<BE>
 23        + GGLWEPreparedFactory<BE>
 24        + GGLWEKeyswitch<BE>
 25        + GLWEDecrypt<BE>
 26        + GLWESecretPreparedFactory<BE>
 27        + GLWESwitchingKeyEncryptSk<BE>
 28        + VecZnxFillUniform
 29        + GGLWENoise<BE>,
 30    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
 31    Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
 32{
 33    let n: usize = module.n();
 34    let base2k: usize = 12;
 35    let k_ksk: usize = 54;
 36    let dsize: usize = k_ksk / base2k;
 37    for rank_in in 1_usize..3 {
 38        for rank_out in 1_usize..3 {
 39            for di in 1_usize..dsize + 1 {
 40                let dnum: usize = (k_ksk - di * base2k) / (di * base2k);
 41
 42                let gglwe_infos: GGLWELayout = GGLWELayout {
 43                    n: n.into(),
 44                    base2k: base2k.into(),
 45                    k: k_ksk.into(),
 46                    dnum: dnum.into(),
 47                    dsize: di.into(),
 48                    rank_in: rank_in.into(),
 49                    rank_out: rank_out.into(),
 50                };
 51
 52                let mut ksk: GLWESwitchingKey<Vec<u8>> = GLWESwitchingKey::alloc_from_infos(&gglwe_infos);
 53
 54                let mut source_xs: Source = Source::new([0u8; 32]);
 55                let mut source_xe: Source = Source::new([0u8; 32]);
 56                let mut source_xa: Source = Source::new([0u8; 32]);
 57
 58                let mut scratch: ScratchOwned<BE> =
 59                    ScratchOwned::alloc(GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &gglwe_infos));
 60
 61                let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_in.into());
 62                sk_in.fill_ternary_prob(0.5, &mut source_xs);
 63
 64                let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_out.into());
 65                sk_out.fill_ternary_prob(0.5, &mut source_xs);
 66                let mut sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank_out.into());
 67                sk_out_prepared.prepare(module, &sk_out);
 68
 69                ksk.encrypt_sk(
 70                    module,
 71                    &sk_in,
 72                    &sk_out,
 73                    &mut source_xa,
 74                    &mut source_xe,
 75                    scratch.borrow(),
 76                );
 77
 78                let max_noise: f64 = SIGMA.log2() - (ksk.k().as_usize() as f64) + 0.5;
 79
 80                for row in 0..ksk.dnum().as_usize() {
 81                    for col in 0..ksk.rank_in().as_usize() {
 82                        let noise_have = ksk
 83                            .key
 84                            .noise(
 85                                module,
 86                                row,
 87                                col,
 88                                &sk_in.data,
 89                                &sk_out_prepared,
 90                                scratch.borrow(),
 91                            )
 92                            .std()
 93                            .log2();
 94
 95                        assert!(
 96                            noise_have < max_noise + 0.5,
 97                            "row:{row} col:{col} noise_have:{noise_have} > max_noise:{}",
 98                            max_noise + 0.5
 99                        );
100                    }
101                }
102            }
103        }
104    }
105}
106
107pub fn test_gglwe_switching_key_compressed_encrypt_sk<BE: Backend>(module: &Module<BE>)
108where
109    Module<BE>: GGLWEEncryptSk<BE>
110        + GGLWEPreparedFactory<BE>
111        + GGLWEKeyswitch<BE>
112        + GLWEDecrypt<BE>
113        + GLWESecretPreparedFactory<BE>
114        + GLWESwitchingKeyEncryptSk<BE>
115        + GLWESwitchingKeyCompressedEncryptSk<BE>
116        + GLWESwitchingKeyDecompress
117        + GGLWENoise<BE>
118        + VecZnxFillUniform,
119    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
120    Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
121{
122    let n: usize = module.n();
123    let base2k: usize = 12;
124    let k_ksk: usize = 54;
125    let max_dsize: usize = k_ksk / base2k;
126    for rank_in in 1_usize..3 {
127        for rank_out in 1_usize..3 {
128            for dsize in 1_usize..max_dsize {
129                let dnum: usize = (k_ksk - dsize * base2k) / (dsize * base2k);
130
131                let gglwe_infos: GGLWELayout = GGLWELayout {
132                    n: n.into(),
133                    base2k: base2k.into(),
134                    k: k_ksk.into(),
135                    dnum: dnum.into(),
136                    dsize: dsize.into(),
137                    rank_in: rank_in.into(),
138                    rank_out: rank_out.into(),
139                };
140
141                let mut ksk_compressed: GLWESwitchingKeyCompressed<Vec<u8>> =
142                    GLWESwitchingKeyCompressed::alloc_from_infos(&gglwe_infos);
143
144                let mut source_xs: Source = Source::new([0u8; 32]);
145                let mut source_xe: Source = Source::new([0u8; 32]);
146
147                let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(GLWESwitchingKeyCompressed::encrypt_sk_tmp_bytes(
148                    module,
149                    &gglwe_infos,
150                ));
151
152                let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_in.into());
153                sk_in.fill_ternary_prob(0.5, &mut source_xs);
154
155                let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_out.into());
156                sk_out.fill_ternary_prob(0.5, &mut source_xs);
157                let mut sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank_out.into());
158                sk_out_prepared.prepare(module, &sk_out);
159
160                let seed_xa = [1u8; 32];
161
162                ksk_compressed.encrypt_sk(
163                    module,
164                    &sk_in,
165                    &sk_out,
166                    seed_xa,
167                    &mut source_xe,
168                    scratch.borrow(),
169                );
170
171                let mut ksk: GLWESwitchingKey<Vec<u8>> = GLWESwitchingKey::alloc_from_infos(&gglwe_infos);
172                ksk.decompress(module, &ksk_compressed);
173
174                let max_noise: f64 = SIGMA.log2() - (ksk.k().as_usize() as f64) + 0.5;
175
176                for row in 0..ksk.dnum().as_usize() {
177                    for col in 0..ksk.rank_in().as_usize() {
178                        let noise_have = ksk
179                            .key
180                            .noise(
181                                module,
182                                row,
183                                col,
184                                &sk_in.data,
185                                &sk_out_prepared,
186                                scratch.borrow(),
187                            )
188                            .std()
189                            .log2();
190
191                        assert!(
192                            noise_have < max_noise + 0.5,
193                            "row:{row} col:{col} noise_have:{noise_have} > max_noise:{}",
194                            max_noise + 0.5
195                        );
196                    }
197                }
198            }
199        }
200    }
201}
202
203pub fn test_gglwe_compressed_encrypt_sk<BE: Backend>(module: &Module<BE>)
204where
205    Module<BE>: GGLWEEncryptSk<BE>
206        + GGLWEPreparedFactory<BE>
207        + GGLWEKeyswitch<BE>
208        + GLWEDecrypt<BE>
209        + GLWESecretPreparedFactory<BE>
210        + GLWESwitchingKeyEncryptSk<BE>
211        + GGLWECompressedEncryptSk<BE>
212        + GLWESwitchingKeyDecompress
213        + GGLWENoise<BE>
214        + VecZnxFillUniform,
215    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
216    Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
217{
218    let n: usize = module.n();
219    let base2k: usize = 12;
220    let k_ksk: usize = 54;
221    let max_dsize: usize = k_ksk / base2k;
222    for rank_in in 1_usize..3 {
223        for rank_out in 1_usize..3 {
224            for dsize in 1_usize..max_dsize + 1 {
225                let dnum: usize = (k_ksk - dsize * base2k) / (dsize * base2k);
226
227                let gglwe_infos: GGLWELayout = GGLWELayout {
228                    n: n.into(),
229                    base2k: base2k.into(),
230                    k: k_ksk.into(),
231                    dnum: dnum.into(),
232                    dsize: dsize.into(),
233                    rank_in: rank_in.into(),
234                    rank_out: rank_out.into(),
235                };
236
237                let mut ksk_compressed: GGLWECompressed<Vec<u8>> = GGLWECompressed::alloc_from_infos(&gglwe_infos);
238
239                let mut source_xs: Source = Source::new([0u8; 32]);
240                let mut source_xe: Source = Source::new([0u8; 32]);
241
242                let mut scratch: ScratchOwned<BE> =
243                    ScratchOwned::alloc(GGLWECompressed::encrypt_sk_tmp_bytes(module, &gglwe_infos));
244
245                let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_in.into());
246                sk_in.fill_ternary_prob(0.5, &mut source_xs);
247
248                let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_out.into());
249                sk_out.fill_ternary_prob(0.5, &mut source_xs);
250                let mut sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank_out.into());
251                sk_out_prepared.prepare(module, &sk_out);
252
253                let seed_xa = [1u8; 32];
254
255                ksk_compressed.encrypt_sk(
256                    module,
257                    &sk_in.data,
258                    &sk_out_prepared,
259                    seed_xa,
260                    &mut source_xe,
261                    scratch.borrow(),
262                );
263
264                let mut ksk: GGLWE<Vec<u8>> = GGLWE::alloc_from_infos(&gglwe_infos);
265                ksk.decompress(module, &ksk_compressed);
266
267                let max_noise: f64 = SIGMA.log2() - (ksk.k().as_usize() as f64) + 0.5;
268
269                for row in 0..ksk.dnum().as_usize() {
270                    for col in 0..ksk.rank_in().as_usize() {
271                        let noise_have = ksk
272                            .noise(
273                                module,
274                                row,
275                                col,
276                                &sk_in.data,
277                                &sk_out_prepared,
278                                scratch.borrow(),
279                            )
280                            .std()
281                            .log2();
282
283                        assert!(
284                            noise_have < max_noise + 0.5,
285                            "row:{row} col:{col} noise_have:{noise_have} > max_noise:{}",
286                            max_noise + 0.5
287                        );
288                    }
289                }
290            }
291        }
292    }
293}