Skip to main content

poulpy_core/layouts/prepared/
glwe_public_key.rs

1use poulpy_hal::{
2    api::{VecZnxDftAlloc, VecZnxDftApply, VecZnxDftBytesOf},
3    layouts::{Backend, Data, HostDataMut, HostDataRef, Module},
4};
5
6use crate::{
7    GetDistribution, GetDistributionMut,
8    dist::Distribution,
9    layouts::{
10        Base2K, Degree, GLWEInfos, GLWEPrepared, GLWEPreparedBackendMut, GLWEPreparedBackendRef, GLWEPreparedFactory,
11        GLWEPreparedToBackendMut, GLWEPreparedToBackendRef, GLWEToBackendRef, GetDegree, LWEInfos, Rank, TorusPrecision,
12    },
13};
14
15/// DFT-domain (prepared) variant of a GLWE public key.
16///
17/// Wraps a [`GLWEPrepared`] with distribution metadata for public-key
18/// encryption. Tied to a specific backend via `B: Backend`.
19#[derive(PartialEq, Eq)]
20pub struct GLWEPublicKeyPrepared<D: Data, B: Backend> {
21    pub(crate) key: GLWEPrepared<D, B>,
22    pub(crate) dist: Distribution,
23}
24
25impl<D: HostDataRef, BE: Backend> GetDistribution for GLWEPublicKeyPrepared<D, BE> {
26    fn dist(&self) -> &Distribution {
27        &self.dist
28    }
29}
30
31impl<D: HostDataMut, BE: Backend> GetDistributionMut for GLWEPublicKeyPrepared<D, BE> {
32    fn dist_mut(&mut self) -> &mut Distribution {
33        &mut self.dist
34    }
35}
36
37impl<D: Data, B: Backend> LWEInfos for GLWEPublicKeyPrepared<D, B> {
38    fn base2k(&self) -> Base2K {
39        self.key.base2k()
40    }
41
42    fn size(&self) -> usize {
43        self.key.size()
44    }
45
46    fn n(&self) -> Degree {
47        self.key.n()
48    }
49}
50
51impl<D: Data, B: Backend> GLWEInfos for GLWEPublicKeyPrepared<D, B> {
52    fn rank(&self) -> Rank {
53        self.key.rank()
54    }
55}
56
57pub trait GLWEPublicKeyPreparedFactory<B: Backend>
58where
59    Self: GetDegree + GLWEPreparedFactory<B>,
60{
61    fn glwe_public_key_prepared_alloc(
62        &self,
63        base2k: Base2K,
64        k: TorusPrecision,
65        rank: Rank,
66    ) -> GLWEPublicKeyPrepared<B::OwnedBuf, B> {
67        GLWEPublicKeyPrepared {
68            key: self.glwe_prepared_alloc(base2k, k, rank),
69            dist: Distribution::NONE,
70        }
71    }
72
73    fn glwe_public_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> GLWEPublicKeyPrepared<B::OwnedBuf, B>
74    where
75        A: GLWEInfos,
76    {
77        self.glwe_public_key_prepared_alloc(infos.base2k(), infos.max_k(), infos.rank())
78    }
79
80    fn glwe_public_key_prepared_bytes_of(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
81        self.glwe_prepared_bytes_of(base2k, k, rank)
82    }
83
84    fn glwe_public_key_prepared_bytes_of_from_infos<A>(&self, infos: &A) -> usize
85    where
86        A: GLWEInfos,
87    {
88        self.glwe_public_key_prepared_bytes_of(infos.base2k(), infos.max_k(), infos.rank())
89    }
90
91    fn glwe_public_key_prepare<R, O>(&self, res: &mut R, other: &O)
92    where
93        R: GLWEPreparedToBackendMut<B> + GetDistributionMut,
94        O: GLWEToBackendRef<B> + GetDistribution + GLWEInfos,
95    {
96        self.glwe_prepare(res, other);
97        *res.dist_mut() = *other.dist();
98    }
99}
100
101impl<B: Backend> GLWEPublicKeyPreparedFactory<B> for Module<B> where Self: VecZnxDftAlloc<B> + VecZnxDftBytesOf + VecZnxDftApply<B>
102{}
103
104// module-only API: allocation, sizing, and preparation are provided by
105// `GLWEPublicKeyPreparedFactory` on `Module`.
106
107pub type GLWEPublicKeyPreparedBackendRef<'a, B> = GLWEPublicKeyPrepared<<B as Backend>::BufRef<'a>, B>;
108pub type GLWEPublicKeyPreparedBackendMut<'a, B> = GLWEPublicKeyPrepared<<B as Backend>::BufMut<'a>, B>;
109
110pub trait GLWEPublicKeyPreparedToBackendRef<B: Backend> {
111    fn to_backend_ref(&self) -> GLWEPublicKeyPreparedBackendRef<'_, B>;
112}
113
114impl<D: Data, B: Backend> GLWEPublicKeyPreparedToBackendRef<B> for GLWEPublicKeyPrepared<D, B>
115where
116    GLWEPrepared<D, B>: GLWEPreparedToBackendRef<B>,
117{
118    fn to_backend_ref(&self) -> GLWEPublicKeyPreparedBackendRef<'_, B> {
119        GLWEPublicKeyPrepared {
120            key: self.key.to_backend_ref(),
121            dist: self.dist,
122        }
123    }
124}
125
126pub trait GLWEPublicKeyPreparedToBackendMut<B: Backend> {
127    fn to_backend_mut(&mut self) -> GLWEPublicKeyPreparedBackendMut<'_, B>;
128}
129
130impl<D: Data, B: Backend> GLWEPublicKeyPreparedToBackendMut<B> for GLWEPublicKeyPrepared<D, B>
131where
132    GLWEPrepared<D, B>: GLWEPreparedToBackendMut<B>,
133{
134    fn to_backend_mut(&mut self) -> GLWEPublicKeyPreparedBackendMut<'_, B> {
135        GLWEPublicKeyPrepared {
136            key: self.key.to_backend_mut(),
137            dist: self.dist,
138        }
139    }
140}
141
142impl<D: Data, B: Backend> GLWEPreparedToBackendMut<B> for GLWEPublicKeyPrepared<D, B>
143where
144    GLWEPrepared<D, B>: GLWEPreparedToBackendMut<B>,
145{
146    fn to_backend_mut(&mut self) -> GLWEPreparedBackendMut<'_, B> {
147        self.key.to_backend_mut()
148    }
149}
150
151impl<D: Data, B: Backend> GLWEPreparedToBackendRef<B> for GLWEPublicKeyPrepared<D, B>
152where
153    GLWEPrepared<D, B>: GLWEPreparedToBackendRef<B>,
154{
155    fn to_backend_ref(&self) -> GLWEPreparedBackendRef<'_, B> {
156        self.key.to_backend_ref()
157    }
158}