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(module, &sk_in, &sk_out, &mut source_xa, &mut source_xe, scratch.borrow());
 70
 71                let max_noise: f64 = SIGMA.log2() - (ksk.k().as_usize() as f64) + 0.5;
 72
 73                for row in 0..ksk.dnum().as_usize() {
 74                    for col in 0..ksk.rank_in().as_usize() {
 75                        let noise_have = ksk
 76                            .key
 77                            .noise(module, row, col, &sk_in.data, &sk_out_prepared, scratch.borrow())
 78                            .std()
 79                            .log2();
 80
 81                        assert!(
 82                            noise_have < max_noise + 0.5,
 83                            "row:{row} col:{col} noise_have:{noise_have} > max_noise:{}",
 84                            max_noise + 0.5
 85                        );
 86                    }
 87                }
 88            }
 89        }
 90    }
 91}
 92
 93pub fn test_gglwe_switching_key_compressed_encrypt_sk<BE: Backend>(module: &Module<BE>)
 94where
 95    Module<BE>: GGLWEEncryptSk<BE>
 96        + GGLWEPreparedFactory<BE>
 97        + GGLWEKeyswitch<BE>
 98        + GLWEDecrypt<BE>
 99        + GLWESecretPreparedFactory<BE>
100        + GLWESwitchingKeyEncryptSk<BE>
101        + GLWESwitchingKeyCompressedEncryptSk<BE>
102        + GLWESwitchingKeyDecompress
103        + GGLWENoise<BE>
104        + VecZnxFillUniform,
105    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
106    Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
107{
108    let n: usize = module.n();
109    let base2k: usize = 12;
110    let k_ksk: usize = 54;
111    let max_dsize: usize = k_ksk / base2k;
112    for rank_in in 1_usize..3 {
113        for rank_out in 1_usize..3 {
114            for dsize in 1_usize..max_dsize {
115                let dnum: usize = (k_ksk - dsize * base2k) / (dsize * base2k);
116
117                let gglwe_infos: GGLWELayout = GGLWELayout {
118                    n: n.into(),
119                    base2k: base2k.into(),
120                    k: k_ksk.into(),
121                    dnum: dnum.into(),
122                    dsize: dsize.into(),
123                    rank_in: rank_in.into(),
124                    rank_out: rank_out.into(),
125                };
126
127                let mut ksk_compressed: GLWESwitchingKeyCompressed<Vec<u8>> =
128                    GLWESwitchingKeyCompressed::alloc_from_infos(&gglwe_infos);
129
130                let mut source_xs: Source = Source::new([0u8; 32]);
131                let mut source_xe: Source = Source::new([0u8; 32]);
132
133                let mut scratch: ScratchOwned<BE> =
134                    ScratchOwned::alloc(GLWESwitchingKeyCompressed::encrypt_sk_tmp_bytes(module, &gglwe_infos));
135
136                let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_in.into());
137                sk_in.fill_ternary_prob(0.5, &mut source_xs);
138
139                let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_out.into());
140                sk_out.fill_ternary_prob(0.5, &mut source_xs);
141                let mut sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank_out.into());
142                sk_out_prepared.prepare(module, &sk_out);
143
144                let seed_xa = [1u8; 32];
145
146                ksk_compressed.encrypt_sk(module, &sk_in, &sk_out, seed_xa, &mut source_xe, scratch.borrow());
147
148                let mut ksk: GLWESwitchingKey<Vec<u8>> = GLWESwitchingKey::alloc_from_infos(&gglwe_infos);
149                ksk.decompress(module, &ksk_compressed);
150
151                let max_noise: f64 = SIGMA.log2() - (ksk.k().as_usize() as f64) + 0.5;
152
153                for row in 0..ksk.dnum().as_usize() {
154                    for col in 0..ksk.rank_in().as_usize() {
155                        let noise_have = ksk
156                            .key
157                            .noise(module, row, col, &sk_in.data, &sk_out_prepared, scratch.borrow())
158                            .std()
159                            .log2();
160
161                        assert!(
162                            noise_have < max_noise + 0.5,
163                            "row:{row} col:{col} noise_have:{noise_have} > max_noise:{}",
164                            max_noise + 0.5
165                        );
166                    }
167                }
168            }
169        }
170    }
171}
172
173pub fn test_gglwe_compressed_encrypt_sk<BE: Backend>(module: &Module<BE>)
174where
175    Module<BE>: GGLWEEncryptSk<BE>
176        + GGLWEPreparedFactory<BE>
177        + GGLWEKeyswitch<BE>
178        + GLWEDecrypt<BE>
179        + GLWESecretPreparedFactory<BE>
180        + GLWESwitchingKeyEncryptSk<BE>
181        + GGLWECompressedEncryptSk<BE>
182        + GLWESwitchingKeyDecompress
183        + GGLWENoise<BE>
184        + VecZnxFillUniform,
185    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
186    Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
187{
188    let n: usize = module.n();
189    let base2k: usize = 12;
190    let k_ksk: usize = 54;
191    let max_dsize: usize = k_ksk / base2k;
192    for rank_in in 1_usize..3 {
193        for rank_out in 1_usize..3 {
194            for dsize in 1_usize..max_dsize + 1 {
195                let dnum: usize = (k_ksk - dsize * base2k) / (dsize * base2k);
196
197                let gglwe_infos: GGLWELayout = GGLWELayout {
198                    n: n.into(),
199                    base2k: base2k.into(),
200                    k: k_ksk.into(),
201                    dnum: dnum.into(),
202                    dsize: dsize.into(),
203                    rank_in: rank_in.into(),
204                    rank_out: rank_out.into(),
205                };
206
207                let mut ksk_compressed: GGLWECompressed<Vec<u8>> = GGLWECompressed::alloc_from_infos(&gglwe_infos);
208
209                let mut source_xs: Source = Source::new([0u8; 32]);
210                let mut source_xe: Source = Source::new([0u8; 32]);
211
212                let mut scratch: ScratchOwned<BE> =
213                    ScratchOwned::alloc(GGLWECompressed::encrypt_sk_tmp_bytes(module, &gglwe_infos));
214
215                let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_in.into());
216                sk_in.fill_ternary_prob(0.5, &mut source_xs);
217
218                let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_out.into());
219                sk_out.fill_ternary_prob(0.5, &mut source_xs);
220                let mut sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank_out.into());
221                sk_out_prepared.prepare(module, &sk_out);
222
223                let seed_xa = [1u8; 32];
224
225                ksk_compressed.encrypt_sk(
226                    module,
227                    &sk_in.data,
228                    &sk_out_prepared,
229                    seed_xa,
230                    &mut source_xe,
231                    scratch.borrow(),
232                );
233
234                let mut ksk: GGLWE<Vec<u8>> = GGLWE::alloc_from_infos(&gglwe_infos);
235                ksk.decompress(module, &ksk_compressed);
236
237                let max_noise: f64 = SIGMA.log2() - (ksk.k().as_usize() as f64) + 0.5;
238
239                for row in 0..ksk.dnum().as_usize() {
240                    for col in 0..ksk.rank_in().as_usize() {
241                        let noise_have = ksk
242                            .noise(module, row, col, &sk_in.data, &sk_out_prepared, scratch.borrow())
243                            .std()
244                            .log2();
245
246                        assert!(
247                            noise_have < max_noise + 0.5,
248                            "row:{row} col:{col} noise_have:{noise_have} > max_noise:{}",
249                            max_noise + 0.5
250                        );
251                    }
252                }
253            }
254        }
255    }
256}