poulpy_core/decryption/
lwe_ct.rs1use poulpy_hal::{
2 api::{ScratchOwnedAlloc, ScratchOwnedBorrow, ZnNormalizeInplace},
3 layouts::{Backend, DataMut, DataRef, Module, ScratchOwned, ZnxView, ZnxViewMut},
4 oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl},
5};
6
7use crate::layouts::{LWECiphertext, LWEInfos, LWEPlaintext, LWESecret};
8
9impl<DataSelf> LWECiphertext<DataSelf>
10where
11 DataSelf: DataRef,
12{
13 pub fn decrypt<DataPt, DataSk, B>(&self, module: &Module<B>, pt: &mut LWEPlaintext<DataPt>, sk: &LWESecret<DataSk>)
14 where
15 DataPt: DataMut,
16 DataSk: DataRef,
17 Module<B>: ZnNormalizeInplace<B>,
18 B: Backend + ScratchOwnedAllocImpl<B> + ScratchOwnedBorrowImpl<B>,
19 {
20 #[cfg(debug_assertions)]
21 {
22 assert_eq!(self.n(), sk.n());
23 }
24
25 (0..pt.size().min(self.size())).for_each(|i| {
26 pt.data.at_mut(0, i)[0] = self.data.at(0, i)[0]
27 + self.data.at(0, i)[1..]
28 .iter()
29 .zip(sk.data.at(0, 0))
30 .map(|(x, y)| x * y)
31 .sum::<i64>();
32 });
33 module.zn_normalize_inplace(
34 1,
35 self.base2k().into(),
36 &mut pt.data,
37 0,
38 ScratchOwned::alloc(size_of::<i64>()).borrow(),
39 );
40 pt.base2k = self.base2k();
41 pt.k = crate::layouts::TorusPrecision(self.k().0.min(pt.size() as u32 * self.base2k().0));
42 }
43}