arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/tests/generics/automorphism/glwe_ct.rs
core/src/tests/generics/automorphism/glwe_ct.rsRaw
  1use 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};
 16use sampling::source::Source;
 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
 26pub fn test_glwe_automorphism<B: Backend>(
 27    module: &Module<B>,
 28    basek: usize,
 29    p: i64,
 30    k_out: usize,
 31    k_in: usize,
 32    k_ksk: usize,
 33    digits: usize,
 34    rank: usize,
 35    sigma: f64,
 36) where
 37    Module<B>: VecZnxDftAllocBytes
 38        + VecZnxBigNormalize<B>
 39        + VecZnxDftFromVecZnx<B>
 40        + SvpApplyInplace<B>
 41        + VecZnxDftToVecZnxBigConsume<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: TakeVecZnxDftImpl<B>
 67        + TakeVecZnxBigImpl<B>
 68        + TakeSvpPPolImpl<B>
 69        + ScratchOwnedAllocImpl<B>
 70        + ScratchOwnedBorrowImpl<B>
 71        + ScratchAvailableImpl<B>
 72        + TakeScalarZnxImpl<B>
 73        + TakeVecZnxImpl<B>,
 74{
 75    let n: usize = module.n();
 76    let rows: usize = k_in.div_ceil(basek * digits);
 77
 78    let mut autokey: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
 79    let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_in, rank);
 80    let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_out, rank);
 81    let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k_in);
 82
 83    let mut source_xs: Source = Source::new([0u8; 32]);
 84    let mut source_xe: Source = Source::new([0u8; 32]);
 85    let mut source_xa: Source = Source::new([0u8; 32]);
 86
 87    module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_in, &mut source_xa);
 88
 89    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
 90        GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, n, basek, autokey.k(), rank)
 91            | GLWECiphertext::decrypt_scratch_space(module, n, basek, ct_out.k())
 92            | GLWECiphertext::encrypt_sk_scratch_space(module, n, basek, ct_in.k())
 93            | GLWECiphertext::automorphism_scratch_space(
 94                module,
 95                n,
 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        sigma,
116        scratch.borrow(),
117    );
118
119    ct_in.encrypt_sk(
120        module,
121        &pt_want,
122        &sk_prepared,
123        &mut source_xa,
124        &mut source_xe,
125        sigma,
126        scratch.borrow(),
127    );
128
129    let mut autokey_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
130        GGLWEAutomorphismKeyPrepared::alloc(module, n, basek, k_ksk, rows, digits, rank);
131    autokey_prepared.prepare(module, &autokey, scratch.borrow());
132
133    ct_out.automorphism(module, &ct_in, &autokey_prepared, scratch.borrow());
134
135    let max_noise: f64 = log2_std_noise_gglwe_product(
136        module.n() as f64,
137        basek * digits,
138        0.5,
139        0.5,
140        0f64,
141        sigma * sigma,
142        0f64,
143        rank as f64,
144        k_in,
145        k_ksk,
146    );
147
148    module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
149
150    ct_out.assert_noise(module, &sk_prepared, &pt_want, max_noise + 1.0);
151}
152
153pub fn test_glwe_automorphism_inplace<B: Backend>(
154    module: &Module<B>,
155    basek: usize,
156    p: i64,
157    k_ct: usize,
158    k_ksk: usize,
159    digits: usize,
160    rank: usize,
161    sigma: f64,
162) where
163    Module<B>: VecZnxDftAllocBytes
164        + VecZnxBigNormalize<B>
165        + VecZnxDftFromVecZnx<B>
166        + SvpApplyInplace<B>
167        + VecZnxDftToVecZnxBigConsume<B>
168        + VecZnxNormalizeTmpBytes
169        + VecZnxFillUniform
170        + VecZnxSubABInplace
171        + VecZnxAddInplace
172        + VecZnxNormalizeInplace<B>
173        + VecZnxAddNormal
174        + VecZnxNormalize<B>
175        + VecZnxSub
176        + SvpPrepare<B>
177        + SvpPPolAllocBytes
178        + SvpPPolAlloc<B>
179        + VecZnxBigAllocBytes
180        + VecZnxBigAddInplace<B>
181        + VecZnxBigAddSmallInplace<B>
182        + VmpApplyTmpBytes
183        + VecZnxBigNormalizeTmpBytes
184        + VmpApply<B>
185        + VmpApplyAdd<B>
186        + VecZnxAutomorphism
187        + VecZnxSwithcDegree
188        + VecZnxAddScalarInplace
189        + VecZnxAutomorphismInplace
190        + VmpPMatAlloc<B>
191        + VmpPrepare<B>,
192    B: TakeVecZnxDftImpl<B>
193        + TakeVecZnxBigImpl<B>
194        + TakeSvpPPolImpl<B>
195        + ScratchOwnedAllocImpl<B>
196        + ScratchOwnedBorrowImpl<B>
197        + ScratchAvailableImpl<B>
198        + TakeScalarZnxImpl<B>
199        + TakeVecZnxImpl<B>,
200{
201    let n: usize = module.n();
202    let rows: usize = k_ct.div_ceil(basek * digits);
203
204    let mut autokey: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
205    let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_ct, rank);
206    let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k_ct);
207
208    let mut source_xs: Source = Source::new([0u8; 32]);
209    let mut source_xe: Source = Source::new([0u8; 32]);
210    let mut source_xa: Source = Source::new([0u8; 32]);
211
212    module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_ct, &mut source_xa);
213
214    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
215        GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, n, basek, autokey.k(), rank)
216            | GLWECiphertext::decrypt_scratch_space(module, n, basek, ct.k())
217            | GLWECiphertext::encrypt_sk_scratch_space(module, n, basek, ct.k())
218            | GLWECiphertext::automorphism_inplace_scratch_space(module, n, basek, ct.k(), autokey.k(), digits, rank),
219    );
220
221    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
222    sk.fill_ternary_prob(0.5, &mut source_xs);
223    let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
224
225    autokey.encrypt_sk(
226        module,
227        p,
228        &sk,
229        &mut source_xa,
230        &mut source_xe,
231        sigma,
232        scratch.borrow(),
233    );
234
235    ct.encrypt_sk(
236        module,
237        &pt_want,
238        &sk_prepared,
239        &mut source_xa,
240        &mut source_xe,
241        sigma,
242        scratch.borrow(),
243    );
244
245    let mut autokey_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
246        GGLWEAutomorphismKeyPrepared::alloc(module, n, basek, k_ksk, rows, digits, rank);
247    autokey_prepared.prepare(module, &autokey, scratch.borrow());
248
249    ct.automorphism_inplace(module, &autokey_prepared, scratch.borrow());
250
251    let max_noise: f64 = log2_std_noise_gglwe_product(
252        module.n() as f64,
253        basek * digits,
254        0.5,
255        0.5,
256        0f64,
257        sigma * sigma,
258        0f64,
259        rank as f64,
260        k_ct,
261        k_ksk,
262    );
263
264    module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
265
266    ct.assert_noise(module, &sk_prepared, &pt_want, max_noise + 1.0);
267}