arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-schemes/src/tfhe/bdd_arithmetic/key.rs
poulpy-schemes/src/tfhe/bdd_arithmetic/key.rsRaw
  1use crate::tfhe::bdd_arithmetic::FheUintPreparedDebug;
  2use crate::tfhe::{
  3    bdd_arithmetic::{FheUint, FheUintPrepared, UnsignedInteger},
  4    blind_rotation::{BlindRotationAlgo, BlindRotationKey, BlindRotationKeyFactory},
  5    circuit_bootstrapping::{
  6        CircuitBootstrappingKey, CircuitBootstrappingKeyEncryptSk, CircuitBootstrappingKeyLayout,
  7        CircuitBootstrappingKeyPrepared, CircuitBootstrappingKeyPreparedFactory, CirtuitBootstrappingExecute,
  8    },
  9};
 10use poulpy_core::{
 11    GLWEToLWESwitchingKeyEncryptSk, GetDistribution, LWEFromGLWE, ScratchTakeCore,
 12    layouts::{
 13        GGSWInfos, GGSWPreparedFactory, GLWEInfos, GLWESecretToRef, GLWEToLWEKey, GLWEToLWEKeyLayout,
 14        GLWEToLWEKeyPreparedFactory, LWE, LWEInfos, LWESecretToRef, prepared::GLWEToLWEKeyPrepared,
 15    },
 16};
 17use poulpy_hal::{
 18    layouts::{Backend, Data, DataMut, DataRef, Module, Scratch},
 19    source::Source,
 20};
 21
 22pub trait BDDKeyInfos {
 23    fn cbt_infos(&self) -> CircuitBootstrappingKeyLayout;
 24    fn ks_infos(&self) -> GLWEToLWEKeyLayout;
 25}
 26
 27#[derive(Debug, Clone, Copy)]
 28pub struct BDDKeyLayout {
 29    pub cbt: CircuitBootstrappingKeyLayout,
 30    pub ks: GLWEToLWEKeyLayout,
 31}
 32
 33impl BDDKeyInfos for BDDKeyLayout {
 34    fn cbt_infos(&self) -> CircuitBootstrappingKeyLayout {
 35        self.cbt
 36    }
 37
 38    fn ks_infos(&self) -> GLWEToLWEKeyLayout {
 39        self.ks
 40    }
 41}
 42
 43pub struct BDDKey<D, BRA>
 44where
 45    D: Data,
 46    BRA: BlindRotationAlgo,
 47{
 48    cbt: CircuitBootstrappingKey<D, BRA>,
 49    ks: GLWEToLWEKey<D>,
 50}
 51
 52impl<BRA: BlindRotationAlgo> BDDKey<Vec<u8>, BRA>
 53where
 54    BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyFactory<BRA>,
 55{
 56    pub fn alloc_from_infos<A>(infos: &A) -> Self
 57    where
 58        A: BDDKeyInfos,
 59    {
 60        Self {
 61            cbt: CircuitBootstrappingKey::alloc_from_infos(&infos.cbt_infos()),
 62            ks: GLWEToLWEKey::alloc_from_infos(&infos.ks_infos()),
 63        }
 64    }
 65}
 66
 67pub trait BDDKeyEncryptSk<BRA: BlindRotationAlgo, BE: Backend> {
 68    fn bdd_key_encrypt_sk<D, S0, S1>(
 69        &self,
 70        res: &mut BDDKey<D, BRA>,
 71        sk_lwe: &S0,
 72        sk_glwe: &S1,
 73        source_xa: &mut Source,
 74        source_xe: &mut Source,
 75        scratch: &mut Scratch<BE>,
 76    ) where
 77        D: DataMut,
 78        S0: LWESecretToRef + GetDistribution + LWEInfos,
 79        S1: GLWESecretToRef + GetDistribution + GLWEInfos;
 80}
 81
 82impl<BE: Backend, BRA: BlindRotationAlgo> BDDKeyEncryptSk<BRA, BE> for Module<BE>
 83where
 84    Self: CircuitBootstrappingKeyEncryptSk<BRA, BE> + GLWEToLWESwitchingKeyEncryptSk<BE>,
 85    Scratch<BE>: ScratchTakeCore<BE>,
 86{
 87    fn bdd_key_encrypt_sk<D, S0, S1>(
 88        &self,
 89        res: &mut BDDKey<D, BRA>,
 90        sk_lwe: &S0,
 91        sk_glwe: &S1,
 92        source_xa: &mut Source,
 93        source_xe: &mut Source,
 94        scratch: &mut Scratch<BE>,
 95    ) where
 96        D: DataMut,
 97        S0: LWESecretToRef + GetDistribution + LWEInfos,
 98        S1: GLWESecretToRef + GetDistribution + GLWEInfos,
 99    {
100        res.ks
101            .encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
102        res.cbt
103            .encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
104    }
105}
106
107impl<D: DataMut, BRA: BlindRotationAlgo> BDDKey<D, BRA> {
108    pub fn encrypt_sk<S0, S1, M, BE: Backend>(
109        &mut self,
110        module: &M,
111        sk_lwe: &S0,
112        sk_glwe: &S1,
113        source_xa: &mut Source,
114        source_xe: &mut Source,
115        scratch: &mut Scratch<BE>,
116    ) where
117        S0: LWESecretToRef + GetDistribution + LWEInfos,
118        S1: GLWESecretToRef + GetDistribution + GLWEInfos,
119        M: BDDKeyEncryptSk<BRA, BE>,
120        Scratch<BE>: ScratchTakeCore<BE>,
121    {
122        module.bdd_key_encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
123    }
124}
125
126pub struct BddKeyPrepared<D, BRA, BE>
127where
128    D: Data,
129    BRA: BlindRotationAlgo,
130    BE: Backend,
131{
132    pub(crate) cbt: CircuitBootstrappingKeyPrepared<D, BRA, BE>,
133    pub(crate) ks: GLWEToLWEKeyPrepared<D, BE>,
134}
135
136pub trait BDDKeyPreparedFactory<BRA: BlindRotationAlgo, BE: Backend>
137where
138    Self: Sized + CircuitBootstrappingKeyPreparedFactory<BRA, BE> + GLWEToLWEKeyPreparedFactory<BE>,
139{
140    fn alloc_bdd_key_from_infos<A>(&self, infos: &A) -> BddKeyPrepared<Vec<u8>, BRA, BE>
141    where
142        A: BDDKeyInfos,
143    {
144        BddKeyPrepared {
145            cbt: CircuitBootstrappingKeyPrepared::alloc_from_infos(self, &infos.cbt_infos()),
146            ks: GLWEToLWEKeyPrepared::alloc_from_infos(self, &infos.ks_infos()),
147        }
148    }
149
150    fn prepare_bdd_key_tmp_bytes<A>(&self, infos: &A) -> usize
151    where
152        A: BDDKeyInfos,
153    {
154        self.circuit_bootstrapping_key_prepare_tmp_bytes(&infos.cbt_infos())
155            .max(self.prepare_glwe_to_lwe_key_tmp_bytes(&infos.ks_infos()))
156    }
157
158    fn prepare_bdd_key<DM, DR>(&self, res: &mut BddKeyPrepared<DM, BRA, BE>, other: &BDDKey<DR, BRA>, scratch: &mut Scratch<BE>)
159    where
160        DM: DataMut,
161        DR: DataRef,
162        Scratch<BE>: ScratchTakeCore<BE>,
163    {
164        res.cbt.prepare(self, &other.cbt, scratch);
165        res.ks.prepare(self, &other.ks, scratch);
166    }
167}
168impl<BRA: BlindRotationAlgo, BE: Backend> BDDKeyPreparedFactory<BRA, BE> for Module<BE> where
169    Self: Sized + CircuitBootstrappingKeyPreparedFactory<BRA, BE> + GLWEToLWEKeyPreparedFactory<BE>
170{
171}
172
173impl<BRA: BlindRotationAlgo, BE: Backend> BddKeyPrepared<Vec<u8>, BRA, BE> {
174    pub fn alloc_from_infos<M, A>(module: &M, infos: &A) -> Self
175    where
176        M: BDDKeyPreparedFactory<BRA, BE>,
177        A: BDDKeyInfos,
178    {
179        module.alloc_bdd_key_from_infos(infos)
180    }
181}
182
183impl<D: DataMut, BRA: BlindRotationAlgo, BE: Backend> BddKeyPrepared<D, BRA, BE> {
184    pub fn prepare<DR, M>(&mut self, module: &M, other: &BDDKey<DR, BRA>, scratch: &mut Scratch<BE>)
185    where
186        DR: DataRef,
187        M: BDDKeyPreparedFactory<BRA, BE>,
188        Scratch<BE>: ScratchTakeCore<BE>,
189    {
190        module.prepare_bdd_key(self, other, scratch);
191    }
192}
193
194pub trait FheUintBlocksPrepare<BRA: BlindRotationAlgo, T: UnsignedInteger, BE: Backend> {
195    fn fhe_uint_prepare_tmp_bytes<R, A>(&self, block_size: usize, extension_factor: usize, res_infos: &R, infos: &A) -> usize
196    where
197        R: GGSWInfos,
198        A: BDDKeyInfos;
199    fn fhe_uint_prepare<DM, DR0, DR1>(
200        &self,
201        res: &mut FheUintPrepared<DM, T, BE>,
202        bits: &FheUint<DR0, T>,
203        key: &BddKeyPrepared<DR1, BRA, BE>,
204        scratch: &mut Scratch<BE>,
205    ) where
206        DM: DataMut,
207        DR0: DataRef,
208        DR1: DataRef;
209}
210
211impl<BRA: BlindRotationAlgo, BE: Backend, T: UnsignedInteger> FheUintBlocksPrepare<BRA, T, BE> for Module<BE>
212where
213    Self: LWEFromGLWE<BE> + CirtuitBootstrappingExecute<BRA, BE> + GGSWPreparedFactory<BE>,
214    Scratch<BE>: ScratchTakeCore<BE>,
215{
216    fn fhe_uint_prepare_tmp_bytes<R, A>(&self, block_size: usize, extension_factor: usize, res_infos: &R, bdd_infos: &A) -> usize
217    where
218        R: GGSWInfos,
219        A: BDDKeyInfos,
220    {
221        self.circuit_bootstrapping_execute_tmp_bytes(
222            block_size,
223            extension_factor,
224            res_infos,
225            &bdd_infos.cbt_infos(),
226        )
227    }
228
229    fn fhe_uint_prepare<DM, DR0, DR1>(
230        &self,
231        res: &mut FheUintPrepared<DM, T, BE>,
232        bits: &FheUint<DR0, T>,
233        key: &BddKeyPrepared<DR1, BRA, BE>,
234        scratch: &mut Scratch<BE>,
235    ) where
236        DM: DataMut,
237        DR0: DataRef,
238        DR1: DataRef,
239    {
240        assert_eq!(res.bits.len(), bits.bits.len());
241
242        let mut lwe: LWE<Vec<u8>> = LWE::alloc_from_infos(&bits.bits[0]); //TODO: add TakeLWE
243        let (mut tmp_ggsw, scratch_1) = scratch.take_ggsw(res);
244        for (dst, src) in res.bits.iter_mut().zip(bits.bits.iter()) {
245            lwe.from_glwe(self, src, &key.ks, scratch_1);
246            key.cbt
247                .execute_to_constant(self, &mut tmp_ggsw, &lwe, 1, 1, scratch_1);
248            dst.prepare(self, &tmp_ggsw, scratch_1);
249        }
250    }
251}
252
253impl<D: DataMut, T: UnsignedInteger, BE: Backend> FheUintPrepared<D, T, BE> {
254    pub fn prepare<BRA, M, O, K>(
255        &mut self,
256        module: &M,
257        other: &FheUint<O, T>,
258        key: &BddKeyPrepared<K, BRA, BE>,
259        scratch: &mut Scratch<BE>,
260    ) where
261        BRA: BlindRotationAlgo,
262        O: DataRef,
263        K: DataRef,
264        M: FheUintBlocksPrepare<BRA, T, BE>,
265        Scratch<BE>: ScratchTakeCore<BE>,
266    {
267        module.fhe_uint_prepare(self, other, key, scratch);
268    }
269}
270
271pub trait FheUintBlockDebugPrepare<BRA: BlindRotationAlgo, T: UnsignedInteger, BE: Backend> {
272    fn fhe_uint_debug_prepare<DM, DR0, DR1>(
273        &self,
274        res: &mut FheUintPreparedDebug<DM, T>,
275        bits: &FheUint<DR0, T>,
276        key: &BddKeyPrepared<DR1, BRA, BE>,
277        scratch: &mut Scratch<BE>,
278    ) where
279        DM: DataMut,
280        DR0: DataRef,
281        DR1: DataRef;
282}