arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/tests/test_suite/encryption/glwe_ct.rs
poulpy-core/src/tests/test_suite/encryption/glwe_ct.rsRaw
  1use poulpy_hal::{
  2    api::{
  3        ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolAllocBytes,
  4        SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxBigAddInplace, VecZnxBigAddNormal, VecZnxBigAddSmallInplace,
  5        VecZnxBigAllocBytes, VecZnxBigNormalize, VecZnxCopy, VecZnxDftAlloc, VecZnxDftAllocBytes, VecZnxDftApply,
  6        VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub,
  7        VecZnxSubInplace,
  8    },
  9    layouts::{Backend, Module, ScratchOwned},
 10    oep::{
 11        ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl,
 12        TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl,
 13    },
 14    source::Source,
 15};
 16
 17use crate::{
 18    encryption::SIGMA,
 19    layouts::{
 20        GLWE, GLWELayout, GLWEPlaintext, GLWEPlaintextLayout, GLWEPublicKey, GLWESecret, LWEInfos,
 21        compressed::{Decompress, GLWECompressed},
 22        prepared::{GLWEPublicKeyPrepared, GLWESecretPrepared, PrepareAlloc},
 23    },
 24    operations::GLWEOperations,
 25};
 26
 27pub fn test_glwe_encrypt_sk<B>(module: &Module<B>)
 28where
 29    Module<B>: VecZnxDftAllocBytes
 30        + VecZnxBigAllocBytes
 31        + VecZnxDftApply<B>
 32        + SvpApplyDftToDftInplace<B>
 33        + VecZnxIdftApplyConsume<B>
 34        + VecZnxBigAddInplace<B>
 35        + VecZnxBigAddSmallInplace<B>
 36        + VecZnxBigNormalize<B>
 37        + VecZnxNormalizeTmpBytes
 38        + SvpPrepare<B>
 39        + SvpPPolAllocBytes
 40        + SvpPPolAlloc<B>
 41        + SvpApplyDftToDft<B>
 42        + VecZnxBigAddNormal<B>
 43        + VecZnxFillUniform
 44        + VecZnxSubInplace
 45        + VecZnxAddInplace
 46        + VecZnxNormalizeInplace<B>
 47        + VecZnxAddNormal
 48        + VecZnxNormalize<B>
 49        + VecZnxSub,
 50    B: Backend
 51        + TakeVecZnxDftImpl<B>
 52        + TakeVecZnxBigImpl<B>
 53        + TakeSvpPPolImpl<B>
 54        + ScratchOwnedAllocImpl<B>
 55        + ScratchOwnedBorrowImpl<B>
 56        + ScratchAvailableImpl<B>
 57        + TakeScalarZnxImpl<B>
 58        + TakeVecZnxImpl<B>,
 59{
 60    let base2k: usize = 8;
 61    let k_ct: usize = 54;
 62    let k_pt: usize = 30;
 63
 64    for rank in 1_usize..3 {
 65        let n: usize = module.n();
 66
 67        let glwe_infos: GLWELayout = GLWELayout {
 68            n: n.into(),
 69            base2k: base2k.into(),
 70            k: k_ct.into(),
 71            rank: rank.into(),
 72        };
 73
 74        let pt_infos: GLWEPlaintextLayout = GLWEPlaintextLayout {
 75            n: n.into(),
 76            base2k: base2k.into(),
 77            k: k_pt.into(),
 78        };
 79
 80        let mut ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos);
 81        let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&pt_infos);
 82        let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&pt_infos);
 83
 84        let mut source_xs: Source = Source::new([0u8; 32]);
 85        let mut source_xe: Source = Source::new([0u8; 32]);
 86        let mut source_xa: Source = Source::new([0u8; 32]);
 87
 88        let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
 89            GLWE::encrypt_sk_scratch_space(module, &glwe_infos) | GLWE::decrypt_scratch_space(module, &glwe_infos),
 90        );
 91
 92        let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
 93        sk.fill_ternary_prob(0.5, &mut source_xs);
 94        let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
 95
 96        module.vec_znx_fill_uniform(base2k, &mut pt_want.data, 0, &mut source_xa);
 97
 98        ct.encrypt_sk(
 99            module,
100            &pt_want,
101            &sk_prepared,
102            &mut source_xa,
103            &mut source_xe,
104            scratch.borrow(),
105        );
106
107        ct.decrypt(module, &mut pt_have, &sk_prepared, scratch.borrow());
108
109        pt_want.sub_inplace_ab(module, &pt_have);
110
111        let noise_have: f64 = pt_want.data.std(base2k, 0) * (ct.k().as_u32() as f64).exp2();
112        let noise_want: f64 = SIGMA;
113
114        assert!(noise_have <= noise_want + 0.2);
115    }
116}
117
118pub fn test_glwe_compressed_encrypt_sk<B>(module: &Module<B>)
119where
120    Module<B>: VecZnxDftAllocBytes
121        + VecZnxBigAllocBytes
122        + VecZnxDftApply<B>
123        + SvpApplyDftToDftInplace<B>
124        + VecZnxIdftApplyConsume<B>
125        + VecZnxBigAddInplace<B>
126        + VecZnxBigAddSmallInplace<B>
127        + VecZnxBigNormalize<B>
128        + VecZnxNormalizeTmpBytes
129        + SvpPrepare<B>
130        + SvpPPolAllocBytes
131        + SvpPPolAlloc<B>
132        + SvpApplyDftToDft<B>
133        + VecZnxBigAddNormal<B>
134        + VecZnxFillUniform
135        + VecZnxSubInplace
136        + VecZnxAddInplace
137        + VecZnxNormalizeInplace<B>
138        + VecZnxAddNormal
139        + VecZnxNormalize<B>
140        + VecZnxSub
141        + VecZnxCopy,
142    B: Backend
143        + TakeVecZnxDftImpl<B>
144        + TakeVecZnxBigImpl<B>
145        + TakeSvpPPolImpl<B>
146        + ScratchOwnedAllocImpl<B>
147        + ScratchOwnedBorrowImpl<B>
148        + ScratchAvailableImpl<B>
149        + TakeScalarZnxImpl<B>
150        + TakeVecZnxImpl<B>,
151{
152    let base2k: usize = 8;
153    let k_ct: usize = 54;
154    let k_pt: usize = 30;
155
156    for rank in 1_usize..3 {
157        let n: usize = module.n();
158
159        let glwe_infos: GLWELayout = GLWELayout {
160            n: n.into(),
161            base2k: base2k.into(),
162            k: k_ct.into(),
163            rank: rank.into(),
164        };
165
166        let pt_infos: GLWEPlaintextLayout = GLWEPlaintextLayout {
167            n: n.into(),
168            base2k: base2k.into(),
169            k: k_pt.into(),
170        };
171
172        let mut ct_compressed: GLWECompressed<Vec<u8>> = GLWECompressed::alloc_from_infos(&glwe_infos);
173
174        let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&pt_infos);
175        let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&pt_infos);
176
177        let mut source_xs: Source = Source::new([0u8; 32]);
178        let mut source_xe: Source = Source::new([0u8; 32]);
179        let mut source_xa: Source = Source::new([0u8; 32]);
180
181        let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
182            GLWECompressed::encrypt_sk_scratch_space(module, &glwe_infos) | GLWE::decrypt_scratch_space(module, &glwe_infos),
183        );
184
185        let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
186        sk.fill_ternary_prob(0.5, &mut source_xs);
187        let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
188
189        module.vec_znx_fill_uniform(base2k, &mut pt_want.data, 0, &mut source_xa);
190
191        let seed_xa: [u8; 32] = [1u8; 32];
192
193        ct_compressed.encrypt_sk(
194            module,
195            &pt_want,
196            &sk_prepared,
197            seed_xa,
198            &mut source_xe,
199            scratch.borrow(),
200        );
201
202        let mut ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos);
203        ct.decompress(module, &ct_compressed);
204
205        ct.decrypt(module, &mut pt_have, &sk_prepared, scratch.borrow());
206
207        pt_want.sub_inplace_ab(module, &pt_have);
208
209        let noise_have: f64 = pt_want.data.std(base2k, 0) * (ct.k().as_u32() as f64).exp2();
210        let noise_want: f64 = SIGMA;
211
212        assert!(
213            noise_have <= noise_want + 0.2,
214            "{noise_have} <= {}",
215            noise_want + 0.2
216        );
217    }
218}
219
220pub fn test_glwe_encrypt_zero_sk<B>(module: &Module<B>)
221where
222    Module<B>: VecZnxDftAllocBytes
223        + VecZnxBigAllocBytes
224        + VecZnxDftApply<B>
225        + SvpApplyDftToDftInplace<B>
226        + VecZnxIdftApplyConsume<B>
227        + VecZnxBigAddInplace<B>
228        + VecZnxBigAddSmallInplace<B>
229        + VecZnxBigNormalize<B>
230        + VecZnxNormalizeTmpBytes
231        + SvpPrepare<B>
232        + SvpPPolAllocBytes
233        + SvpPPolAlloc<B>
234        + SvpApplyDftToDft<B>
235        + VecZnxBigAddNormal<B>
236        + VecZnxFillUniform
237        + VecZnxSubInplace
238        + VecZnxAddInplace
239        + VecZnxNormalizeInplace<B>
240        + VecZnxAddNormal
241        + VecZnxNormalize<B>
242        + VecZnxSub,
243    B: Backend
244        + TakeVecZnxDftImpl<B>
245        + TakeVecZnxBigImpl<B>
246        + TakeSvpPPolImpl<B>
247        + ScratchOwnedAllocImpl<B>
248        + ScratchOwnedBorrowImpl<B>
249        + ScratchAvailableImpl<B>
250        + TakeScalarZnxImpl<B>
251        + TakeVecZnxImpl<B>,
252{
253    let base2k: usize = 8;
254    let k_ct: usize = 54;
255
256    for rank in 1_usize..3 {
257        let n: usize = module.n();
258
259        let glwe_infos: GLWELayout = GLWELayout {
260            n: n.into(),
261            base2k: base2k.into(),
262            k: k_ct.into(),
263            rank: rank.into(),
264        };
265
266        let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos);
267
268        let mut source_xs: Source = Source::new([0u8; 32]);
269        let mut source_xe: Source = Source::new([1u8; 32]);
270        let mut source_xa: Source = Source::new([0u8; 32]);
271
272        let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
273            GLWE::decrypt_scratch_space(module, &glwe_infos) | GLWE::encrypt_sk_scratch_space(module, &glwe_infos),
274        );
275
276        let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
277        sk.fill_ternary_prob(0.5, &mut source_xs);
278        let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
279
280        let mut ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos);
281
282        ct.encrypt_zero_sk(
283            module,
284            &sk_prepared,
285            &mut source_xa,
286            &mut source_xe,
287            scratch.borrow(),
288        );
289        ct.decrypt(module, &mut pt, &sk_prepared, scratch.borrow());
290
291        assert!((SIGMA - pt.data.std(base2k, 0) * (k_ct as f64).exp2()) <= 0.2);
292    }
293}
294
295pub fn test_glwe_encrypt_pk<B>(module: &Module<B>)
296where
297    Module<B>: VecZnxDftAllocBytes
298        + VecZnxBigNormalize<B>
299        + VecZnxDftApply<B>
300        + SvpApplyDftToDftInplace<B>
301        + VecZnxIdftApplyConsume<B>
302        + VecZnxNormalizeTmpBytes
303        + VecZnxFillUniform
304        + VecZnxSubInplace
305        + VecZnxAddInplace
306        + VecZnxNormalizeInplace<B>
307        + VecZnxAddNormal
308        + VecZnxNormalize<B>
309        + VecZnxSub
310        + SvpPrepare<B>
311        + SvpPPolAllocBytes
312        + SvpPPolAlloc<B>
313        + VecZnxBigAddSmallInplace<B>
314        + VecZnxBigAllocBytes
315        + VecZnxBigAddInplace<B>
316        + VecZnxCopy
317        + VecZnxDftAlloc<B>
318        + SvpApplyDftToDft<B>
319        + VecZnxBigAddNormal<B>,
320    B: Backend
321        + TakeVecZnxDftImpl<B>
322        + TakeVecZnxBigImpl<B>
323        + TakeSvpPPolImpl<B>
324        + ScratchOwnedAllocImpl<B>
325        + ScratchOwnedBorrowImpl<B>
326        + ScratchAvailableImpl<B>
327        + TakeScalarZnxImpl<B>
328        + TakeVecZnxImpl<B>,
329{
330    let base2k: usize = 8;
331    let k_ct: usize = 54;
332
333    for rank in 1_usize..3 {
334        let n: usize = module.n();
335
336        let glwe_infos: GLWELayout = GLWELayout {
337            n: n.into(),
338            base2k: base2k.into(),
339            k: k_ct.into(),
340            rank: rank.into(),
341        };
342
343        let mut ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos);
344        let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos);
345        let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos);
346
347        let mut source_xs: Source = Source::new([0u8; 32]);
348        let mut source_xe: Source = Source::new([0u8; 32]);
349        let mut source_xa: Source = Source::new([0u8; 32]);
350        let mut source_xu: Source = Source::new([0u8; 32]);
351
352        let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
353            GLWE::encrypt_sk_scratch_space(module, &glwe_infos)
354                | GLWE::decrypt_scratch_space(module, &glwe_infos)
355                | GLWE::encrypt_pk_scratch_space(module, &glwe_infos),
356        );
357
358        let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
359        sk.fill_ternary_prob(0.5, &mut source_xs);
360        let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
361
362        let mut pk: GLWEPublicKey<Vec<u8>> = GLWEPublicKey::alloc_from_infos(&glwe_infos);
363        pk.generate(module, &sk_prepared, &mut source_xa, &mut source_xe);
364
365        module.vec_znx_fill_uniform(base2k, &mut pt_want.data, 0, &mut source_xa);
366
367        let pk_prepared: GLWEPublicKeyPrepared<Vec<u8>, B> = pk.prepare_alloc(module, scratch.borrow());
368
369        ct.encrypt_pk(
370            module,
371            &pt_want,
372            &pk_prepared,
373            &mut source_xu,
374            &mut source_xe,
375            scratch.borrow(),
376        );
377
378        ct.decrypt(module, &mut pt_have, &sk_prepared, scratch.borrow());
379
380        pt_want.sub_inplace_ab(module, &pt_have);
381
382        let noise_have: f64 = pt_want.data.std(base2k, 0).log2();
383        let noise_want: f64 = ((((rank as f64) + 1.0) * n as f64 * 0.5 * SIGMA * SIGMA).sqrt()).log2() - (k_ct as f64);
384
385        assert!(
386            noise_have <= noise_want + 0.2,
387            "{noise_have} <= {}",
388            noise_want + 0.2
389        );
390    }
391}