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