arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/tests/generics/automorphism/glwe_ct.rs
poulpy-core/src/tests/generics/automorphism/glwe_ct.rsRaw
  1use poulpy_backend::hal::{
  2    api::{
  3        ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyInplace, SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare, VecZnxAddInplace,
  4        VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxAutomorphismInplace, VecZnxBigAddInplace,
  5        VecZnxBigAddSmallInplace, VecZnxBigAllocBytes, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxDftAllocBytes,
  6        VecZnxDftFromVecZnx, VecZnxDftToVecZnxBigConsume, VecZnxFillUniform, VecZnxNormalize, VecZnxNormalizeInplace,
  7        VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace, VecZnxSwithcDegree, VmpApply, VmpApplyAdd, VmpApplyTmpBytes,
  8        VmpPMatAlloc, VmpPrepare,
  9    },
 10    layouts::{Backend, Module, ScratchOwned},
 11    oep::{
 12        ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl,
 13        TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl,
 14    },
 15    source::Source,
 16};
 17
 18use crate::{
 19    layouts::{
 20        GGLWEAutomorphismKey, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos,
 21        prepared::{GGLWEAutomorphismKeyPrepared, GLWESecretPrepared, Prepare, PrepareAlloc},
 22    },
 23    noise::log2_std_noise_gglwe_product,
 24};
 25
 26#[allow(clippy::too_many_arguments)]
 27pub fn test_glwe_automorphism<B>(
 28    module: &Module<B>,
 29    basek: usize,
 30    p: i64,
 31    k_out: usize,
 32    k_in: usize,
 33    k_ksk: usize,
 34    digits: usize,
 35    rank: usize,
 36    sigma: f64,
 37) where
 38    Module<B>: VecZnxDftAllocBytes
 39        + VecZnxBigNormalize<B>
 40        + VecZnxDftFromVecZnx<B>
 41        + SvpApplyInplace<B>
 42        + VecZnxDftToVecZnxBigConsume<B>
 43        + VecZnxNormalizeTmpBytes
 44        + VecZnxFillUniform
 45        + VecZnxSubABInplace
 46        + VecZnxAddInplace
 47        + VecZnxNormalizeInplace<B>
 48        + VecZnxAddNormal
 49        + VecZnxNormalize<B>
 50        + VecZnxSub
 51        + SvpPrepare<B>
 52        + SvpPPolAllocBytes
 53        + SvpPPolAlloc<B>
 54        + VecZnxBigAllocBytes
 55        + VecZnxBigAddInplace<B>
 56        + VecZnxBigAddSmallInplace<B>
 57        + VmpApplyTmpBytes
 58        + VecZnxBigNormalizeTmpBytes
 59        + VmpApply<B>
 60        + VmpApplyAdd<B>
 61        + VecZnxAutomorphism
 62        + VecZnxSwithcDegree
 63        + VecZnxAddScalarInplace
 64        + VecZnxAutomorphismInplace
 65        + VmpPMatAlloc<B>
 66        + VmpPrepare<B>,
 67    B: Backend
 68        + TakeVecZnxDftImpl<B>
 69        + TakeVecZnxBigImpl<B>
 70        + TakeSvpPPolImpl<B>
 71        + ScratchOwnedAllocImpl<B>
 72        + ScratchOwnedBorrowImpl<B>
 73        + ScratchAvailableImpl<B>
 74        + TakeScalarZnxImpl<B>
 75        + TakeVecZnxImpl<B>,
 76{
 77    let n: usize = module.n();
 78    let rows: usize = k_in.div_ceil(basek * digits);
 79
 80    let mut autokey: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
 81    let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_in, rank);
 82    let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_out, rank);
 83    let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k_in);
 84
 85    let mut source_xs: Source = Source::new([0u8; 32]);
 86    let mut source_xe: Source = Source::new([0u8; 32]);
 87    let mut source_xa: Source = Source::new([0u8; 32]);
 88
 89    module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_in, &mut source_xa);
 90
 91    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
 92        GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, n, basek, autokey.k(), rank)
 93            | GLWECiphertext::decrypt_scratch_space(module, n, basek, ct_out.k())
 94            | GLWECiphertext::encrypt_sk_scratch_space(module, n, basek, ct_in.k())
 95            | GLWECiphertext::automorphism_scratch_space(
 96                module,
 97                n,
 98                basek,
 99                ct_out.k(),
100                ct_in.k(),
101                autokey.k(),
102                digits,
103                rank,
104            ),
105    );
106
107    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
108    sk.fill_ternary_prob(0.5, &mut source_xs);
109    let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
110
111    autokey.encrypt_sk(
112        module,
113        p,
114        &sk,
115        &mut source_xa,
116        &mut source_xe,
117        sigma,
118        scratch.borrow(),
119    );
120
121    ct_in.encrypt_sk(
122        module,
123        &pt_want,
124        &sk_prepared,
125        &mut source_xa,
126        &mut source_xe,
127        sigma,
128        scratch.borrow(),
129    );
130
131    let mut autokey_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
132        GGLWEAutomorphismKeyPrepared::alloc(module, n, basek, k_ksk, rows, digits, rank);
133    autokey_prepared.prepare(module, &autokey, scratch.borrow());
134
135    ct_out.automorphism(module, &ct_in, &autokey_prepared, scratch.borrow());
136
137    let max_noise: f64 = log2_std_noise_gglwe_product(
138        module.n() as f64,
139        basek * digits,
140        0.5,
141        0.5,
142        0f64,
143        sigma * sigma,
144        0f64,
145        rank as f64,
146        k_in,
147        k_ksk,
148    );
149
150    module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
151
152    ct_out.assert_noise(module, &sk_prepared, &pt_want, max_noise + 1.0);
153}
154
155#[allow(clippy::too_many_arguments)]
156pub fn test_glwe_automorphism_inplace<B>(
157    module: &Module<B>,
158    basek: usize,
159    p: i64,
160    k_ct: usize,
161    k_ksk: usize,
162    digits: usize,
163    rank: usize,
164    sigma: f64,
165) where
166    Module<B>: VecZnxDftAllocBytes
167        + VecZnxBigNormalize<B>
168        + VecZnxDftFromVecZnx<B>
169        + SvpApplyInplace<B>
170        + VecZnxDftToVecZnxBigConsume<B>
171        + VecZnxNormalizeTmpBytes
172        + VecZnxFillUniform
173        + VecZnxSubABInplace
174        + VecZnxAddInplace
175        + VecZnxNormalizeInplace<B>
176        + VecZnxAddNormal
177        + VecZnxNormalize<B>
178        + VecZnxSub
179        + SvpPrepare<B>
180        + SvpPPolAllocBytes
181        + SvpPPolAlloc<B>
182        + VecZnxBigAllocBytes
183        + VecZnxBigAddInplace<B>
184        + VecZnxBigAddSmallInplace<B>
185        + VmpApplyTmpBytes
186        + VecZnxBigNormalizeTmpBytes
187        + VmpApply<B>
188        + VmpApplyAdd<B>
189        + VecZnxAutomorphism
190        + VecZnxSwithcDegree
191        + VecZnxAddScalarInplace
192        + VecZnxAutomorphismInplace
193        + VmpPMatAlloc<B>
194        + VmpPrepare<B>,
195    B: Backend
196        + TakeVecZnxDftImpl<B>
197        + TakeVecZnxBigImpl<B>
198        + TakeSvpPPolImpl<B>
199        + ScratchOwnedAllocImpl<B>
200        + ScratchOwnedBorrowImpl<B>
201        + ScratchAvailableImpl<B>
202        + TakeScalarZnxImpl<B>
203        + TakeVecZnxImpl<B>,
204{
205    let n: usize = module.n();
206    let rows: usize = k_ct.div_ceil(basek * digits);
207
208    let mut autokey: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
209    let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_ct, rank);
210    let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k_ct);
211
212    let mut source_xs: Source = Source::new([0u8; 32]);
213    let mut source_xe: Source = Source::new([0u8; 32]);
214    let mut source_xa: Source = Source::new([0u8; 32]);
215
216    module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_ct, &mut source_xa);
217
218    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
219        GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, n, basek, autokey.k(), rank)
220            | GLWECiphertext::decrypt_scratch_space(module, n, basek, ct.k())
221            | GLWECiphertext::encrypt_sk_scratch_space(module, n, basek, ct.k())
222            | GLWECiphertext::automorphism_inplace_scratch_space(module, n, basek, ct.k(), autokey.k(), digits, rank),
223    );
224
225    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
226    sk.fill_ternary_prob(0.5, &mut source_xs);
227    let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
228
229    autokey.encrypt_sk(
230        module,
231        p,
232        &sk,
233        &mut source_xa,
234        &mut source_xe,
235        sigma,
236        scratch.borrow(),
237    );
238
239    ct.encrypt_sk(
240        module,
241        &pt_want,
242        &sk_prepared,
243        &mut source_xa,
244        &mut source_xe,
245        sigma,
246        scratch.borrow(),
247    );
248
249    let mut autokey_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
250        GGLWEAutomorphismKeyPrepared::alloc(module, n, basek, k_ksk, rows, digits, rank);
251    autokey_prepared.prepare(module, &autokey, scratch.borrow());
252
253    ct.automorphism_inplace(module, &autokey_prepared, scratch.borrow());
254
255    let max_noise: f64 = log2_std_noise_gglwe_product(
256        module.n() as f64,
257        basek * digits,
258        0.5,
259        0.5,
260        0f64,
261        sigma * sigma,
262        0f64,
263        rank as f64,
264        k_ct,
265        k_ksk,
266    );
267
268    module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
269
270    ct.assert_noise(module, &sk_prepared, &pt_want, max_noise + 1.0);
271}