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