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}