poulpy/poulpy-schemes/src/tfhe/bdd_arithmetic/key.rs
poulpy-schemes/src/tfhe/bdd_arithmetic/key.rsRaw
1#[cfg(test)]
2use crate::tfhe::bdd_arithmetic::FheUintBlocksPrepDebug;
3use crate::tfhe::{
4 bdd_arithmetic::{FheUintBlocks, FheUintBlocksPrep, UnsignedInteger},
5 blind_rotation::{BlindRotationAlgo, BlindRotationKey, BlindRotationKeyAlloc, BlindRotationKeyEncryptSk},
6 circuit_bootstrapping::{
7 CircuitBootstrappingKey, CircuitBootstrappingKeyEncryptSk, CircuitBootstrappingKeyLayout,
8 CircuitBootstrappingKeyPrepared, CirtuitBootstrappingExecute,
9 },
10};
11use poulpy_core::{
12 TakeGGSW, TakeGLWECt,
13 layouts::{
14 GLWESecret, GLWEToLWEKeyLayout, GLWEToLWESwitchingKey, LWECiphertext, LWESecret,
15 prepared::{GLWEToLWESwitchingKeyPrepared, Prepare, PrepareAlloc},
16 },
17};
18use poulpy_hal::{
19 api::{
20 ScratchAvailable, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx,
21 TakeSvpPPol, TakeVecZnx, TakeVecZnxBig, TakeVecZnxDft, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace,
22 VecZnxAutomorphism, VecZnxAutomorphismInplace, VecZnxBigAddSmallInplace, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes,
23 VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, VecZnxNormalize,
24 VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxRotate, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
25 VmpApplyDftToDft, VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes, VmpPrepare,
26 },
27 layouts::{Backend, Data, DataMut, DataRef, Module, Scratch},
28 source::Source,
29};
30
31pub trait BDDKeyInfos {
32 fn cbt_infos(&self) -> CircuitBootstrappingKeyLayout;
33 fn ks_infos(&self) -> GLWEToLWEKeyLayout;
34}
35
36#[derive(Debug, Clone, Copy)]
37pub struct BDDKeyLayout {
38 pub cbt: CircuitBootstrappingKeyLayout,
39 pub ks: GLWEToLWEKeyLayout,
40}
41
42impl BDDKeyInfos for BDDKeyLayout {
43 fn cbt_infos(&self) -> CircuitBootstrappingKeyLayout {
44 self.cbt
45 }
46
47 fn ks_infos(&self) -> GLWEToLWEKeyLayout {
48 self.ks
49 }
50}
51
52pub struct BDDKey<CBT, LWE, BRA>
53where
54 CBT: Data,
55 LWE: Data,
56 BRA: BlindRotationAlgo,
57{
58 cbt: CircuitBootstrappingKey<CBT, BRA>,
59 ks: GLWEToLWESwitchingKey<LWE>,
60}
61
62impl<BRA: BlindRotationAlgo> BDDKey<Vec<u8>, Vec<u8>, BRA> {
63 pub fn encrypt_sk<DLwe, DGlwe, A, BE: Backend>(
64 module: &Module<BE>,
65 sk_lwe: &LWESecret<DLwe>,
66 sk_glwe: &GLWESecret<DGlwe>,
67 infos: &A,
68 source_xa: &mut Source,
69 source_xe: &mut Source,
70 scratch: &mut Scratch<BE>,
71 ) -> Self
72 where
73 A: BDDKeyInfos,
74 DLwe: DataRef,
75 DGlwe: DataRef,
76 BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk<BE>,
77 Module<BE>: SvpApplyDftToDft<BE>
78 + VecZnxIdftApplyTmpA<BE>
79 + VecZnxAddScalarInplace
80 + VecZnxDftAllocBytes
81 + VecZnxBigNormalize<BE>
82 + VecZnxDftApply<BE>
83 + SvpApplyDftToDftInplace<BE>
84 + VecZnxIdftApplyConsume<BE>
85 + VecZnxNormalizeTmpBytes
86 + VecZnxFillUniform
87 + VecZnxSubInplace
88 + VecZnxAddInplace
89 + VecZnxNormalizeInplace<BE>
90 + VecZnxAddNormal
91 + VecZnxNormalize<BE>
92 + VecZnxSub
93 + SvpPrepare<BE>
94 + VecZnxSwitchRing
95 + SvpPPolAllocBytes
96 + SvpPPolAlloc<BE>
97 + VecZnxAutomorphism
98 + VecZnxAutomorphismInplace<BE>,
99 Scratch<BE>: TakeVecZnxDft<BE> + ScratchAvailable + TakeVecZnx + TakeScalarZnx + TakeSvpPPol<BE> + TakeVecZnxBig<BE>,
100 {
101 let mut ks: GLWEToLWESwitchingKey<Vec<u8>> = GLWEToLWESwitchingKey::alloc(&infos.ks_infos());
102 ks.encrypt_sk(module, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
103
104 Self {
105 cbt: CircuitBootstrappingKey::encrypt_sk(
106 module,
107 sk_lwe,
108 sk_glwe,
109 &infos.cbt_infos(),
110 source_xa,
111 source_xe,
112 scratch,
113 ),
114 ks,
115 }
116 }
117}
118
119pub struct BDDKeyPrepared<CBT, LWE, BRA, BE>
120where
121 CBT: Data,
122 LWE: Data,
123 BRA: BlindRotationAlgo,
124 BE: Backend,
125{
126 cbt: CircuitBootstrappingKeyPrepared<CBT, BRA, BE>,
127 ks: GLWEToLWESwitchingKeyPrepared<LWE, BE>,
128}
129
130impl<CBT: DataMut, LWE: DataMut, BRA: BlindRotationAlgo, BE: Backend> PrepareAlloc<BE, BDDKeyPrepared<CBT, LWE, BRA, BE>>
131 for BDDKey<CBT, LWE, BRA>
132where
133 CircuitBootstrappingKey<CBT, BRA>: PrepareAlloc<BE, CircuitBootstrappingKeyPrepared<CBT, BRA, BE>>,
134 GLWEToLWESwitchingKey<LWE>: PrepareAlloc<BE, GLWEToLWESwitchingKeyPrepared<LWE, BE>>,
135{
136 fn prepare_alloc(&self, module: &Module<BE>, scratch: &mut Scratch<BE>) -> BDDKeyPrepared<CBT, LWE, BRA, BE> {
137 BDDKeyPrepared {
138 cbt: self.cbt.prepare_alloc(module, scratch),
139 ks: self.ks.prepare_alloc(module, scratch),
140 }
141 }
142}
143
144pub trait FheUintPrepare<BE: Backend, OUT, IN> {
145 fn prepare(&self, module: &Module<BE>, out: &mut OUT, bits: &IN, scratch: &mut Scratch<BE>);
146}
147
148impl<CBT, OUT, IN, LWE, BRA, BE, T> FheUintPrepare<BE, FheUintBlocksPrep<OUT, BE, T>, FheUintBlocks<IN, T>>
149 for BDDKeyPrepared<CBT, LWE, BRA, BE>
150where
151 T: UnsignedInteger,
152 CBT: DataRef,
153 OUT: DataMut,
154 IN: DataRef,
155 LWE: DataRef,
156 BRA: BlindRotationAlgo,
157 BE: Backend,
158 Module<BE>: VmpPrepare<BE>
159 + VecZnxRotate
160 + VecZnxDftAllocBytes
161 + VmpApplyDftToDftTmpBytes
162 + VecZnxBigNormalizeTmpBytes
163 + VmpApplyDftToDft<BE>
164 + VmpApplyDftToDftAdd<BE>
165 + VecZnxDftApply<BE>
166 + VecZnxIdftApplyConsume<BE>
167 + VecZnxBigAddSmallInplace<BE>
168 + VecZnxBigNormalize<BE>
169 + VecZnxNormalize<BE>
170 + VecZnxNormalizeTmpBytes,
171 Scratch<BE>: ScratchAvailable + TakeVecZnxDft<BE> + TakeGLWECt + TakeVecZnx + TakeGGSW,
172 CircuitBootstrappingKeyPrepared<CBT, BRA, BE>: CirtuitBootstrappingExecute<BE>,
173{
174 fn prepare(
175 &self,
176 module: &Module<BE>,
177 out: &mut FheUintBlocksPrep<OUT, BE, T>,
178 bits: &FheUintBlocks<IN, T>,
179 scratch: &mut Scratch<BE>,
180 ) {
181 #[cfg(debug_assertions)]
182 {
183 assert_eq!(out.blocks.len(), bits.blocks.len());
184 }
185 let mut lwe: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(&bits.blocks[0]); //TODO: add TakeLWE
186 let (mut tmp_ggsw, scratch_1) = scratch.take_ggsw(out);
187 for (dst, src) in out.blocks.iter_mut().zip(bits.blocks.iter()) {
188 lwe.from_glwe(module, src, &self.ks, scratch_1);
189 self.cbt
190 .execute_to_constant(module, &mut tmp_ggsw, &lwe, 1, 1, scratch_1);
191 dst.prepare(module, &tmp_ggsw, scratch_1);
192 }
193 }
194}
195
196#[cfg(test)]
197impl<CBT, OUT, IN, LWE, BRA, BE, T> FheUintPrepare<BE, FheUintBlocksPrepDebug<OUT, T>, FheUintBlocks<IN, T>>
198 for BDDKeyPrepared<CBT, LWE, BRA, BE>
199where
200 T: UnsignedInteger,
201 CBT: DataRef,
202 OUT: DataMut,
203 IN: DataRef,
204 LWE: DataRef,
205 BRA: BlindRotationAlgo,
206 BE: Backend,
207 Module<BE>: VmpPrepare<BE>
208 + VecZnxRotate
209 + VecZnxDftAllocBytes
210 + VmpApplyDftToDftTmpBytes
211 + VecZnxBigNormalizeTmpBytes
212 + VmpApplyDftToDft<BE>
213 + VmpApplyDftToDftAdd<BE>
214 + VecZnxDftApply<BE>
215 + VecZnxIdftApplyConsume<BE>
216 + VecZnxBigAddSmallInplace<BE>
217 + VecZnxBigNormalize<BE>
218 + VecZnxNormalize<BE>
219 + VecZnxNormalizeTmpBytes,
220 Scratch<BE>: ScratchAvailable + TakeVecZnxDft<BE> + TakeGLWECt + TakeVecZnx + TakeGGSW,
221 CircuitBootstrappingKeyPrepared<CBT, BRA, BE>: CirtuitBootstrappingExecute<BE>,
222{
223 fn prepare(
224 &self,
225 module: &Module<BE>,
226 out: &mut FheUintBlocksPrepDebug<OUT, T>,
227 bits: &FheUintBlocks<IN, T>,
228 scratch: &mut Scratch<BE>,
229 ) {
230 #[cfg(debug_assertions)]
231 {
232 assert_eq!(out.blocks.len(), bits.blocks.len());
233 }
234 let mut lwe: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(&bits.blocks[0]); //TODO: add TakeLWE
235 for (dst, src) in out.blocks.iter_mut().zip(bits.blocks.iter()) {
236 lwe.from_glwe(module, src, &self.ks, scratch);
237 self.cbt
238 .execute_to_constant(module, dst, &lwe, 1, 1, scratch);
239 }
240 }
241}