arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/tests/generics/keyswitch/lwe_ct.rs
core/src/tests/generics/keyswitch/lwe_ct.rsRaw
  1use backend::hal::{
  2    api::{
  3        ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxAddScalarInplace, VecZnxAutomorphismInplace, VecZnxEncodeCoeffsi64,
  4        VecZnxSwithcDegree, VmpPMatAlloc, VmpPMatPrepare, ZnxView,
  5    },
  6    layouts::{Backend, Module, ScratchOwned},
  7    oep::{
  8        ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl,
  9        TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl,
 10    },
 11};
 12use sampling::source::Source;
 13
 14use crate::layouts::{Infos, LWECiphertext, LWEPlaintext, LWESecret, LWESwitchingKey, prepared::LWESwitchingKeyExec};
 15
 16use crate::trait_families::{GGLWEEncryptSkFamily, GLWEDecryptFamily, GLWEKeyswitchFamily, GLWESecretExecModuleFamily};
 17
 18pub fn test_lwe_keyswitch<B: Backend>(module: &Module<B>)
 19where
 20    Module<B>: GGLWEEncryptSkFamily<B>
 21        + GLWEDecryptFamily<B>
 22        + VecZnxSwithcDegree
 23        + VecZnxAddScalarInplace
 24        + GLWEKeyswitchFamily<B>
 25        + VecZnxEncodeCoeffsi64
 26        + VecZnxAutomorphismInplace
 27        + VmpPMatAlloc<B>
 28        + VmpPMatPrepare<B>
 29        + GLWESecretExecModuleFamily<B>,
 30    B: TakeScalarZnxImpl<B>
 31        + TakeVecZnxDftImpl<B>
 32        + ScratchAvailableImpl<B>
 33        + TakeVecZnxImpl<B>
 34        + TakeVecZnxBigImpl<B>
 35        + TakeSvpPPolImpl<B>
 36        + ScratchOwnedAllocImpl<B>
 37        + ScratchOwnedBorrowImpl<B>,
 38{
 39    let n: usize = module.n();
 40    let basek: usize = 17;
 41    let sigma: f64 = 3.2;
 42
 43    let n_lwe_in: usize = 22;
 44    let n_lwe_out: usize = 30;
 45    let k_lwe_ct: usize = 2 * basek;
 46    let k_lwe_pt: usize = 8;
 47
 48    let k_ksk: usize = k_lwe_ct + basek;
 49
 50    let mut source_xs: Source = Source::new([0u8; 32]);
 51    let mut source_xa: Source = Source::new([0u8; 32]);
 52    let mut source_xe: Source = Source::new([0u8; 32]);
 53
 54    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
 55        LWESwitchingKey::encrypt_sk_scratch_space(module, n, basek, k_ksk)
 56            | LWECiphertext::keyswitch_scratch_space(module, n, basek, k_lwe_ct, k_lwe_ct, k_ksk),
 57    );
 58
 59    let mut sk_lwe_in: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe_in);
 60    sk_lwe_in.fill_ternary_prob(0.5, &mut source_xs);
 61
 62    let mut sk_lwe_out: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe_out);
 63    sk_lwe_out.fill_ternary_prob(0.5, &mut source_xs);
 64
 65    let data: i64 = 17;
 66
 67    let mut lwe_pt_in: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc(basek, k_lwe_pt);
 68    module.encode_coeff_i64(basek, &mut lwe_pt_in.data, 0, k_lwe_pt, 0, data, k_lwe_pt);
 69
 70    let mut lwe_ct_in: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(n_lwe_in, basek, k_lwe_ct);
 71    lwe_ct_in.encrypt_sk(
 72        module,
 73        &lwe_pt_in,
 74        &sk_lwe_in,
 75        &mut source_xa,
 76        &mut source_xe,
 77        sigma,
 78    );
 79
 80    let mut ksk: LWESwitchingKey<Vec<u8>> = LWESwitchingKey::alloc(n, basek, k_ksk, lwe_ct_in.size());
 81
 82    ksk.encrypt_sk(
 83        module,
 84        &sk_lwe_in,
 85        &sk_lwe_out,
 86        &mut source_xa,
 87        &mut source_xe,
 88        sigma,
 89        scratch.borrow(),
 90    );
 91
 92    let mut lwe_ct_out: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(n_lwe_out, basek, k_lwe_ct);
 93
 94    let ksk_exec: LWESwitchingKeyExec<Vec<u8>, B> = LWESwitchingKeyExec::from(module, &ksk, scratch.borrow());
 95
 96    lwe_ct_out.keyswitch(module, &lwe_ct_in, &ksk_exec, scratch.borrow());
 97
 98    let mut lwe_pt_out: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc(basek, k_lwe_ct);
 99    lwe_ct_out.decrypt(module, &mut lwe_pt_out, &sk_lwe_out);
100
101    assert_eq!(lwe_pt_in.data.at(0, 0)[0], lwe_pt_out.data.at(0, 0)[0]);
102}