arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/glwe/tests/generic_automorphism.rs
core/src/glwe/tests/generic_automorphism.rsRaw
  1use backend::hal::{
  2    api::{
  3        MatZnxAlloc, ScalarZnxAlloc, ScalarZnxAllocBytes, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxAddScalarInplace,
  4        VecZnxAlloc, VecZnxAllocBytes, VecZnxAutomorphism, VecZnxAutomorphismInplace, VecZnxFillUniform, VecZnxStd,
  5        VecZnxSwithcDegree,
  6    },
  7    layouts::{Backend, Module, ScratchOwned},
  8    oep::{
  9        ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl,
 10        TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl,
 11    },
 12};
 13use sampling::source::Source;
 14
 15use crate::{
 16    AutomorphismKey, AutomorphismKeyEncryptSkFamily, AutomorphismKeyExec, GGLWEExecLayoutFamily, GLWECiphertext,
 17    GLWEDecryptFamily, GLWEKeyswitchFamily, GLWEPlaintext, GLWESecret, GLWESecretExec, Infos,
 18    noise::log2_std_noise_gglwe_product,
 19};
 20
 21pub(crate) trait AutomorphismTestModuleFamily<B: Backend> = AutomorphismKeyEncryptSkFamily<B>
 22    + GLWEDecryptFamily<B>
 23    + GGLWEExecLayoutFamily<B>
 24    + GLWEKeyswitchFamily<B>
 25    + MatZnxAlloc
 26    + VecZnxAlloc
 27    + ScalarZnxAllocBytes
 28    + VecZnxAllocBytes
 29    + VecZnxAutomorphism
 30    + VecZnxSwithcDegree
 31    + ScalarZnxAlloc
 32    + VecZnxAddScalarInplace
 33    + VecZnxAutomorphismInplace
 34    + VecZnxStd;
 35pub(crate) trait AutomorphismTestScratchFamily<B: Backend> = TakeVecZnxDftImpl<B>
 36    + TakeVecZnxBigImpl<B>
 37    + TakeSvpPPolImpl<B>
 38    + ScratchOwnedAllocImpl<B>
 39    + ScratchOwnedBorrowImpl<B>
 40    + ScratchAvailableImpl<B>
 41    + TakeScalarZnxImpl<B>
 42    + TakeVecZnxImpl<B>;
 43
 44pub(crate) fn test_automorphism<B: Backend>(
 45    module: &Module<B>,
 46    basek: usize,
 47    p: i64,
 48    k_out: usize,
 49    k_in: usize,
 50    k_ksk: usize,
 51    digits: usize,
 52    rank: usize,
 53    sigma: f64,
 54) where
 55    Module<B>: AutomorphismTestModuleFamily<B>,
 56    B: AutomorphismTestScratchFamily<B>,
 57{
 58    let rows: usize = k_in.div_ceil(basek * digits);
 59
 60    let mut autokey: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(module, basek, k_ksk, rows, digits, rank);
 61    let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(module, basek, k_in, rank);
 62    let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(module, basek, k_out, rank);
 63    let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(module, basek, k_in);
 64
 65    let mut source_xs: Source = Source::new([0u8; 32]);
 66    let mut source_xe: Source = Source::new([0u8; 32]);
 67    let mut source_xa: Source = Source::new([0u8; 32]);
 68
 69    module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_in, &mut source_xa);
 70
 71    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
 72        AutomorphismKey::encrypt_sk_scratch_space(module, basek, autokey.k(), rank)
 73            | GLWECiphertext::decrypt_scratch_space(module, basek, ct_out.k())
 74            | GLWECiphertext::encrypt_sk_scratch_space(module, basek, ct_in.k())
 75            | GLWECiphertext::automorphism_scratch_space(
 76                module,
 77                basek,
 78                ct_out.k(),
 79                ct_in.k(),
 80                autokey.k(),
 81                digits,
 82                rank,
 83            ),
 84    );
 85
 86    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(module, rank);
 87    sk.fill_ternary_prob(0.5, &mut source_xs);
 88    let sk_exec: GLWESecretExec<Vec<u8>, B> = GLWESecretExec::from(module, &sk);
 89
 90    autokey.encrypt_sk(
 91        module,
 92        p,
 93        &sk,
 94        &mut source_xa,
 95        &mut source_xe,
 96        sigma,
 97        scratch.borrow(),
 98    );
 99
100    ct_in.encrypt_sk(
101        module,
102        &pt_want,
103        &sk_exec,
104        &mut source_xa,
105        &mut source_xe,
106        sigma,
107        scratch.borrow(),
108    );
109
110    let mut autokey_exec: AutomorphismKeyExec<Vec<u8>, B> = AutomorphismKeyExec::alloc(module, basek, k_ksk, rows, digits, rank);
111    autokey_exec.prepare(module, &autokey, scratch.borrow());
112
113    ct_out.automorphism(module, &ct_in, &autokey_exec, scratch.borrow());
114
115    let max_noise: f64 = log2_std_noise_gglwe_product(
116        module.n() as f64,
117        basek * digits,
118        0.5,
119        0.5,
120        0f64,
121        sigma * sigma,
122        0f64,
123        rank as f64,
124        k_in,
125        k_ksk,
126    );
127
128    module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
129
130    ct_out.assert_noise(module, &sk_exec, &pt_want, max_noise + 1.0);
131}
132
133pub(crate) fn test_automorphism_inplace<B: Backend>(
134    module: &Module<B>,
135    basek: usize,
136    p: i64,
137    k_ct: usize,
138    k_ksk: usize,
139    digits: usize,
140    rank: usize,
141    sigma: f64,
142) where
143    Module<B>: AutomorphismTestModuleFamily<B>,
144    B: AutomorphismTestScratchFamily<B>,
145{
146    let rows: usize = k_ct.div_ceil(basek * digits);
147
148    let mut autokey: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(module, basek, k_ksk, rows, digits, rank);
149    let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(module, basek, k_ct, rank);
150    let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(module, basek, k_ct);
151
152    let mut source_xs: Source = Source::new([0u8; 32]);
153    let mut source_xe: Source = Source::new([0u8; 32]);
154    let mut source_xa: Source = Source::new([0u8; 32]);
155
156    module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_ct, &mut source_xa);
157
158    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
159        AutomorphismKey::encrypt_sk_scratch_space(module, basek, autokey.k(), rank)
160            | GLWECiphertext::decrypt_scratch_space(module, basek, ct.k())
161            | GLWECiphertext::encrypt_sk_scratch_space(module, basek, ct.k())
162            | GLWECiphertext::automorphism_inplace_scratch_space(module, basek, ct.k(), autokey.k(), digits, rank),
163    );
164
165    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(module, rank);
166    sk.fill_ternary_prob(0.5, &mut source_xs);
167    let sk_exec: GLWESecretExec<Vec<u8>, B> = GLWESecretExec::from(module, &sk);
168
169    autokey.encrypt_sk(
170        module,
171        p,
172        &sk,
173        &mut source_xa,
174        &mut source_xe,
175        sigma,
176        scratch.borrow(),
177    );
178
179    ct.encrypt_sk(
180        module,
181        &pt_want,
182        &sk_exec,
183        &mut source_xa,
184        &mut source_xe,
185        sigma,
186        scratch.borrow(),
187    );
188
189    let mut autokey_exec: AutomorphismKeyExec<Vec<u8>, B> = AutomorphismKeyExec::alloc(module, basek, k_ksk, rows, digits, rank);
190    autokey_exec.prepare(module, &autokey, scratch.borrow());
191
192    ct.automorphism_inplace(module, &autokey_exec, scratch.borrow());
193
194    let max_noise: f64 = log2_std_noise_gglwe_product(
195        module.n() as f64,
196        basek * digits,
197        0.5,
198        0.5,
199        0f64,
200        sigma * sigma,
201        0f64,
202        rank as f64,
203        k_ct,
204        k_ksk,
205    );
206
207    module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
208
209    ct.assert_noise(module, &sk_exec, &pt_want, max_noise + 1.0);
210}