poulpy_core/layouts/prepared/
glwe_sk.rs

1use poulpy_hal::{
2    api::{SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare},
3    layouts::{Backend, Data, DataMut, DataRef, Module, SvpPPol, ZnxInfos},
4};
5
6use crate::{
7    dist::Distribution,
8    layouts::{
9        Base2K, Degree, GLWEInfos, GLWESecret, LWEInfos, Rank, TorusPrecision,
10        prepared::{Prepare, PrepareAlloc},
11    },
12};
13
14pub struct GLWESecretPrepared<D: Data, B: Backend> {
15    pub(crate) data: SvpPPol<D, B>,
16    pub(crate) dist: Distribution,
17}
18
19impl<D: Data, B: Backend> LWEInfos for GLWESecretPrepared<D, B> {
20    fn base2k(&self) -> Base2K {
21        Base2K(0)
22    }
23
24    fn k(&self) -> TorusPrecision {
25        TorusPrecision(0)
26    }
27
28    fn n(&self) -> Degree {
29        Degree(self.data.n() as u32)
30    }
31
32    fn size(&self) -> usize {
33        self.data.size()
34    }
35}
36impl<D: Data, B: Backend> GLWEInfos for GLWESecretPrepared<D, B> {
37    fn rank(&self) -> Rank {
38        Rank(self.data.cols() as u32)
39    }
40}
41impl<B: Backend> GLWESecretPrepared<Vec<u8>, B> {
42    pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
43    where
44        A: GLWEInfos,
45        Module<B>: SvpPPolAlloc<B>,
46    {
47        assert_eq!(module.n() as u32, infos.n());
48        Self::alloc_with(module, infos.rank())
49    }
50
51    pub fn alloc_with(module: &Module<B>, rank: Rank) -> Self
52    where
53        Module<B>: SvpPPolAlloc<B>,
54    {
55        Self {
56            data: module.svp_ppol_alloc(rank.into()),
57            dist: Distribution::NONE,
58        }
59    }
60
61    pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize
62    where
63        A: GLWEInfos,
64        Module<B>: SvpPPolAllocBytes,
65    {
66        assert_eq!(module.n() as u32, infos.n());
67        Self::alloc_bytes_with(module, infos.rank())
68    }
69
70    pub fn alloc_bytes_with(module: &Module<B>, rank: Rank) -> usize
71    where
72        Module<B>: SvpPPolAllocBytes,
73    {
74        module.svp_ppol_alloc_bytes(rank.into())
75    }
76}
77
78impl<D: Data, B: Backend> GLWESecretPrepared<D, B> {
79    pub fn n(&self) -> Degree {
80        Degree(self.data.n() as u32)
81    }
82
83    pub fn rank(&self) -> Rank {
84        Rank(self.data.cols() as u32)
85    }
86}
87
88impl<D: DataRef, B: Backend> PrepareAlloc<B, GLWESecretPrepared<Vec<u8>, B>> for GLWESecret<D>
89where
90    Module<B>: SvpPrepare<B> + SvpPPolAlloc<B>,
91{
92    fn prepare_alloc(&self, module: &Module<B>, scratch: &mut poulpy_hal::layouts::Scratch<B>) -> GLWESecretPrepared<Vec<u8>, B> {
93        let mut sk_dft: GLWESecretPrepared<Vec<u8>, B> = GLWESecretPrepared::alloc(module, self);
94        sk_dft.prepare(module, self, scratch);
95        sk_dft
96    }
97}
98
99impl<DM: DataMut, DR: DataRef, B: Backend> Prepare<B, GLWESecret<DR>> for GLWESecretPrepared<DM, B>
100where
101    Module<B>: SvpPrepare<B>,
102{
103    fn prepare(&mut self, module: &Module<B>, other: &GLWESecret<DR>, _scratch: &mut poulpy_hal::layouts::Scratch<B>) {
104        (0..self.rank().into()).for_each(|i| {
105            module.svp_prepare(&mut self.data, i, &other.data, i);
106        });
107        self.dist = other.dist
108    }
109}