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