Skip to main content

poulpy_core/oep/
decryption.rs

1use poulpy_hal::{
2    layouts::{Backend, Data, HostBackend, HostDataMut, HostDataRef, Module, ScratchArena},
3    oep::{HalSvpImpl, HalVecZnxBigImpl, HalVecZnxDftImpl, HalVecZnxImpl},
4};
5
6use crate::layouts::{
7    GLWEInfos, GLWEPlaintext, GLWESecretPrepared, GLWESecretTensorPrepared, GLWETensor, GLWEToBackendMut, GLWEToBackendRef,
8    LWEInfos, LWEPlaintextToBackendMut, LWESecretToBackendRef, LWEToBackendRef, SetLWEInfos,
9    prepared::{GLWESecretPreparedToBackendRef, GLWESecretTensorPreparedToBackendRef},
10};
11
12/// Backend-provided decryption operations.
13///
14/// # Safety
15/// Implementations must interpret ciphertexts, plaintexts, and secrets according to their layout
16/// metadata, avoid out-of-bounds or aliased writes, and only use scratch space within the
17/// advertised temporary-size contracts.
18pub unsafe trait DecryptionImpl<BE: Backend>: Backend {
19    fn glwe_decrypt_tmp_bytes<A>(module: &Module<BE>, infos: &A) -> usize
20    where
21        A: GLWEInfos;
22
23    fn glwe_decrypt<R, P, S>(module: &Module<BE>, res: &R, pt: &mut P, sk: &S, scratch: &mut ScratchArena<'_, BE>)
24    where
25        R: GLWEToBackendRef<BE> + GLWEInfos,
26        P: GLWEToBackendMut<BE> + GLWEInfos + SetLWEInfos,
27        S: GLWESecretPreparedToBackendRef<BE> + GLWEInfos;
28
29    fn lwe_decrypt_tmp_bytes<A>(module: &Module<BE>, infos: &A) -> usize
30    where
31        A: LWEInfos;
32
33    fn lwe_decrypt<R, P, S>(module: &Module<BE>, res: &R, pt: &mut P, sk: &S, scratch: &mut ScratchArena<'_, BE>)
34    where
35        R: LWEToBackendRef<BE> + LWEInfos,
36        P: LWEPlaintextToBackendMut<BE> + SetLWEInfos + LWEInfos,
37        S: LWESecretToBackendRef<BE> + LWEInfos;
38
39    fn glwe_tensor_decrypt<R: Data, P: Data, S0: Data, S1: Data>(
40        module: &Module<BE>,
41        res: &GLWETensor<R>,
42        pt: &mut GLWEPlaintext<P>,
43        sk: &GLWESecretPrepared<S0, BE>,
44        sk_tensor: &GLWESecretTensorPrepared<S1, BE>,
45        scratch: &mut ScratchArena<'_, BE>,
46    ) where
47        GLWETensor<R>: GLWEToBackendRef<BE> + GLWEInfos,
48        GLWEPlaintext<P>: GLWEToBackendMut<BE> + GLWEInfos + SetLWEInfos,
49        GLWESecretPrepared<S0, BE>: GLWESecretPreparedToBackendRef<BE> + GLWEInfos,
50        GLWESecretTensorPrepared<S1, BE>: GLWESecretTensorPreparedToBackendRef<BE> + GLWEInfos;
51
52    fn glwe_tensor_decrypt_tmp_bytes<A>(module: &Module<BE>, infos: &A) -> usize
53    where
54        A: GLWEInfos;
55}
56
57/// Override surface for the decryption family.
58///
59/// Abstract: no HAL supertraits, no default method bodies. See [`decryption_defaults`]
60/// for reference algorithms a backend may forward to.
61#[doc(hidden)]
62#[allow(private_bounds)]
63pub trait DecryptionDefault<BE: Backend> {
64    fn glwe_decrypt_tmp_bytes_default<A>(&self, infos: &A) -> usize
65    where
66        A: GLWEInfos;
67
68    fn glwe_decrypt_default<R, P, S>(&self, res: &R, pt: &mut P, sk: &S, scratch: &mut ScratchArena<'_, BE>)
69    where
70        R: GLWEToBackendRef<BE> + GLWEInfos,
71        P: GLWEToBackendMut<BE> + GLWEInfos + SetLWEInfos,
72        S: GLWESecretPreparedToBackendRef<BE> + GLWEInfos;
73
74    fn lwe_decrypt_tmp_bytes_default<A>(&self, infos: &A) -> usize
75    where
76        A: LWEInfos;
77
78    fn lwe_decrypt_default<R, P, S>(&self, res: &R, pt: &mut P, sk: &S, scratch: &mut ScratchArena<'_, BE>)
79    where
80        R: LWEToBackendRef<BE> + LWEInfos,
81        P: LWEPlaintextToBackendMut<BE> + SetLWEInfos + LWEInfos,
82        S: LWESecretToBackendRef<BE> + LWEInfos,
83        BE: HostBackend,
84        for<'a> BE::BufMut<'a>: HostDataMut,
85        for<'a> BE::BufRef<'a>: HostDataRef;
86
87    fn glwe_tensor_decrypt_default<R: Data, P: Data, S0: Data, S1: Data>(
88        &self,
89        res: &GLWETensor<R>,
90        pt: &mut GLWEPlaintext<P>,
91        sk: &GLWESecretPrepared<S0, BE>,
92        sk_tensor: &GLWESecretTensorPrepared<S1, BE>,
93        scratch: &mut ScratchArena<'_, BE>,
94    ) where
95        GLWETensor<R>: GLWEToBackendRef<BE> + GLWEInfos,
96        GLWEPlaintext<P>: GLWEToBackendMut<BE> + GLWEInfos + SetLWEInfos,
97        GLWESecretPrepared<S0, BE>: GLWESecretPreparedToBackendRef<BE> + GLWEInfos,
98        GLWESecretTensorPrepared<S1, BE>: GLWESecretTensorPreparedToBackendRef<BE> + GLWEInfos;
99
100    fn glwe_tensor_decrypt_tmp_bytes_default<A>(&self, infos: &A) -> usize
101    where
102        A: GLWEInfos;
103}
104
105/// Implements [`DecryptionDefault`] for `Module<$be>` by forwarding every method to
106/// the corresponding [`decryption_defaults`] free function.
107#[macro_export]
108macro_rules! impl_decryption_defaults_full {
109    ($be:ty) => {
110        impl $crate::oep::DecryptionDefault<$be> for ::poulpy_hal::layouts::Module<$be> {
111            fn glwe_decrypt_tmp_bytes_default<A>(&self, infos: &A) -> usize
112            where
113                A: $crate::layouts::GLWEInfos,
114            {
115                $crate::default::decryption::glwe::glwe_decrypt_tmp_bytes_default::<Self, $be, _>(self, infos)
116            }
117
118            fn glwe_decrypt_default<R, P, S>(
119                &self,
120                res: &R,
121                pt: &mut P,
122                sk: &S,
123                scratch: &mut ::poulpy_hal::layouts::ScratchArena<'_, $be>,
124            ) where
125                R: $crate::layouts::GLWEToBackendRef<$be> + $crate::layouts::GLWEInfos,
126                P: $crate::layouts::GLWEToBackendMut<$be> + $crate::layouts::GLWEInfos + $crate::layouts::SetLWEInfos,
127                S: $crate::layouts::prepared::GLWESecretPreparedToBackendRef<$be> + $crate::layouts::GLWEInfos,
128            {
129                $crate::default::decryption::glwe::glwe_decrypt_default::<Self, $be, _, _, _>(self, res, pt, sk, scratch)
130            }
131
132            fn lwe_decrypt_tmp_bytes_default<A>(&self, infos: &A) -> usize
133            where
134                A: $crate::layouts::LWEInfos,
135            {
136                $crate::default::decryption::lwe::lwe_decrypt_tmp_bytes_default::<Self, $be, _>(self, infos)
137            }
138
139            fn lwe_decrypt_default<R, P, S>(
140                &self,
141                res: &R,
142                pt: &mut P,
143                sk: &S,
144                scratch: &mut ::poulpy_hal::layouts::ScratchArena<'_, $be>,
145            ) where
146                R: $crate::layouts::LWEToBackendRef<$be> + $crate::layouts::LWEInfos,
147                P: $crate::layouts::LWEPlaintextToBackendMut<$be> + $crate::layouts::SetLWEInfos + $crate::layouts::LWEInfos,
148                S: $crate::layouts::LWESecretToBackendRef<$be> + $crate::layouts::LWEInfos,
149                $be: ::poulpy_hal::layouts::HostBackend,
150            {
151                $crate::default::decryption::lwe::lwe_decrypt_default::<Self, $be, _, _, _>(self, res, pt, sk, scratch)
152            }
153
154            fn glwe_tensor_decrypt_default<
155                R: ::poulpy_hal::layouts::Data,
156                P: ::poulpy_hal::layouts::Data,
157                S0: ::poulpy_hal::layouts::Data,
158                S1: ::poulpy_hal::layouts::Data,
159            >(
160                &self,
161                res: &$crate::layouts::GLWETensor<R>,
162                pt: &mut $crate::layouts::GLWEPlaintext<P>,
163                sk: &$crate::layouts::GLWESecretPrepared<S0, $be>,
164                sk_tensor: &$crate::layouts::GLWESecretTensorPrepared<S1, $be>,
165                scratch: &mut ::poulpy_hal::layouts::ScratchArena<'_, $be>,
166            ) where
167                $crate::layouts::GLWETensor<R>: $crate::layouts::GLWEToBackendRef<$be> + $crate::layouts::GLWEInfos,
168                $crate::layouts::GLWEPlaintext<P>:
169                    $crate::layouts::GLWEToBackendMut<$be> + $crate::layouts::GLWEInfos + $crate::layouts::SetLWEInfos,
170                $crate::layouts::GLWESecretPrepared<S0, $be>:
171                    $crate::layouts::prepared::GLWESecretPreparedToBackendRef<$be> + $crate::layouts::GLWEInfos,
172                $crate::layouts::GLWESecretTensorPrepared<S1, $be>:
173                    $crate::layouts::prepared::GLWESecretTensorPreparedToBackendRef<$be> + $crate::layouts::GLWEInfos,
174            {
175                $crate::default::decryption::glwe_tensor::glwe_tensor_decrypt_default::<Self, $be, R, P, S0, S1>(
176                    self, res, pt, sk, sk_tensor, scratch,
177                )
178            }
179
180            fn glwe_tensor_decrypt_tmp_bytes_default<A>(&self, infos: &A) -> usize
181            where
182                A: $crate::layouts::GLWEInfos,
183            {
184                $crate::default::decryption::glwe_tensor::glwe_tensor_decrypt_tmp_bytes_default::<Self, $be, _>(self, infos)
185            }
186        }
187    };
188}
189
190#[allow(private_bounds)]
191unsafe impl<BE: Backend + HostBackend + HalVecZnxImpl<BE> + HalVecZnxBigImpl<BE> + HalVecZnxDftImpl<BE> + HalSvpImpl<BE>>
192    DecryptionImpl<BE> for BE
193where
194    Module<BE>: DecryptionDefault<BE>,
195    for<'a> BE::BufMut<'a>: HostDataMut,
196    for<'a> BE::BufRef<'a>: HostDataRef,
197{
198    fn glwe_decrypt_tmp_bytes<A>(module: &Module<BE>, infos: &A) -> usize
199    where
200        A: GLWEInfos,
201    {
202        <Module<BE> as DecryptionDefault<BE>>::glwe_decrypt_tmp_bytes_default(module, infos)
203    }
204
205    fn glwe_decrypt<R, P, S>(module: &Module<BE>, res: &R, pt: &mut P, sk: &S, scratch: &mut ScratchArena<'_, BE>)
206    where
207        R: GLWEToBackendRef<BE> + GLWEInfos,
208        P: GLWEToBackendMut<BE> + GLWEInfos + SetLWEInfos,
209        S: GLWESecretPreparedToBackendRef<BE> + GLWEInfos,
210    {
211        <Module<BE> as DecryptionDefault<BE>>::glwe_decrypt_default(module, res, pt, sk, scratch)
212    }
213
214    fn lwe_decrypt_tmp_bytes<A>(module: &Module<BE>, infos: &A) -> usize
215    where
216        A: LWEInfos,
217    {
218        <Module<BE> as DecryptionDefault<BE>>::lwe_decrypt_tmp_bytes_default(module, infos)
219    }
220
221    fn lwe_decrypt<R, P, S>(module: &Module<BE>, res: &R, pt: &mut P, sk: &S, scratch: &mut ScratchArena<'_, BE>)
222    where
223        R: LWEToBackendRef<BE> + LWEInfos,
224        P: LWEPlaintextToBackendMut<BE> + SetLWEInfos + LWEInfos,
225        S: LWESecretToBackendRef<BE> + LWEInfos,
226    {
227        <Module<BE> as DecryptionDefault<BE>>::lwe_decrypt_default(module, res, pt, sk, scratch)
228    }
229
230    fn glwe_tensor_decrypt<R: Data, P: Data, S0: Data, S1: Data>(
231        module: &Module<BE>,
232        res: &GLWETensor<R>,
233        pt: &mut GLWEPlaintext<P>,
234        sk: &GLWESecretPrepared<S0, BE>,
235        sk_tensor: &GLWESecretTensorPrepared<S1, BE>,
236        scratch: &mut ScratchArena<'_, BE>,
237    ) where
238        GLWETensor<R>: GLWEToBackendRef<BE> + GLWEInfos,
239        GLWEPlaintext<P>: GLWEToBackendMut<BE> + GLWEInfos + SetLWEInfos,
240        GLWESecretPrepared<S0, BE>: GLWESecretPreparedToBackendRef<BE> + GLWEInfos,
241        GLWESecretTensorPrepared<S1, BE>: GLWESecretTensorPreparedToBackendRef<BE> + GLWEInfos,
242    {
243        <Module<BE> as DecryptionDefault<BE>>::glwe_tensor_decrypt_default(module, res, pt, sk, sk_tensor, scratch)
244    }
245
246    fn glwe_tensor_decrypt_tmp_bytes<A>(module: &Module<BE>, infos: &A) -> usize
247    where
248        A: GLWEInfos,
249    {
250        <Module<BE> as DecryptionDefault<BE>>::glwe_tensor_decrypt_tmp_bytes_default(module, infos)
251    }
252}