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, VecZnxSwithcDegree,
  4        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::{
 15    Infos, LWECiphertext, LWEPlaintext, LWESecret, LWESwitchingKey,
 16    prepared::{LWESwitchingKeyPrepared, PrepareAlloc},
 17};
 18
 19use crate::trait_families::{GGLWEEncryptSkFamily, GLWEDecryptFamily, GLWEKeyswitchFamily, GLWESecretPreparedModuleFamily};
 20
 21pub fn test_lwe_keyswitch<B: Backend>(module: &Module<B>)
 22where
 23    Module<B>: GGLWEEncryptSkFamily<B>
 24        + GLWEDecryptFamily<B>
 25        + VecZnxSwithcDegree
 26        + VecZnxAddScalarInplace
 27        + GLWEKeyswitchFamily<B>
 28        + VecZnxAutomorphismInplace
 29        + VmpPMatAlloc<B>
 30        + VmpPMatPrepare<B>
 31        + GLWESecretPreparedModuleFamily<B>,
 32    B: TakeScalarZnxImpl<B>
 33        + TakeVecZnxDftImpl<B>
 34        + ScratchAvailableImpl<B>
 35        + TakeVecZnxImpl<B>
 36        + TakeVecZnxBigImpl<B>
 37        + TakeSvpPPolImpl<B>
 38        + ScratchOwnedAllocImpl<B>
 39        + ScratchOwnedBorrowImpl<B>,
 40{
 41    let n: usize = module.n();
 42    let basek: usize = 17;
 43    let sigma: f64 = 3.2;
 44
 45    let n_lwe_in: usize = 22;
 46    let n_lwe_out: usize = 30;
 47    let k_lwe_ct: usize = 2 * basek;
 48    let k_lwe_pt: usize = 8;
 49
 50    let k_ksk: usize = k_lwe_ct + basek;
 51
 52    let mut source_xs: Source = Source::new([0u8; 32]);
 53    let mut source_xa: Source = Source::new([0u8; 32]);
 54    let mut source_xe: Source = Source::new([0u8; 32]);
 55
 56    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
 57        LWESwitchingKey::encrypt_sk_scratch_space(module, n, basek, k_ksk)
 58            | LWECiphertext::keyswitch_scratch_space(module, n, basek, k_lwe_ct, k_lwe_ct, k_ksk),
 59    );
 60
 61    let mut sk_lwe_in: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe_in);
 62    sk_lwe_in.fill_ternary_prob(0.5, &mut source_xs);
 63
 64    let mut sk_lwe_out: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe_out);
 65    sk_lwe_out.fill_ternary_prob(0.5, &mut source_xs);
 66
 67    let data: i64 = 17;
 68
 69    let mut lwe_pt_in: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc(basek, k_lwe_pt);
 70
 71    lwe_pt_in.encode_i64(data, k_lwe_pt);
 72
 73    let mut lwe_ct_in: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(n_lwe_in, basek, k_lwe_ct);
 74    lwe_ct_in.encrypt_sk(
 75        module,
 76        &lwe_pt_in,
 77        &sk_lwe_in,
 78        &mut source_xa,
 79        &mut source_xe,
 80        sigma,
 81    );
 82
 83    let mut ksk: LWESwitchingKey<Vec<u8>> = LWESwitchingKey::alloc(n, basek, k_ksk, lwe_ct_in.size());
 84
 85    ksk.encrypt_sk(
 86        module,
 87        &sk_lwe_in,
 88        &sk_lwe_out,
 89        &mut source_xa,
 90        &mut source_xe,
 91        sigma,
 92        scratch.borrow(),
 93    );
 94
 95    let mut lwe_ct_out: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(n_lwe_out, basek, k_lwe_ct);
 96
 97    let ksk_prepared: LWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow());
 98
 99    lwe_ct_out.keyswitch(module, &lwe_ct_in, &ksk_prepared, scratch.borrow());
100
101    let mut lwe_pt_out: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc(basek, k_lwe_ct);
102    lwe_ct_out.decrypt(module, &mut lwe_pt_out, &sk_lwe_out);
103
104    assert_eq!(lwe_pt_in.data.at(0, 0)[0], lwe_pt_out.data.at(0, 0)[0]);
105}