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