poulpy/poulpy-core/src/encryption/ggsw_ct.rs
poulpy-core/src/encryption/ggsw_ct.rsRaw
1use poulpy_hal::{
2 api::{ModuleN, VecZnxAddScalarInplace, VecZnxDftBytesOf, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes},
3 layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, ScalarZnxToRef, Scratch, VecZnx, ZnxZero},
4 source::Source,
5};
6
7use crate::{
8 SIGMA, ScratchTakeCore,
9 encryption::glwe_ct::GLWEEncryptSkInternal,
10 layouts::{
11 GGSW, GGSWInfos, GGSWToMut, GLWE, GLWEInfos, LWEInfos,
12 prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
13 },
14};
15
16impl GGSW<Vec<u8>> {
17 pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
18 where
19 A: GGSWInfos,
20 M: GGSWEncryptSk<BE>,
21 {
22 module.ggsw_encrypt_sk_tmp_bytes(infos)
23 }
24 // pub fn encrypt_sk_tmp_bytes<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
25 // where
26 // A: GGSWInfos,
27 // Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftBytesOf,
28 // {
29 // let size = infos.size();
30 // GLWE::encrypt_sk_tmp_bytes(module, &infos.glwe_layout())
31 // + VecZnx::bytes_of(module.n(), (infos.rank() + 1).into(), size)
32 // + VecZnx::bytes_of(module.n(), 1, size)
33 // + module.bytes_of_vec_znx_dft((infos.rank() + 1).into(), size)
34 // }
35}
36
37impl<DataSelf: DataMut> GGSW<DataSelf> {
38 #[allow(clippy::too_many_arguments)]
39 pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>(
40 &mut self,
41 module: &Module<B>,
42 pt: &ScalarZnx<DataPt>,
43 sk: &GLWESecretPrepared<DataSk, B>,
44 source_xa: &mut Source,
45 source_xe: &mut Source,
46 scratch: &mut Scratch<B>,
47 ) where
48 Module<B>: GGSWEncryptSk<B>,
49 {
50 module.ggsw_encrypt_sk(self, pt, sk, source_xa, source_xe, scratch);
51 }
52}
53
54pub trait GGSWEncryptSk<B: Backend> {
55 fn ggsw_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
56 where
57 A: GGSWInfos;
58
59 fn ggsw_encrypt_sk<R, P, S>(
60 &self,
61 res: &mut R,
62 pt: &P,
63 sk: &S,
64 source_xa: &mut Source,
65 source_xe: &mut Source,
66 scratch: &mut Scratch<B>,
67 ) where
68 R: GGSWToMut,
69 P: ScalarZnxToRef,
70 S: GLWESecretPreparedToRef<B>;
71}
72
73impl<B: Backend> GGSWEncryptSk<B> for Module<B>
74where
75 Module<B>: ModuleN
76 + GLWEEncryptSkInternal<B>
77 + VecZnxAddScalarInplace
78 + VecZnxNormalizeInplace<B>
79 + VecZnxDftBytesOf
80 + VecZnxNormalizeTmpBytes,
81 Scratch<B>: ScratchTakeCore<B>,
82{
83
84 fn ggsw_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
85 where
86 A: GGSWInfos,
87 {
88 let size = infos.size();
89 GLWE::encrypt_sk_tmp_bytes(self, &infos.glwe_layout())
90 + VecZnx::bytes_of(self.n(), (infos.rank() + 1).into(), size)
91 + VecZnx::bytes_of(self.n(), 1, size)
92 + self.bytes_of_vec_znx_dft((infos.rank() + 1).into(), size)
93 }
94
95 fn ggsw_encrypt_sk<R, P, S>(
96 &self,
97 res: &mut R,
98 pt: &P,
99 sk: &S,
100 source_xa: &mut Source,
101 source_xe: &mut Source,
102 scratch: &mut Scratch<B>,
103 ) where
104 R: GGSWToMut,
105 P: ScalarZnxToRef,
106 S: GLWESecretPreparedToRef<B>,
107 {
108 let res: &mut GGSW<&mut [u8]> = &mut res.to_mut();
109 let pt: &ScalarZnx<&[u8]> = &pt.to_ref();
110 let sk: &GLWESecretPrepared<&[u8], B> = &sk.to_ref();
111
112 #[cfg(debug_assertions)]
113 {
114 use poulpy_hal::layouts::ZnxInfos;
115
116 assert_eq!(res.rank(), sk.rank());
117 assert_eq!(res.n(), self.n() as u32);
118 assert_eq!(pt.n(), self.n());
119 assert_eq!(sk.n(), self.n() as u32);
120 }
121
122 let k: usize = res.k().into();
123 let base2k: usize = res.base2k().into();
124 let rank: usize = res.rank().into();
125 let dsize: usize = res.dsize().into();
126 let cols: usize = (rank + 1).into();
127
128 let (mut tmp_pt, scratch_1) = scratch.take_glwe_pt(self, &res.glwe_layout());
129
130 for row_i in 0..res.dnum().into() {
131 tmp_pt.data.zero();
132 // Adds the scalar_znx_pt to the i-th limb of the vec_znx_pt
133 self.vec_znx_add_scalar_inplace(&mut tmp_pt.data, 0, (dsize - 1) + row_i * dsize, pt, 0);
134 self.vec_znx_normalize_inplace(base2k, &mut tmp_pt.data, 0, scratch_1);
135 for col_j in 0..rank + 1 {
136 self.glwe_encrypt_sk_internal(
137 base2k,
138 k,
139 res.at_mut(row_i, col_j).data_mut(),
140 cols,
141 false,
142 Some((&tmp_pt, col_j)),
143 sk,
144 source_xa,
145 source_xe,
146 SIGMA,
147 scratch_1,
148 );
149 }
150 }
151 }
152}