arnaucube
arnaucube/poulpyPublic Self-hosted repository
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}