use poulpy_hal::{ api::{ScratchOwnedAlloc, ScratchOwnedBorrow}, layouts::{Backend, DataMut, Module, Scratch, ScratchOwned}, source::Source, }; use crate::{ Distribution, GLWEEncryptSk, GetDistribution, GetDistributionMut, ScratchTakeCore, layouts::{ GLWEInfos, GLWEPublicKey, GLWEToMut, prepared::{GLWESecretPrepared, GLWESecretPreparedToRef}, }, }; impl GLWEPublicKey { pub fn generate(&mut self, module: &M, sk: &S, source_xa: &mut Source, source_xe: &mut Source) where S: GLWESecretPreparedToRef + GetDistribution, M: GLWEPublicKeyGenerate, { module.glwe_public_key_generate(self, sk, source_xa, source_xe); } } pub trait GLWEPublicKeyGenerate { fn glwe_public_key_generate(&self, res: &mut R, sk: &S, source_xa: &mut Source, source_xe: &mut Source) where R: GLWEToMut + GetDistributionMut + GLWEInfos, S: GLWESecretPreparedToRef + GetDistribution; } impl GLWEPublicKeyGenerate for Module where Self: GLWEEncryptSk, ScratchOwned: ScratchOwnedAlloc + ScratchOwnedBorrow, Scratch: ScratchTakeCore, { fn glwe_public_key_generate(&self, res: &mut R, sk: &S, source_xa: &mut Source, source_xe: &mut Source) where R: GLWEToMut + GetDistributionMut + GLWEInfos, S: GLWESecretPreparedToRef + GetDistribution, { { let sk: &GLWESecretPrepared<&[u8], BE> = &sk.to_ref(); assert_eq!(res.n(), self.n() as u32); assert_eq!(sk.n(), self.n() as u32); if 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::alloc(self.glwe_encrypt_sk_tmp_bytes(res)); res.to_mut().encrypt_zero_sk(self, sk, source_xa, source_xe, scratch.borrow()); } *res.dist_mut() = *sk.dist(); } }