arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/gglwe/test/tensor_key_generic.rs
core/src/gglwe/test/tensor_key_generic.rsRaw
  1use backend::hal::{
  2    api::{
  3        MatZnxAlloc, ScalarZnxAlloc, ScalarZnxAllocBytes, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxAddScalarInplace,
  4        VecZnxAlloc, VecZnxAllocBytes, VecZnxBigAlloc, VecZnxDftAlloc, VecZnxStd, VecZnxSubScalarInplace, VecZnxSwithcDegree,
  5    },
  6    layouts::{Backend, Module, ScratchOwned, VecZnxDft},
  7    oep::{
  8        ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl,
  9        TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl, VecZnxBigAllocBytesImpl, VecZnxDftAllocBytesImpl,
 10    },
 11};
 12use sampling::source::Source;
 13
 14use crate::{
 15    GGLWEEncryptSkFamily, GGLWEExecLayoutFamily, GLWEDecryptFamily, GLWEPlaintext, GLWESecret, GLWESecretExec, GLWETensorKey,
 16    GLWETensorKeyEncryptSkFamily, Infos,
 17};
 18
 19pub(crate) trait TestModuleFamily<B: Backend> = GGLWEEncryptSkFamily<B>
 20    + GLWEDecryptFamily<B>
 21    + MatZnxAlloc
 22    + ScalarZnxAlloc
 23    + ScalarZnxAllocBytes
 24    + VecZnxAllocBytes
 25    + VecZnxSwithcDegree
 26    + VecZnxAddScalarInplace
 27    + VecZnxStd
 28    + VecZnxAlloc
 29    + VecZnxSubScalarInplace;
 30
 31pub(crate) trait TestScratchFamily<B: Backend> = TakeVecZnxDftImpl<B>
 32    + TakeVecZnxBigImpl<B>
 33    + TakeSvpPPolImpl<B>
 34    + ScratchOwnedAllocImpl<B>
 35    + ScratchOwnedBorrowImpl<B>
 36    + ScratchAvailableImpl<B>
 37    + TakeScalarZnxImpl<B>
 38    + TakeVecZnxImpl<B>
 39    + VecZnxDftAllocBytesImpl<B>
 40    + VecZnxBigAllocBytesImpl<B>
 41    + TakeSvpPPolImpl<B>;
 42
 43pub(crate) fn test_encrypt_sk<B: Backend>(module: &Module<B>, basek: usize, k: usize, sigma: f64, rank: usize)
 44where
 45    Module<B>: TestModuleFamily<B>
 46        + GGLWEExecLayoutFamily<B>
 47        + GLWETensorKeyEncryptSkFamily<B>
 48        + GLWEDecryptFamily<B>
 49        + VecZnxDftAlloc<B>
 50        + VecZnxBigAlloc<B>,
 51    B: TestScratchFamily<B>,
 52{
 53    let rows: usize = k / basek;
 54
 55    let mut tensor_key: GLWETensorKey<Vec<u8>> = GLWETensorKey::alloc(&module, basek, k, rows, 1, rank);
 56
 57    let mut source_xs: Source = Source::new([0u8; 32]);
 58    let mut source_xe: Source = Source::new([0u8; 32]);
 59    let mut source_xa: Source = Source::new([0u8; 32]);
 60
 61    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GLWETensorKey::encrypt_sk_scratch_space(
 62        module,
 63        basek,
 64        tensor_key.k(),
 65        rank,
 66    ));
 67
 68    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&module, rank);
 69    sk.fill_ternary_prob(0.5, &mut source_xs);
 70    let mut sk_exec: GLWESecretExec<Vec<u8>, B> = GLWESecretExec::from(&module, &sk);
 71    sk_exec.prepare(module, &sk);
 72
 73    tensor_key.encrypt_sk(
 74        module,
 75        &sk,
 76        &mut source_xa,
 77        &mut source_xe,
 78        sigma,
 79        scratch.borrow(),
 80    );
 81
 82    let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k);
 83
 84    let mut sk_ij_dft = module.vec_znx_dft_alloc(1, 1);
 85    let mut sk_ij_big = module.vec_znx_big_alloc(1, 1);
 86    let mut sk_ij: GLWESecret<Vec<u8>> = GLWESecret::alloc(&module, 1);
 87    let mut sk_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(rank, 1);
 88
 89    (0..rank).for_each(|i| {
 90        module.vec_znx_dft_from_vec_znx(1, 0, &mut sk_dft, i, &sk.data, i);
 91    });
 92
 93    (0..rank).for_each(|i| {
 94        (0..rank).for_each(|j| {
 95            module.svp_apply(&mut sk_ij_dft, 0, &sk_exec.data, j, &sk_dft, i);
 96            module.vec_znx_dft_to_vec_znx_big_tmp_a(&mut sk_ij_big, 0, &mut sk_ij_dft, 0);
 97            module.vec_znx_big_normalize(basek, &mut sk_ij.data, 0, &sk_ij_big, 0, scratch.borrow());
 98            (0..tensor_key.rank_in()).for_each(|col_i| {
 99                (0..tensor_key.rows()).for_each(|row_i| {
100                    tensor_key
101                        .at(i, j)
102                        .at(row_i, col_i)
103                        .decrypt(&module, &mut pt, &sk_exec, scratch.borrow());
104
105                    module.vec_znx_sub_scalar_inplace(&mut pt.data, 0, row_i, &sk_ij.data, col_i);
106
107                    let std_pt: f64 = module.vec_znx_std(basek, &pt.data, 0) * (k as f64).exp2();
108                    assert!((sigma - std_pt).abs() <= 0.5, "{} {}", sigma, std_pt);
109                });
110            });
111        })
112    })
113}