use backend::{Backend, FFT64, Module, ScratchOwned, VecZnxDft}; use sampling::source::Source; use crate::{FourierGLWECiphertext, FourierGLWESecret, Infos, dist::Distribution}; pub struct GLWEPublicKey { pub(crate) data: FourierGLWECiphertext, pub(crate) dist: Distribution, } impl GLWEPublicKey, B> { pub fn alloc(module: &Module, basek: usize, k: usize, rank: usize) -> Self { Self { data: FourierGLWECiphertext::alloc(module, basek, k, rank), dist: Distribution::NONE, } } pub fn bytes_of(module: &Module, basek: usize, k: usize, rank: usize) -> usize { FourierGLWECiphertext::, B>::bytes_of(module, basek, k, rank) } } impl Infos for GLWEPublicKey { type Inner = VecZnxDft; fn inner(&self) -> &Self::Inner { &self.data.data } fn basek(&self) -> usize { self.data.basek } fn k(&self) -> usize { self.data.k } } impl GLWEPublicKey { pub fn rank(&self) -> usize { self.cols() - 1 } } impl + AsMut<[u8]>> GLWEPublicKey { pub fn generate_from_sk>( &mut self, module: &Module, sk: &FourierGLWESecret, source_xa: &mut Source, source_xe: &mut Source, sigma: f64, ) { #[cfg(debug_assertions)] { match sk.dist { Distribution::NONE => panic!("invalid sk: SecretDistribution::NONE"), _ => {} } } // Its ok to allocate scratch space here since pk is usually generated only once. let mut scratch: ScratchOwned = ScratchOwned::new(FourierGLWECiphertext::encrypt_sk_scratch_space( module, self.basek(), self.k(), self.rank(), )); self.data .encrypt_zero_sk(module, sk, source_xa, source_xe, sigma, scratch.borrow()); self.dist = sk.dist; } }