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    GGLWEEncryptSk, GGLWEKeyswitch, GLWESwitchingKeyCompressedEncryptSk, GLWESwitchingKeyEncryptSk, ScratchTakeCore,
  9    decryption::GLWEDecrypt,
 10    encryption::SIGMA,
 11    layouts::{
 12        GGLWEInfos, GGLWELayout, GLWESecret, GLWESecretPreparedFactory, GLWESwitchingKey, GLWESwitchingKeyCompressed,
 13        GLWESwitchingKeyDecompress, LWEInfos,
 14        prepared::{GGLWEPreparedFactory, GLWESecretPrepared},
 15    },
 16    noise::GGLWENoise,
 17};
 18
 19pub fn test_gglwe_switching_key_encrypt_sk<BE: Backend>(module: &Module<BE>)
 20where
 21    Module<BE>: GGLWEEncryptSk<BE>
 22        + GGLWEPreparedFactory<BE>
 23        + GGLWEKeyswitch<BE>
 24        + GLWEDecrypt<BE>
 25        + GLWESecretPreparedFactory<BE>
 26        + GLWESwitchingKeyEncryptSk<BE>
 27        + VecZnxFillUniform
 28        + GGLWENoise<BE>,
 29    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
 30    Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
 31{
 32    let n: usize = module.n();
 33    let base2k: usize = 12;
 34    let k_ksk: usize = 54;
 35    let dsize: usize = k_ksk / base2k;
 36    for rank_in in 1_usize..3 {
 37        for rank_out in 1_usize..3 {
 38            for di in 1_usize..dsize + 1 {
 39                let dnum: usize = (k_ksk - di * base2k) / (di * base2k);
 40
 41                let gglwe_infos: GGLWELayout = GGLWELayout {
 42                    n: n.into(),
 43                    base2k: base2k.into(),
 44                    k: k_ksk.into(),
 45                    dnum: dnum.into(),
 46                    dsize: di.into(),
 47                    rank_in: rank_in.into(),
 48                    rank_out: rank_out.into(),
 49                };
 50
 51                let mut ksk: GLWESwitchingKey<Vec<u8>> = GLWESwitchingKey::alloc_from_infos(&gglwe_infos);
 52
 53                let mut source_xs: Source = Source::new([0u8; 32]);
 54                let mut source_xe: Source = Source::new([0u8; 32]);
 55                let mut source_xa: Source = Source::new([0u8; 32]);
 56
 57                let mut scratch: ScratchOwned<BE> =
 58                    ScratchOwned::alloc(GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &gglwe_infos));
 59
 60                let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_in.into());
 61                sk_in.fill_ternary_prob(0.5, &mut source_xs);
 62
 63                let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_out.into());
 64                sk_out.fill_ternary_prob(0.5, &mut source_xs);
 65                let mut sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank_out.into());
 66                sk_out_prepared.prepare(module, &sk_out);
 67
 68                ksk.encrypt_sk(
 69                    module,
 70                    &sk_in,
 71                    &sk_out,
 72                    &mut source_xa,
 73                    &mut source_xe,
 74                    scratch.borrow(),
 75                );
 76
 77                let max_noise: f64 = SIGMA.log2() - (ksk.k().as_usize() as f64) + 0.5;
 78
 79                for row in 0..ksk.dnum().as_usize() {
 80                    for col in 0..ksk.rank_in().as_usize() {
 81                        let noise_have = ksk
 82                            .key
 83                            .noise(
 84                                module,
 85                                row,
 86                                col,
 87                                &sk_in.data,
 88                                &sk_out_prepared,
 89                                scratch.borrow(),
 90                            )
 91                            .std()
 92                            .log2();
 93
 94                        assert!(
 95                            noise_have < max_noise + 0.5,
 96                            "row:{row} col:{col} noise_have:{noise_have} > max_noise:{}",
 97                            max_noise + 0.5
 98                        );
 99                    }
100                }
101            }
102        }
103    }
104}
105
106pub fn test_gglwe_switching_key_compressed_encrypt_sk<BE: Backend>(module: &Module<BE>)
107where
108    Module<BE>: GGLWEEncryptSk<BE>
109        + GGLWEPreparedFactory<BE>
110        + GGLWEKeyswitch<BE>
111        + GLWEDecrypt<BE>
112        + GLWESecretPreparedFactory<BE>
113        + GLWESwitchingKeyEncryptSk<BE>
114        + GLWESwitchingKeyCompressedEncryptSk<BE>
115        + GLWESwitchingKeyDecompress
116        + GGLWENoise<BE>
117        + VecZnxFillUniform,
118    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
119    Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
120{
121    let n: usize = module.n();
122    let base2k: usize = 12;
123    let k_ksk: usize = 54;
124    let dsize: usize = k_ksk / base2k;
125    for rank_in in 1_usize..3 {
126        for rank_out in 1_usize..3 {
127            for di in 1_usize..dsize + 1 {
128                let dnum: usize = (k_ksk - di * base2k) / (di * base2k);
129
130                let gglwe_infos: GGLWELayout = GGLWELayout {
131                    n: n.into(),
132                    base2k: base2k.into(),
133                    k: k_ksk.into(),
134                    dnum: dnum.into(),
135                    dsize: di.into(),
136                    rank_in: rank_in.into(),
137                    rank_out: rank_out.into(),
138                };
139
140                let mut ksk_compressed: GLWESwitchingKeyCompressed<Vec<u8>> =
141                    GLWESwitchingKeyCompressed::alloc_from_infos(&gglwe_infos);
142
143                let mut source_xs: Source = Source::new([0u8; 32]);
144                let mut source_xe: Source = Source::new([0u8; 32]);
145
146                let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(GLWESwitchingKeyCompressed::encrypt_sk_tmp_bytes(
147                    module,
148                    &gglwe_infos,
149                ));
150
151                let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_in.into());
152                sk_in.fill_ternary_prob(0.5, &mut source_xs);
153
154                let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(n.into(), rank_out.into());
155                sk_out.fill_ternary_prob(0.5, &mut source_xs);
156                let mut sk_out_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc(module, rank_out.into());
157                sk_out_prepared.prepare(module, &sk_out);
158
159                let seed_xa = [1u8; 32];
160
161                ksk_compressed.encrypt_sk(
162                    module,
163                    &sk_in,
164                    &sk_out,
165                    seed_xa,
166                    &mut source_xe,
167                    scratch.borrow(),
168                );
169
170                let mut ksk: GLWESwitchingKey<Vec<u8>> = GLWESwitchingKey::alloc_from_infos(&gglwe_infos);
171                ksk.decompress(module, &ksk_compressed);
172
173                let max_noise: f64 = SIGMA.log2() - (ksk.k().as_usize() as f64) + 0.5;
174
175                for row in 0..ksk.dnum().as_usize() {
176                    for col in 0..ksk.rank_in().as_usize() {
177                        let noise_have = ksk
178                            .key
179                            .noise(
180                                module,
181                                row,
182                                col,
183                                &sk_in.data,
184                                &sk_out_prepared,
185                                scratch.borrow(),
186                            )
187                            .std()
188                            .log2();
189
190                        assert!(
191                            noise_have < max_noise + 0.5,
192                            "row:{row} col:{col} noise_have:{noise_have} > max_noise:{}",
193                            max_noise + 0.5
194                        );
195                    }
196                }
197            }
198        }
199    }
200}