poulpy/poulpy-core/src/layouts/prepared/gglwe_ct.rs
poulpy-core/src/layouts/prepared/gglwe_ct.rsRaw
1use poulpy_hal::{
2 api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
3 layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
4};
5
6use crate::layouts::{
7 GGLWECiphertext, Infos,
8 prepared::{Prepare, PrepareAlloc},
9};
10
11#[derive(PartialEq, Eq)]
12pub struct GGLWECiphertextPrepared<D: Data, B: Backend> {
13 pub(crate) data: VmpPMat<D, B>,
14 pub(crate) basek: usize,
15 pub(crate) k: usize,
16 pub(crate) digits: usize,
17}
18
19impl<B: Backend> GGLWECiphertextPrepared<Vec<u8>, B> {
20 #[allow(clippy::too_many_arguments)]
21 pub fn alloc(
22 module: &Module<B>,
23 n: usize,
24 basek: usize,
25 k: usize,
26 rows: usize,
27 digits: usize,
28 rank_in: usize,
29 rank_out: usize,
30 ) -> Self
31 where
32 Module<B>: VmpPMatAlloc<B>,
33 {
34 let size: usize = k.div_ceil(basek);
35 debug_assert!(
36 size > digits,
37 "invalid gglwe: ceil(k/basek): {} <= digits: {}",
38 size,
39 digits
40 );
41
42 assert!(
43 rows * digits <= size,
44 "invalid gglwe: rows: {} * digits:{} > ceil(k/basek): {}",
45 rows,
46 digits,
47 size
48 );
49
50 Self {
51 data: module.vmp_pmat_alloc(n, rows, rank_in, rank_out + 1, size),
52 basek,
53 k,
54 digits,
55 }
56 }
57
58 #[allow(clippy::too_many_arguments)]
59 pub fn bytes_of(
60 module: &Module<B>,
61 n: usize,
62 basek: usize,
63 k: usize,
64 rows: usize,
65 digits: usize,
66 rank_in: usize,
67 rank_out: usize,
68 ) -> usize
69 where
70 Module<B>: VmpPMatAllocBytes,
71 {
72 let size: usize = k.div_ceil(basek);
73 debug_assert!(
74 size > digits,
75 "invalid gglwe: ceil(k/basek): {} <= digits: {}",
76 size,
77 digits
78 );
79
80 assert!(
81 rows * digits <= size,
82 "invalid gglwe: rows: {} * digits:{} > ceil(k/basek): {}",
83 rows,
84 digits,
85 size
86 );
87
88 module.vmp_pmat_alloc_bytes(n, rows, rank_in, rank_out + 1, rows)
89 }
90}
91
92impl<D: Data, B: Backend> Infos for GGLWECiphertextPrepared<D, B> {
93 type Inner = VmpPMat<D, B>;
94
95 fn inner(&self) -> &Self::Inner {
96 &self.data
97 }
98
99 fn basek(&self) -> usize {
100 self.basek
101 }
102
103 fn k(&self) -> usize {
104 self.k
105 }
106}
107
108impl<D: Data, B: Backend> GGLWECiphertextPrepared<D, B> {
109 pub fn rank(&self) -> usize {
110 self.data.cols_out() - 1
111 }
112
113 pub fn digits(&self) -> usize {
114 self.digits
115 }
116
117 pub fn rank_in(&self) -> usize {
118 self.data.cols_in()
119 }
120
121 pub fn rank_out(&self) -> usize {
122 self.data.cols_out() - 1
123 }
124}
125
126impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWECiphertext<DR>> for GGLWECiphertextPrepared<D, B>
127where
128 Module<B>: VmpPrepare<B>,
129{
130 fn prepare(&mut self, module: &Module<B>, other: &GGLWECiphertext<DR>, scratch: &mut Scratch<B>) {
131 module.vmp_prepare(&mut self.data, &other.data, scratch);
132 self.basek = other.basek;
133 self.k = other.k;
134 self.digits = other.digits;
135 }
136}
137
138impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWECiphertextPrepared<Vec<u8>, B>> for GGLWECiphertext<D>
139where
140 Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
141{
142 fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWECiphertextPrepared<Vec<u8>, B> {
143 let mut atk_prepared: GGLWECiphertextPrepared<Vec<u8>, B> = GGLWECiphertextPrepared::alloc(
144 module,
145 self.n(),
146 self.basek(),
147 self.k(),
148 self.rows(),
149 self.digits(),
150 self.rank_in(),
151 self.rank_out(),
152 );
153 atk_prepared.prepare(module, self, scratch);
154 atk_prepared
155 }
156}