arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/glwe/public_key.rs
core/src/glwe/public_key.rsRaw
 1use backend::{Backend, FFT64, Module, ScratchOwned, VecZnxDft};
 2use sampling::source::Source;
 3
 4use crate::{FourierGLWECiphertext, GLWESecret, Infos, keys::SecretDistribution};
 5
 6pub struct GLWEPublicKey<D, B: Backend> {
 7    pub(crate) data: FourierGLWECiphertext<D, B>,
 8    pub(crate) dist: SecretDistribution,
 9}
10
11impl<B: Backend> GLWEPublicKey<Vec<u8>, B> {
12    pub fn alloc(module: &Module<B>, basek: usize, k: usize, rank: usize) -> Self {
13        Self {
14            data: FourierGLWECiphertext::alloc(module, basek, k, rank),
15            dist: SecretDistribution::NONE,
16        }
17    }
18
19    pub fn bytes_of(module: &Module<B>, basek: usize, k: usize, rank: usize) -> usize {
20        FourierGLWECiphertext::<Vec<u8>, B>::bytes_of(module, basek, k, rank)
21    }
22}
23
24impl<T, B: Backend> Infos for GLWEPublicKey<T, B> {
25    type Inner = VecZnxDft<T, B>;
26
27    fn inner(&self) -> &Self::Inner {
28        &self.data.data
29    }
30
31    fn basek(&self) -> usize {
32        self.data.basek
33    }
34
35    fn k(&self) -> usize {
36        self.data.k
37    }
38}
39
40impl<T, B: Backend> GLWEPublicKey<T, B> {
41    pub fn rank(&self) -> usize {
42        self.cols() - 1
43    }
44}
45
46impl<C: AsRef<[u8]> + AsMut<[u8]>> GLWEPublicKey<C, FFT64> {
47    pub fn generate_from_sk<S: AsRef<[u8]>>(
48        &mut self,
49        module: &Module<FFT64>,
50        sk: &GLWESecret<S, FFT64>,
51        source_xa: &mut Source,
52        source_xe: &mut Source,
53        sigma: f64,
54    ) {
55        #[cfg(debug_assertions)]
56        {
57            match sk.dist {
58                SecretDistribution::NONE => panic!("invalid sk: SecretDistribution::NONE"),
59                _ => {}
60            }
61        }
62
63        // Its ok to allocate scratch space here since pk is usually generated only once.
64        let mut scratch: ScratchOwned = ScratchOwned::new(FourierGLWECiphertext::encrypt_sk_scratch_space(
65            module,
66            self.basek(),
67            self.k(),
68            self.rank(),
69        ));
70
71        self.data
72            .encrypt_zero_sk(module, sk, source_xa, source_xe, sigma, scratch.borrow());
73        self.dist = sk.dist;
74    }
75}