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