arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block_debug.rs
poulpy-schemes/src/tfhe/bdd_arithmetic/ciphertexts/block_debug.rsRaw
  1use std::marker::PhantomData;
  2
  3use crate::tfhe::bdd_arithmetic::{BDDKeyPrepared, FheUintBlockDebugPrepare, ToBits};
  4use crate::tfhe::{
  5    bdd_arithmetic::{FheUintBlocks, UnsignedInteger},
  6    blind_rotation::BlindRotationAlgo,
  7    circuit_bootstrapping::CirtuitBootstrappingExecute,
  8};
  9use poulpy_core::GGSWNoise;
 10#[cfg(test)]
 11use poulpy_core::layouts::{Base2K, Dnum, Dsize, Rank, TorusPrecision};
 12use poulpy_core::layouts::{GGSW, GLWESecretPreparedToRef};
 13use poulpy_core::{
 14    LWEFromGLWE, ScratchTakeCore,
 15    layouts::{GGSWInfos, GGSWPreparedFactory, GLWEInfos, LWE, LWEInfos},
 16};
 17#[cfg(test)]
 18use poulpy_hal::api::ModuleN;
 19use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch};
 20
 21pub(crate) struct FheUintBlocksPreparedDebug<D: Data, T: UnsignedInteger> {
 22    pub(crate) blocks: Vec<GGSW<D>>,
 23    pub(crate) _base: u8,
 24    pub(crate) _phantom: PhantomData<T>,
 25}
 26
 27#[cfg(test)]
 28impl<T: UnsignedInteger> FheUintBlocksPreparedDebug<Vec<u8>, T> {
 29    #[allow(dead_code)]
 30    pub(crate) fn alloc<A, M>(module: &M, infos: &A) -> Self
 31    where
 32        M: ModuleN,
 33        A: GGSWInfos,
 34    {
 35        Self::alloc_with(
 36            module,
 37            infos.base2k(),
 38            infos.k(),
 39            infos.dnum(),
 40            infos.dsize(),
 41            infos.rank(),
 42        )
 43    }
 44
 45    #[allow(dead_code)]
 46    pub(crate) fn alloc_with<M>(module: &M, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self
 47    where
 48        M: ModuleN,
 49    {
 50        Self {
 51            blocks: (0..T::WORD_SIZE)
 52                .map(|_| GGSW::alloc(module.n().into(), base2k, k, rank, dnum, dsize))
 53                .collect(),
 54            _base: 1,
 55            _phantom: PhantomData,
 56        }
 57    }
 58}
 59
 60impl<D: DataRef, T: UnsignedInteger> LWEInfos for FheUintBlocksPreparedDebug<D, T> {
 61    fn base2k(&self) -> poulpy_core::layouts::Base2K {
 62        self.blocks[0].base2k()
 63    }
 64
 65    fn k(&self) -> poulpy_core::layouts::TorusPrecision {
 66        self.blocks[0].k()
 67    }
 68
 69    fn n(&self) -> poulpy_core::layouts::Degree {
 70        self.blocks[0].n()
 71    }
 72}
 73
 74impl<D: DataRef, T: UnsignedInteger> GLWEInfos for FheUintBlocksPreparedDebug<D, T> {
 75    fn rank(&self) -> poulpy_core::layouts::Rank {
 76        self.blocks[0].rank()
 77    }
 78}
 79
 80impl<D: DataRef, T: UnsignedInteger> GGSWInfos for FheUintBlocksPreparedDebug<D, T> {
 81    fn dsize(&self) -> poulpy_core::layouts::Dsize {
 82        self.blocks[0].dsize()
 83    }
 84
 85    fn dnum(&self) -> poulpy_core::layouts::Dnum {
 86        self.blocks[0].dnum()
 87    }
 88}
 89
 90impl<D: DataRef, T: UnsignedInteger + ToBits> FheUintBlocksPreparedDebug<D, T> {
 91    #[allow(dead_code)]
 92    pub(crate) fn noise<S, M, BE: Backend>(&self, module: &M, sk: &S, want: T)
 93    where
 94        S: GLWESecretPreparedToRef<BE>,
 95        M: GGSWNoise<BE>,
 96    {
 97        for (i, ggsw) in self.blocks.iter().enumerate() {
 98            use poulpy_hal::layouts::{ScalarZnx, ZnxViewMut};
 99            let mut pt_want = ScalarZnx::alloc(self.n().into(), 1);
100            pt_want.at_mut(0, 0)[0] = want.bit(i) as i64;
101            ggsw.print_noise(module, sk, &pt_want);
102        }
103    }
104}
105
106impl<BRA: BlindRotationAlgo, BE: Backend, T: UnsignedInteger> FheUintBlockDebugPrepare<BRA, T, BE> for Module<BE>
107where
108    Self: LWEFromGLWE<BE> + CirtuitBootstrappingExecute<BRA, BE> + GGSWPreparedFactory<BE>,
109    Scratch<BE>: ScratchTakeCore<BE>,
110{
111    fn fhe_uint_block_debug_prepare<DM, DR0, DR1>(
112        &self,
113        res: &mut FheUintBlocksPreparedDebug<DM, T>,
114        bits: &FheUintBlocks<DR0, T>,
115        key: &BDDKeyPrepared<DR1, BRA, BE>,
116        scratch: &mut Scratch<BE>,
117    ) where
118        DM: DataMut,
119        DR0: DataRef,
120        DR1: DataRef,
121    {
122        assert_eq!(res.blocks.len(), bits.blocks.len());
123
124        let mut lwe: LWE<Vec<u8>> = LWE::alloc_from_infos(&bits.blocks[0]); //TODO: add TakeLWE
125        for (dst, src) in res.blocks.iter_mut().zip(bits.blocks.iter()) {
126            lwe.from_glwe(self, src, &key.ks, scratch);
127            key.cbt.execute_to_constant(self, dst, &lwe, 1, 1, scratch);
128        }
129    }
130}
131
132impl<D: DataMut, T: UnsignedInteger> FheUintBlocksPreparedDebug<D, T> {
133    #[allow(dead_code)]
134    pub fn prepare<BRA, M, O, K, BE: Backend>(
135        &mut self,
136        module: &M,
137        other: &FheUintBlocks<O, T>,
138        key: &BDDKeyPrepared<K, BRA, BE>,
139        scratch: &mut Scratch<BE>,
140    ) where
141        BRA: BlindRotationAlgo,
142        O: DataRef,
143        K: DataRef,
144        M: FheUintBlockDebugPrepare<BRA, T, BE>,
145        Scratch<BE>: ScratchTakeCore<BE>,
146    {
147        module.fhe_uint_block_debug_prepare(self, other, key, scratch);
148    }
149}