poulpy_core/encryption/
glwe_public_key.rs

1use poulpy_hal::{
2    api::{ScratchOwnedAlloc, ScratchOwnedBorrow},
3    layouts::{Backend, DataMut, Module, Scratch, ScratchOwned},
4    source::Source,
5};
6
7use crate::{
8    Distribution, GLWEEncryptSk, GetDistribution, GetDistributionMut, ScratchTakeCore,
9    layouts::{
10        GLWE, GLWEInfos, GLWEPublicKey, GLWEToMut,
11        prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
12    },
13};
14
15impl<D: DataMut> GLWEPublicKey<D> {
16    pub fn generate<S, M, BE: Backend>(&mut self, module: &M, sk: &S, source_xa: &mut Source, source_xe: &mut Source)
17    where
18        S: GLWESecretPreparedToRef<BE> + GetDistribution,
19        M: GLWEPublicKeyGenerate<BE>,
20    {
21        module.glwe_public_key_generate(self, sk, source_xa, source_xe);
22    }
23}
24
25pub trait GLWEPublicKeyGenerate<BE: Backend> {
26    fn glwe_public_key_generate<R, S>(&self, res: &mut R, sk: &S, source_xa: &mut Source, source_xe: &mut Source)
27    where
28        R: GLWEToMut + GetDistributionMut + GLWEInfos,
29        S: GLWESecretPreparedToRef<BE> + GetDistribution;
30}
31
32impl<BE: Backend> GLWEPublicKeyGenerate<BE> for Module<BE>
33where
34    Self: GLWEEncryptSk<BE>,
35    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
36    Scratch<BE>: ScratchTakeCore<BE>,
37{
38    fn glwe_public_key_generate<R, S>(&self, res: &mut R, sk: &S, source_xa: &mut Source, source_xe: &mut Source)
39    where
40        R: GLWEToMut + GetDistributionMut + GLWEInfos,
41        S: GLWESecretPreparedToRef<BE> + GetDistribution,
42    {
43        {
44            let sk: &GLWESecretPrepared<&[u8], BE> = &sk.to_ref();
45
46            assert_eq!(res.n(), self.n() as u32);
47            assert_eq!(sk.n(), self.n() as u32);
48
49            if sk.dist == Distribution::NONE {
50                panic!("invalid sk: SecretDistribution::NONE")
51            }
52
53            // Its ok to allocate scratch space here since pk is usually generated only once.
54            let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(self.glwe_encrypt_sk_tmp_bytes(res));
55
56            let mut tmp: GLWE<Vec<u8>> = GLWE::alloc_from_infos(res);
57
58            tmp.encrypt_zero_sk(self, sk, source_xa, source_xe, scratch.borrow());
59        }
60        *res.dist_mut() = *sk.dist();
61    }
62}