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, 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, GLWEToLWEKeyLayout,
 20    GLWEToLWESwitchingKey, LWECiphertext, LWECiphertextLayout, LWEPlaintext, LWESecret, LWEToGLWESwitchingKey,
 21    LWEToGLWESwitchingKeyLayout, Rank, 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        GLWEToLWESwitchingKey::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: GLWEToLWESwitchingKey<Vec<u8>> = GLWEToLWESwitchingKey::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}