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