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