poulpy/poulpy-core/src/tests/test_suite/conversion.rs
poulpy-core/src/tests/test_suite/conversion.rsRaw
1use poulpy_hal::{
2 api::{
3 ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolBytesOf, SvpPrepare,
4 VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphismInplace, VecZnxBigAddInplace,
5 VecZnxBigAddSmallInplace, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxDftApply,
6 VecZnxDftBytesOf, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace,
7 VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing, VmpApplyDftToDft, VmpApplyDftToDftAdd,
8 VmpApplyDftToDftTmpBytes, VmpPMatAlloc, VmpPrepare, ZnAddNormal, ZnFillUniform, ZnNormalizeInplace,
9 },
10 layouts::{Backend, Module, ScratchOwned, ZnxView},
11 oep::{
12 ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl,
13 TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl,
14 },
15 source::Source,
16};
17
18use crate::layouts::{
19 Base2K, Degree, Dnum, GLWE, GLWELayout, GLWEPlaintext, GLWESecret, GLWEToLWEKeyLayout, GLWEToLWESwitchingKey, LWE,
20 LWECiphertextLayout, LWEPlaintext, LWESecret, LWEToGLWESwitchingKey, LWEToGLWESwitchingKeyLayout, Rank, TorusPrecision,
21 prepared::{GLWESecretPrepared, GLWEToLWESwitchingKeyPrepared, LWEToGLWESwitchingKeyPrepared, PrepareAlloc},
22};
23
24pub fn test_lwe_to_glwe<B>(module: &Module<B>)
25where
26 Module<B>: VecZnxDftBytesOf
27 + VecZnxBigNormalize<B>
28 + VecZnxDftApply<B>
29 + SvpApplyDftToDftInplace<B>
30 + VecZnxIdftApplyConsume<B>
31 + VecZnxFillUniform
32 + VecZnxSubInplace
33 + VecZnxAddInplace
34 + VecZnxNormalizeInplace<B>
35 + VecZnxAddNormal
36 + VecZnxNormalize<B>
37 + VecZnxSub
38 + SvpPrepare<B>
39 + SvpPPolBytesOf
40 + SvpPPolAlloc<B>
41 + VecZnxBigBytesOf
42 + VecZnxBigAddInplace<B>
43 + VecZnxBigAddSmallInplace<B>
44 + VecZnxNormalizeTmpBytes
45 + VecZnxAddScalarInplace
46 + VmpPMatAlloc<B>
47 + VmpPrepare<B>
48 + VmpApplyDftToDftTmpBytes
49 + VmpApplyDftToDft<B>
50 + VmpApplyDftToDftAdd<B>
51 + VecZnxBigNormalizeTmpBytes
52 + VecZnxSwitchRing
53 + VecZnxAutomorphismInplace<B>
54 + ZnNormalizeInplace<B>
55 + ZnFillUniform
56 + ZnAddNormal,
57 B: Backend
58 + TakeVecZnxDftImpl<B>
59 + TakeVecZnxBigImpl<B>
60 + TakeSvpPPolImpl<B>
61 + ScratchOwnedAllocImpl<B>
62 + ScratchOwnedBorrowImpl<B>
63 + ScratchAvailableImpl<B>
64 + TakeScalarZnxImpl<B>
65 + TakeVecZnxImpl<B>,
66{
67 let n_glwe: Degree = Degree(module.n() as u32);
68 let n_lwe: Degree = Degree(22);
69
70 let rank: Rank = Rank(2);
71 let k_lwe_pt: TorusPrecision = TorusPrecision(8);
72
73 let mut source_xs: Source = Source::new([0u8; 32]);
74 let mut source_xa: Source = Source::new([0u8; 32]);
75 let mut source_xe: Source = Source::new([0u8; 32]);
76
77 let lwe_to_glwe_infos: LWEToGLWESwitchingKeyLayout = LWEToGLWESwitchingKeyLayout {
78 n: n_glwe,
79 base2k: Base2K(17),
80 k: TorusPrecision(51),
81 dnum: Dnum(2),
82 rank_out: rank,
83 };
84
85 let glwe_infos: GLWELayout = GLWELayout {
86 n: n_glwe,
87 base2k: Base2K(17),
88 k: TorusPrecision(34),
89 rank,
90 };
91
92 let lwe_infos: LWECiphertextLayout = LWECiphertextLayout {
93 n: n_lwe,
94 base2k: Base2K(17),
95 k: TorusPrecision(34),
96 };
97
98 let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
99 LWEToGLWESwitchingKey::encrypt_sk_tmp_bytes(module, &lwe_to_glwe_infos)
100 | GLWE::from_lwe_tmp_bytes(module, &glwe_infos, &lwe_infos, &lwe_to_glwe_infos)
101 | GLWE::decrypt_tmp_bytes(module, &glwe_infos),
102 );
103
104 let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
105 sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
106
107 let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch.borrow());
108
109 let mut sk_lwe: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe);
110 sk_lwe.fill_ternary_prob(0.5, &mut source_xs);
111
112 let data: i64 = 17;
113
114 let mut lwe_pt: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc_from_infos(&lwe_infos);
115 lwe_pt.encode_i64(data, k_lwe_pt);
116
117 let mut lwe_ct: LWE<Vec<u8>> = LWE::alloc_from_infos(&lwe_infos);
118 lwe_ct.encrypt_sk(module, &lwe_pt, &sk_lwe, &mut source_xa, &mut source_xe);
119
120 let mut ksk: LWEToGLWESwitchingKey<Vec<u8>> = LWEToGLWESwitchingKey::alloc_from_infos(&lwe_to_glwe_infos);
121
122 ksk.encrypt_sk(
123 module,
124 &sk_lwe,
125 &sk_glwe,
126 &mut source_xa,
127 &mut source_xe,
128 scratch.borrow(),
129 );
130
131 let mut glwe_ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos);
132
133 let ksk_prepared: LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow());
134
135 glwe_ct.from_lwe(module, &lwe_ct, &ksk_prepared, scratch.borrow());
136
137 let mut glwe_pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos);
138 glwe_ct.decrypt(module, &mut glwe_pt, &sk_glwe_prepared, scratch.borrow());
139
140 assert_eq!(glwe_pt.data.at(0, 0)[0], lwe_pt.data.at(0, 0)[0]);
141}
142
143pub fn test_glwe_to_lwe<B>(module: &Module<B>)
144where
145 Module<B>: VecZnxDftBytesOf
146 + VecZnxBigNormalize<B>
147 + VecZnxDftApply<B>
148 + SvpApplyDftToDftInplace<B>
149 + VecZnxIdftApplyConsume<B>
150 + VecZnxFillUniform
151 + VecZnxSubInplace
152 + VecZnxAddInplace
153 + VecZnxNormalizeInplace<B>
154 + VecZnxAddNormal
155 + VecZnxNormalize<B>
156 + VecZnxSub
157 + SvpPrepare<B>
158 + SvpPPolBytesOf
159 + SvpPPolAlloc<B>
160 + VecZnxBigBytesOf
161 + VecZnxBigAddInplace<B>
162 + VecZnxBigAddSmallInplace<B>
163 + VecZnxNormalizeTmpBytes
164 + VecZnxAddScalarInplace
165 + VmpPMatAlloc<B>
166 + VmpPrepare<B>
167 + VmpApplyDftToDftTmpBytes
168 + VmpApplyDftToDft<B>
169 + VmpApplyDftToDftAdd<B>
170 + VecZnxBigNormalizeTmpBytes
171 + VecZnxSwitchRing
172 + VecZnxAutomorphismInplace<B>
173 + ZnNormalizeInplace<B>,
174 B: Backend
175 + TakeVecZnxDftImpl<B>
176 + TakeVecZnxBigImpl<B>
177 + TakeSvpPPolImpl<B>
178 + ScratchOwnedAllocImpl<B>
179 + ScratchOwnedBorrowImpl<B>
180 + ScratchAvailableImpl<B>
181 + TakeScalarZnxImpl<B>
182 + TakeVecZnxImpl<B>,
183{
184 let n_glwe: Degree = Degree(module.n() as u32);
185 let n_lwe: Degree = Degree(22);
186
187 let rank: Rank = Rank(2);
188 let k_lwe_pt: TorusPrecision = TorusPrecision(8);
189
190 let glwe_to_lwe_infos: GLWEToLWEKeyLayout = GLWEToLWEKeyLayout {
191 n: n_glwe,
192 base2k: Base2K(17),
193 k: TorusPrecision(51),
194 dnum: Dnum(2),
195 rank_in: rank,
196 };
197
198 let glwe_infos: GLWELayout = GLWELayout {
199 n: n_glwe,
200 base2k: Base2K(17),
201 k: TorusPrecision(34),
202 rank,
203 };
204
205 let lwe_infos: LWECiphertextLayout = LWECiphertextLayout {
206 n: n_lwe,
207 base2k: Base2K(17),
208 k: TorusPrecision(34),
209 };
210
211 let mut source_xs: Source = Source::new([0u8; 32]);
212 let mut source_xa: Source = Source::new([0u8; 32]);
213 let mut source_xe: Source = Source::new([0u8; 32]);
214
215 let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
216 GLWEToLWESwitchingKey::encrypt_sk_tmp_bytes(module, &glwe_to_lwe_infos)
217 | LWE::from_glwe_tmp_bytes(module, &lwe_infos, &glwe_infos, &glwe_to_lwe_infos)
218 | GLWE::decrypt_tmp_bytes(module, &glwe_infos),
219 );
220
221 let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
222 sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
223
224 let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch.borrow());
225
226 let mut sk_lwe: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe);
227 sk_lwe.fill_ternary_prob(0.5, &mut source_xs);
228
229 let data: i64 = 17;
230 let mut glwe_pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos);
231 glwe_pt.encode_coeff_i64(data, k_lwe_pt, 0);
232
233 let mut glwe_ct = GLWE::alloc_from_infos(&glwe_infos);
234 glwe_ct.encrypt_sk(
235 module,
236 &glwe_pt,
237 &sk_glwe_prepared,
238 &mut source_xa,
239 &mut source_xe,
240 scratch.borrow(),
241 );
242
243 let mut ksk: GLWEToLWESwitchingKey<Vec<u8>> = GLWEToLWESwitchingKey::alloc(&glwe_to_lwe_infos);
244
245 ksk.encrypt_sk(
246 module,
247 &sk_lwe,
248 &sk_glwe,
249 &mut source_xa,
250 &mut source_xe,
251 scratch.borrow(),
252 );
253
254 let mut lwe_ct: LWE<Vec<u8>> = LWE::alloc_from_infos(&lwe_infos);
255
256 let ksk_prepared: GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow());
257
258 lwe_ct.from_glwe(module, &glwe_ct, &ksk_prepared, scratch.borrow());
259
260 let mut lwe_pt: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc_from_infos(&lwe_infos);
261 lwe_ct.decrypt(module, &mut lwe_pt, &sk_lwe);
262
263 assert_eq!(glwe_pt.data.at(0, 0)[0], lwe_pt.data.at(0, 0)[0]);
264}