use backend::hal::{ api::{ ScratchAvailable, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxSwithcDegree, }, layouts::{Backend, DataMut, DataRef, Module, Scratch}, }; use sampling::source::Source; use crate::{ TakeGLWESecret, TakeGLWESecretExec, layouts::{GGLWEAutomorphismKey, GLWESecret, GGLWESwitchingKey, Infos}, }; use crate::trait_families::{GGLWEAutomorphismKeyEncryptSkFamily, GLWESecretExecModuleFamily}; impl GGLWEAutomorphismKey> { pub fn encrypt_sk_scratch_space(module: &Module, n: usize, basek: usize, k: usize, rank: usize) -> usize where Module: GGLWEAutomorphismKeyEncryptSkFamily + GLWESecretExecModuleFamily, { GGLWESwitchingKey::encrypt_sk_scratch_space(module, n, basek, k, rank, rank) + GLWESecret::bytes_of(n, rank) } pub fn encrypt_pk_scratch_space(module: &Module, _n: usize, _basek: usize, _k: usize, _rank: usize) -> usize { GGLWESwitchingKey::encrypt_pk_scratch_space(module, _n, _basek, _k, _rank, _rank) } } impl GGLWEAutomorphismKey { pub fn encrypt_sk( &mut self, module: &Module, p: i64, sk: &GLWESecret, source_xa: &mut Source, source_xe: &mut Source, sigma: f64, scratch: &mut Scratch, ) where Module: GGLWEAutomorphismKeyEncryptSkFamily + VecZnxAutomorphism + VecZnxSwithcDegree + VecZnxAddScalarInplace + GLWESecretExecModuleFamily, Scratch: ScratchAvailable + TakeScalarZnx + TakeVecZnxDft + TakeGLWESecretExec + TakeVecZnx, { #[cfg(debug_assertions)] { assert_eq!(self.n(), sk.n()); assert_eq!(self.rank_out(), self.rank_in()); assert_eq!(sk.rank(), self.rank()); assert!( scratch.available() >= GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, sk.n(), self.basek(), self.k(), self.rank()), "scratch.available(): {} < AutomorphismKey::encrypt_sk_scratch_space(module, self.rank()={}, self.size()={}): {}", scratch.available(), self.rank(), self.size(), GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, sk.n(), self.basek(), self.k(), self.rank()) ) } let (mut sk_out, scratch_1) = scratch.take_glwe_secret(sk.n(), sk.rank()); { (0..self.rank()).for_each(|i| { module.vec_znx_automorphism( module.galois_element_inv(p), &mut sk_out.data.as_vec_znx_mut(), i, &sk.data.as_vec_znx(), i, ); }); } self.key .encrypt_sk(module, &sk, &sk_out, source_xa, source_xe, sigma, scratch_1); self.p = p; } }