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, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxAutomorphismInplace,
  4        VecZnxFillUniform, VecZnxStd, VecZnxSwithcDegree, VmpPMatAlloc, VmpPMatPrepare,
  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    layouts::{
 16        GGLWEAutomorphismKey, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos,
 17        prepared::{GGLWEAutomorphismKeyExec, GLWESecretExec},
 18    },
 19    noise::log2_std_noise_gglwe_product,
 20    trait_families::{GLWEDecryptFamily, GLWEKeyswitchFamily},
 21};
 22
 23use crate::trait_families::{GGLWEAutomorphismKeyEncryptSkFamily, GLWESecretExecModuleFamily};
 24
 25pub fn test_glwe_automorphism<B: Backend>(
 26    module: &Module<B>,
 27    basek: usize,
 28    p: i64,
 29    k_out: usize,
 30    k_in: usize,
 31    k_ksk: usize,
 32    digits: usize,
 33    rank: usize,
 34    sigma: f64,
 35) where
 36    Module<B>: GGLWEAutomorphismKeyEncryptSkFamily<B>
 37        + GLWESecretExecModuleFamily<B>
 38        + GLWEDecryptFamily<B>
 39        + GLWEKeyswitchFamily<B>
 40        + VecZnxAutomorphism
 41        + VecZnxSwithcDegree
 42        + VecZnxAddScalarInplace
 43        + VecZnxAutomorphismInplace
 44        + VecZnxStd
 45        + VmpPMatAlloc<B>
 46        + VmpPMatPrepare<B>,
 47    B: TakeVecZnxDftImpl<B>
 48        + TakeVecZnxBigImpl<B>
 49        + TakeSvpPPolImpl<B>
 50        + ScratchOwnedAllocImpl<B>
 51        + ScratchOwnedBorrowImpl<B>
 52        + ScratchAvailableImpl<B>
 53        + TakeScalarZnxImpl<B>
 54        + TakeVecZnxImpl<B>,
 55{
 56    let n: usize = module.n();
 57    let rows: usize = k_in.div_ceil(basek * digits);
 58
 59    let mut autokey: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
 60    let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_in, rank);
 61    let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_out, rank);
 62    let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k_in);
 63
 64    let mut source_xs: Source = Source::new([0u8; 32]);
 65    let mut source_xe: Source = Source::new([0u8; 32]);
 66    let mut source_xa: Source = Source::new([0u8; 32]);
 67
 68    module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_in, &mut source_xa);
 69
 70    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
 71        GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, n, basek, autokey.k(), rank)
 72            | GLWECiphertext::decrypt_scratch_space(module, n, basek, ct_out.k())
 73            | GLWECiphertext::encrypt_sk_scratch_space(module, n, basek, ct_in.k())
 74            | GLWECiphertext::automorphism_scratch_space(
 75                module,
 76                n,
 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(n, 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: GGLWEAutomorphismKeyExec<Vec<u8>, B> =
111        GGLWEAutomorphismKeyExec::alloc(module, n, basek, k_ksk, rows, digits, rank);
112    autokey_exec.prepare(module, &autokey, scratch.borrow());
113
114    ct_out.automorphism(module, &ct_in, &autokey_exec, scratch.borrow());
115
116    let max_noise: f64 = log2_std_noise_gglwe_product(
117        module.n() as f64,
118        basek * digits,
119        0.5,
120        0.5,
121        0f64,
122        sigma * sigma,
123        0f64,
124        rank as f64,
125        k_in,
126        k_ksk,
127    );
128
129    module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
130
131    ct_out.assert_noise(module, &sk_exec, &pt_want, max_noise + 1.0);
132}
133
134pub fn test_glwe_automorphism_inplace<B: Backend>(
135    module: &Module<B>,
136    basek: usize,
137    p: i64,
138    k_ct: usize,
139    k_ksk: usize,
140    digits: usize,
141    rank: usize,
142    sigma: f64,
143) where
144    Module<B>: GGLWEAutomorphismKeyEncryptSkFamily<B>
145        + GLWESecretExecModuleFamily<B>
146        + GLWEDecryptFamily<B>
147        + GLWEKeyswitchFamily<B>
148        + VecZnxAutomorphism
149        + VecZnxSwithcDegree
150        + VecZnxAddScalarInplace
151        + VecZnxAutomorphismInplace
152        + VecZnxStd
153        + VmpPMatAlloc<B>
154        + VmpPMatPrepare<B>,
155    B: TakeVecZnxDftImpl<B>
156        + TakeVecZnxBigImpl<B>
157        + TakeSvpPPolImpl<B>
158        + ScratchOwnedAllocImpl<B>
159        + ScratchOwnedBorrowImpl<B>
160        + ScratchAvailableImpl<B>
161        + TakeScalarZnxImpl<B>
162        + TakeVecZnxImpl<B>,
163{
164    let n: usize = module.n();
165    let rows: usize = k_ct.div_ceil(basek * digits);
166
167    let mut autokey: GGLWEAutomorphismKey<Vec<u8>> = GGLWEAutomorphismKey::alloc(n, basek, k_ksk, rows, digits, rank);
168    let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(n, basek, k_ct, rank);
169    let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k_ct);
170
171    let mut source_xs: Source = Source::new([0u8; 32]);
172    let mut source_xe: Source = Source::new([0u8; 32]);
173    let mut source_xa: Source = Source::new([0u8; 32]);
174
175    module.vec_znx_fill_uniform(basek, &mut pt_want.data, 0, k_ct, &mut source_xa);
176
177    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
178        GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, n, basek, autokey.k(), rank)
179            | GLWECiphertext::decrypt_scratch_space(module, n, basek, ct.k())
180            | GLWECiphertext::encrypt_sk_scratch_space(module, n, basek, ct.k())
181            | GLWECiphertext::automorphism_inplace_scratch_space(module, n, basek, ct.k(), autokey.k(), digits, rank),
182    );
183
184    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
185    sk.fill_ternary_prob(0.5, &mut source_xs);
186    let sk_exec: GLWESecretExec<Vec<u8>, B> = GLWESecretExec::from(module, &sk);
187
188    autokey.encrypt_sk(
189        module,
190        p,
191        &sk,
192        &mut source_xa,
193        &mut source_xe,
194        sigma,
195        scratch.borrow(),
196    );
197
198    ct.encrypt_sk(
199        module,
200        &pt_want,
201        &sk_exec,
202        &mut source_xa,
203        &mut source_xe,
204        sigma,
205        scratch.borrow(),
206    );
207
208    let mut autokey_exec: GGLWEAutomorphismKeyExec<Vec<u8>, B> =
209        GGLWEAutomorphismKeyExec::alloc(module, n, basek, k_ksk, rows, digits, rank);
210    autokey_exec.prepare(module, &autokey, scratch.borrow());
211
212    ct.automorphism_inplace(module, &autokey_exec, scratch.borrow());
213
214    let max_noise: f64 = log2_std_noise_gglwe_product(
215        module.n() as f64,
216        basek * digits,
217        0.5,
218        0.5,
219        0f64,
220        sigma * sigma,
221        0f64,
222        rank as f64,
223        k_ct,
224        k_ksk,
225    );
226
227    module.vec_znx_automorphism_inplace(p, &mut pt_want.data, 0);
228
229    ct.assert_noise(module, &sk_exec, &pt_want, max_noise + 1.0);
230}