poulpy/core/src/encryption/gglwe_atk.rs
core/src/encryption/gglwe_atk.rsRaw
1use backend::hal::{
2 api::{
3 ScratchAvailable, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft, VecZnxAddScalarInplace, VecZnxAutomorphism,
4 VecZnxSwithcDegree,
5 },
6 layouts::{Backend, DataMut, DataRef, Module, Scratch},
7};
8use sampling::source::Source;
9
10use crate::{
11 TakeGLWESecret, TakeGLWESecretPrepared,
12 layouts::{GGLWEAutomorphismKey, GGLWESwitchingKey, GLWESecret, Infos},
13};
14
15use crate::trait_families::{GGLWEAutomorphismKeyEncryptSkFamily, GLWESecretPreparedModuleFamily};
16
17impl GGLWEAutomorphismKey<Vec<u8>> {
18 pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, n: usize, basek: usize, k: usize, rank: usize) -> usize
19 where
20 Module<B>: GGLWEAutomorphismKeyEncryptSkFamily<B> + GLWESecretPreparedModuleFamily<B>,
21 {
22 GGLWESwitchingKey::encrypt_sk_scratch_space(module, n, basek, k, rank, rank) + GLWESecret::bytes_of(n, rank)
23 }
24
25 pub fn encrypt_pk_scratch_space<B: Backend>(module: &Module<B>, _n: usize, _basek: usize, _k: usize, _rank: usize) -> usize {
26 GGLWESwitchingKey::encrypt_pk_scratch_space(module, _n, _basek, _k, _rank, _rank)
27 }
28}
29
30impl<DataSelf: DataMut> GGLWEAutomorphismKey<DataSelf> {
31 pub fn encrypt_sk<DataSk: DataRef, B: Backend>(
32 &mut self,
33 module: &Module<B>,
34 p: i64,
35 sk: &GLWESecret<DataSk>,
36 source_xa: &mut Source,
37 source_xe: &mut Source,
38 sigma: f64,
39 scratch: &mut Scratch<B>,
40 ) where
41 Module<B>: GGLWEAutomorphismKeyEncryptSkFamily<B>
42 + VecZnxAutomorphism
43 + VecZnxSwithcDegree
44 + VecZnxAddScalarInplace
45 + GLWESecretPreparedModuleFamily<B>,
46 Scratch<B>: ScratchAvailable + TakeScalarZnx + TakeVecZnxDft<B> + TakeGLWESecretPrepared<B> + TakeVecZnx,
47 {
48 #[cfg(debug_assertions)]
49 {
50 assert_eq!(self.n(), sk.n());
51 assert_eq!(self.rank_out(), self.rank_in());
52 assert_eq!(sk.rank(), self.rank());
53 assert!(
54 scratch.available()
55 >= GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, sk.n(), self.basek(), self.k(), self.rank()),
56 "scratch.available(): {} < AutomorphismKey::encrypt_sk_scratch_space(module, self.rank()={}, self.size()={}): {}",
57 scratch.available(),
58 self.rank(),
59 self.size(),
60 GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, sk.n(), self.basek(), self.k(), self.rank())
61 )
62 }
63
64 let (mut sk_out, scratch_1) = scratch.take_glwe_secret(sk.n(), sk.rank());
65
66 {
67 (0..self.rank()).for_each(|i| {
68 module.vec_znx_automorphism(
69 module.galois_element_inv(p),
70 &mut sk_out.data.as_vec_znx_mut(),
71 i,
72 &sk.data.as_vec_znx(),
73 i,
74 );
75 });
76 }
77
78 self.key
79 .encrypt_sk(module, &sk, &sk_out, source_xa, source_xe, sigma, scratch_1);
80
81 self.p = p;
82 }
83}