arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/tests/generics/automorphism/ggsw_ct.rs
core/src/tests/generics/automorphism/ggsw_ct.rsRaw
  1use backend::hal::{
  2    api::{
  3        ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApply, SvpApplyInplace, SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare,
  4        VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxAutomorphismInplace,
  5        VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigAlloc, VecZnxBigAllocBytes, VecZnxBigNormalize,
  6        VecZnxBigNormalizeTmpBytes, VecZnxCopy, VecZnxDftAddInplace, VecZnxDftAlloc, VecZnxDftAllocBytes, VecZnxDftCopy,
  7        VecZnxDftFromVecZnx, VecZnxDftToVecZnxBigConsume, VecZnxDftToVecZnxBigTmpA, VecZnxFillUniform, VecZnxNormalize,
  8        VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace, VecZnxSwithcDegree, VmpApply,
  9        VmpApplyAdd, VmpApplyTmpBytes, VmpPMatAlloc, VmpPrepare,
 10    },
 11    layouts::{Backend, Module, ScalarZnx, ScratchOwned},
 12    oep::{
 13        ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl,
 14        TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl, VecZnxBigAllocBytesImpl, VecZnxDftAllocBytesImpl,
 15    },
 16};
 17use sampling::source::Source;
 18
 19use crate::{
 20    layouts::{
 21        GGLWEAutomorphismKey, GGLWETensorKey, GGSWCiphertext, GLWESecret,
 22        prepared::{GGLWEAutomorphismKeyPrepared, GGLWETensorKeyPrepared, GLWESecretPrepared, Prepare, PrepareAlloc},
 23    },
 24    noise::noise_ggsw_keyswitch,
 25};
 26
 27pub fn test_ggsw_automorphism<B: Backend>(
 28    p: i64,
 29    module: &Module<B>,
 30    basek: usize,
 31    k_out: usize,
 32    k_in: usize,
 33    k_ksk: usize,
 34    k_tsk: usize,
 35    digits: usize,
 36    rank: usize,
 37    sigma: f64,
 38) where
 39    Module<B>: VecZnxDftAllocBytes
 40        + VecZnxBigAllocBytes
 41        + VecZnxDftFromVecZnx<B>
 42        + SvpApplyInplace<B>
 43        + VecZnxDftToVecZnxBigConsume<B>
 44        + VecZnxBigAddInplace<B>
 45        + VecZnxBigAddSmallInplace<B>
 46        + VecZnxBigNormalize<B>
 47        + VecZnxNormalizeTmpBytes
 48        + VecZnxBigAlloc<B>
 49        + VecZnxDftAlloc<B>
 50        + VecZnxBigNormalizeTmpBytes
 51        + VecZnxDftToVecZnxBigTmpA<B>
 52        + SvpPrepare<B>
 53        + SvpPPolAllocBytes
 54        + SvpPPolAlloc<B>
 55        + VecZnxAddScalarInplace
 56        + VecZnxCopy
 57        + VecZnxSubABInplace
 58        + VmpPMatAlloc<B>
 59        + VmpPrepare<B>
 60        + VmpApplyTmpBytes
 61        + VmpApply<B>
 62        + VmpApplyAdd<B>
 63        + VecZnxDftCopy<B>
 64        + VecZnxDftAddInplace<B>
 65        + VecZnxFillUniform
 66        + VecZnxAddInplace
 67        + VecZnxNormalizeInplace<B>
 68        + VecZnxAddNormal
 69        + VecZnxNormalize<B>
 70        + VecZnxSub
 71        + SvpApply<B>
 72        + VecZnxSwithcDegree
 73        + VecZnxAutomorphismInplace
 74        + VecZnxAutomorphism,
 75    B: TakeVecZnxDftImpl<B>
 76        + TakeVecZnxBigImpl<B>
 77        + ScratchOwnedAllocImpl<B>
 78        + ScratchOwnedBorrowImpl<B>
 79        + ScratchAvailableImpl<B>
 80        + TakeScalarZnxImpl<B>
 81        + TakeVecZnxImpl<B>
 82        + VecZnxDftAllocBytesImpl<B>
 83        + VecZnxBigAllocBytesImpl<B>
 84        + TakeSvpPPolImpl<B>,
 85{
 86    let n: usize = module.n();
 87    let rows: usize = k_in.div_ceil(basek * digits);
 88    let rows_in: usize = k_in.div_euclid(basek * digits);
 89
 90    let digits_in: usize = 1;
 91
 92    let mut ct_in: GGSWCiphertext<Vec<u8>> = GGSWCiphertext::alloc(n, basek, k_in, rows_in, digits_in, rank);
 93    let mut ct_out: GGSWCiphertext<Vec<u8>> = GGSWCiphertext::alloc(n, basek, k_out, rows_in, digits_in, rank);
 94    let mut tensor_key: GGLWETensorKey<Vec<u8>> = GGLWETensorKey::alloc(n, basek, k_tsk, rows, digits, rank);
 95    let mut auto_key: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
 96    let mut pt_scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, 1);
 97
 98    let mut source_xs: Source = Source::new([0u8; 32]);
 99    let mut source_xe: Source = Source::new([0u8; 32]);
100    let mut source_xa: Source = Source::new([0u8; 32]);
101
102    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
103        GGSWCiphertext::encrypt_sk_scratch_space(module, n, basek, k_in, rank)
104            | GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, n, basek, k_ksk, rank)
105            | GGLWETensorKey::encrypt_sk_scratch_space(module, n, basek, k_tsk, rank)
106            | GGSWCiphertext::automorphism_scratch_space(
107                module, n, basek, k_out, k_in, k_ksk, digits, k_tsk, digits, rank,
108            ),
109    );
110
111    let var_xs: f64 = 0.5;
112
113    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
114    sk.fill_ternary_prob(var_xs, &mut source_xs);
115    let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
116
117    auto_key.encrypt_sk(
118        module,
119        p,
120        &sk,
121        &mut source_xa,
122        &mut source_xe,
123        sigma,
124        scratch.borrow(),
125    );
126    tensor_key.encrypt_sk(
127        module,
128        &sk,
129        &mut source_xa,
130        &mut source_xe,
131        sigma,
132        scratch.borrow(),
133    );
134
135    pt_scalar.fill_ternary_hw(0, n, &mut source_xs);
136
137    ct_in.encrypt_sk(
138        module,
139        &pt_scalar,
140        &sk_prepared,
141        &mut source_xa,
142        &mut source_xe,
143        sigma,
144        scratch.borrow(),
145    );
146
147    let mut auto_key_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
148        GGLWEAutomorphismKeyPrepared::alloc(module, n, basek, k_ksk, rows, digits, rank);
149    auto_key_prepared.prepare(module, &auto_key, scratch.borrow());
150
151    let mut tsk_prepared: GGLWETensorKeyPrepared<Vec<u8>, B> =
152        GGLWETensorKeyPrepared::alloc(module, n, basek, k_tsk, rows, digits, rank);
153    tsk_prepared.prepare(module, &tensor_key, scratch.borrow());
154
155    ct_out.automorphism(
156        module,
157        &ct_in,
158        &auto_key_prepared,
159        &tsk_prepared,
160        scratch.borrow(),
161    );
162
163    module.vec_znx_automorphism_inplace(p, &mut pt_scalar.as_vec_znx_mut(), 0);
164
165    let max_noise = |col_j: usize| -> f64 {
166        noise_ggsw_keyswitch(
167            n as f64,
168            basek * digits,
169            col_j,
170            var_xs,
171            0f64,
172            sigma * sigma,
173            0f64,
174            rank as f64,
175            k_in,
176            k_ksk,
177            k_tsk,
178        ) + 0.5
179    };
180
181    ct_out.assert_noise(module, &sk_prepared, &pt_scalar, &max_noise);
182}
183
184pub fn test_ggsw_automorphism_inplace<B: Backend>(
185    p: i64,
186    module: &Module<B>,
187    basek: usize,
188    k_ct: usize,
189    k_ksk: usize,
190    k_tsk: usize,
191    digits: usize,
192    rank: usize,
193    sigma: f64,
194) where
195    Module<B>: VecZnxDftAllocBytes
196        + VecZnxBigAllocBytes
197        + VecZnxDftFromVecZnx<B>
198        + SvpApplyInplace<B>
199        + VecZnxDftToVecZnxBigConsume<B>
200        + VecZnxBigAddInplace<B>
201        + VecZnxBigAddSmallInplace<B>
202        + VecZnxBigNormalize<B>
203        + VecZnxNormalizeTmpBytes
204        + VecZnxBigAlloc<B>
205        + VecZnxDftAlloc<B>
206        + VecZnxBigNormalizeTmpBytes
207        + VecZnxDftToVecZnxBigTmpA<B>
208        + SvpPrepare<B>
209        + SvpPPolAllocBytes
210        + SvpPPolAlloc<B>
211        + VecZnxAddScalarInplace
212        + VecZnxCopy
213        + VecZnxSubABInplace
214        + VmpPMatAlloc<B>
215        + VmpPrepare<B>
216        + VmpApplyTmpBytes
217        + VmpApply<B>
218        + VmpApplyAdd<B>
219        + VecZnxBigAddSmallInplace<B>
220        + VecZnxDftCopy<B>
221        + VecZnxDftAddInplace<B>
222        + VecZnxAddInplace
223        + VecZnxNormalizeInplace<B>
224        + VecZnxAddNormal
225        + VecZnxNormalize<B>
226        + VecZnxSub
227        + VecZnxFillUniform
228        + SvpApply<B>
229        + VecZnxSwithcDegree
230        + VecZnxAutomorphismInplace
231        + VecZnxAutomorphism,
232    B: TakeVecZnxDftImpl<B>
233        + TakeVecZnxBigImpl<B>
234        + ScratchOwnedAllocImpl<B>
235        + ScratchOwnedBorrowImpl<B>
236        + ScratchAvailableImpl<B>
237        + TakeScalarZnxImpl<B>
238        + TakeVecZnxImpl<B>
239        + VecZnxDftAllocBytesImpl<B>
240        + VecZnxBigAllocBytesImpl<B>
241        + TakeSvpPPolImpl<B>,
242{
243    let n: usize = module.n();
244    let rows: usize = k_ct.div_ceil(digits * basek);
245    let rows_in: usize = k_ct.div_euclid(basek * digits);
246    let digits_in: usize = 1;
247
248    let mut ct: GGSWCiphertext<Vec<u8>> = GGSWCiphertext::alloc(n, basek, k_ct, rows_in, digits_in, rank);
249    let mut tensor_key: GGLWETensorKey<Vec<u8>> = GGLWETensorKey::alloc(n, basek, k_tsk, rows, digits, rank);
250    let mut auto_key: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
251    let mut pt_scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, 1);
252
253    let mut source_xs: Source = Source::new([0u8; 32]);
254    let mut source_xe: Source = Source::new([0u8; 32]);
255    let mut source_xa: Source = Source::new([0u8; 32]);
256
257    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
258        GGSWCiphertext::encrypt_sk_scratch_space(module, n, basek, k_ct, rank)
259            | GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, n, basek, k_ksk, rank)
260            | GGLWETensorKey::encrypt_sk_scratch_space(module, n, basek, k_tsk, rank)
261            | GGSWCiphertext::automorphism_inplace_scratch_space(module, n, basek, k_ct, k_ksk, digits, k_tsk, digits, rank),
262    );
263
264    let var_xs: f64 = 0.5;
265
266    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
267    sk.fill_ternary_prob(var_xs, &mut source_xs);
268    let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
269
270    auto_key.encrypt_sk(
271        module,
272        p,
273        &sk,
274        &mut source_xa,
275        &mut source_xe,
276        sigma,
277        scratch.borrow(),
278    );
279    tensor_key.encrypt_sk(
280        module,
281        &sk,
282        &mut source_xa,
283        &mut source_xe,
284        sigma,
285        scratch.borrow(),
286    );
287
288    pt_scalar.fill_ternary_hw(0, n, &mut source_xs);
289
290    ct.encrypt_sk(
291        module,
292        &pt_scalar,
293        &sk_prepared,
294        &mut source_xa,
295        &mut source_xe,
296        sigma,
297        scratch.borrow(),
298    );
299
300    let mut auto_key_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> =
301        GGLWEAutomorphismKeyPrepared::alloc(module, n, basek, k_ksk, rows, digits, rank);
302    auto_key_prepared.prepare(module, &auto_key, scratch.borrow());
303
304    let mut tsk_prepared: GGLWETensorKeyPrepared<Vec<u8>, B> =
305        GGLWETensorKeyPrepared::alloc(module, n, basek, k_tsk, rows, digits, rank);
306    tsk_prepared.prepare(module, &tensor_key, scratch.borrow());
307
308    ct.automorphism_inplace(module, &auto_key_prepared, &tsk_prepared, scratch.borrow());
309
310    module.vec_znx_automorphism_inplace(p, &mut pt_scalar.as_vec_znx_mut(), 0);
311
312    let max_noise = |col_j: usize| -> f64 {
313        noise_ggsw_keyswitch(
314            n as f64,
315            basek * digits,
316            col_j,
317            var_xs,
318            0f64,
319            sigma * sigma,
320            0f64,
321            rank as f64,
322            k_ct,
323            k_ksk,
324            k_tsk,
325        ) + 0.5
326    };
327
328    ct.assert_noise(module, &sk_prepared, &pt_scalar, &max_noise);
329}