poulpy/core/src/gglwe/ciphertext.rs
core/src/gglwe/ciphertext.rsRaw
1use backend::{Backend, FFT64, MatZnxDft, MatZnxDftAlloc, MatZnxDftOps, Module};
2
3use crate::{FourierGLWECiphertext, GetRow, Infos, SetRow, div_ceil};
4
5pub struct GGLWECiphertext<C, B: Backend> {
6 pub(crate) data: MatZnxDft<C, B>,
7 pub(crate) basek: usize,
8 pub(crate) k: usize,
9 pub(crate) digits: usize,
10}
11
12impl<B: Backend> GGLWECiphertext<Vec<u8>, B> {
13 pub fn alloc(
14 module: &Module<B>,
15 basek: usize,
16 k: usize,
17 rows: usize,
18 digits: usize,
19 rank_in: usize,
20 rank_out: usize,
21 ) -> Self {
22 let size: usize = div_ceil(k, basek);
23 debug_assert!(
24 size > digits,
25 "invalid gglwe: ceil(k/basek): {} <= digits: {}",
26 size,
27 digits
28 );
29
30 assert!(
31 rows * digits <= size,
32 "invalid gglwe: rows: {} * digits:{} > ceil(k/basek): {}",
33 rows,
34 digits,
35 size
36 );
37
38 Self {
39 data: module.new_mat_znx_dft(rows, rank_in, rank_out + 1, size),
40 basek: basek,
41 k,
42 digits,
43 }
44 }
45
46 pub fn bytes_of(
47 module: &Module<FFT64>,
48 basek: usize,
49 k: usize,
50 rows: usize,
51 digits: usize,
52 rank_in: usize,
53 rank_out: usize,
54 ) -> usize {
55 let size: usize = div_ceil(k, basek);
56 debug_assert!(
57 size > digits,
58 "invalid gglwe: ceil(k/basek): {} <= digits: {}",
59 size,
60 digits
61 );
62
63 assert!(
64 rows * digits <= size,
65 "invalid gglwe: rows: {} * digits:{} > ceil(k/basek): {}",
66 rows,
67 digits,
68 size
69 );
70
71 module.bytes_of_mat_znx_dft(rows, rank_in, rank_out + 1, rows)
72 }
73}
74
75impl<T, B: Backend> Infos for GGLWECiphertext<T, B> {
76 type Inner = MatZnxDft<T, B>;
77
78 fn inner(&self) -> &Self::Inner {
79 &self.data
80 }
81
82 fn basek(&self) -> usize {
83 self.basek
84 }
85
86 fn k(&self) -> usize {
87 self.k
88 }
89}
90
91impl<T, B: Backend> GGLWECiphertext<T, B> {
92 pub fn rank(&self) -> usize {
93 self.data.cols_out() - 1
94 }
95
96 pub fn digits(&self) -> usize {
97 self.digits
98 }
99
100 pub fn rank_in(&self) -> usize {
101 self.data.cols_in()
102 }
103
104 pub fn rank_out(&self) -> usize {
105 self.data.cols_out() - 1
106 }
107}
108
109impl<C: AsRef<[u8]>> GetRow<FFT64> for GGLWECiphertext<C, FFT64> {
110 fn get_row<R: AsMut<[u8]> + AsRef<[u8]>>(
111 &self,
112 module: &Module<FFT64>,
113 row_i: usize,
114 col_j: usize,
115 res: &mut FourierGLWECiphertext<R, FFT64>,
116 ) {
117 module.mat_znx_dft_get_row(&mut res.data, &self.data, row_i, col_j);
118 }
119}
120
121impl<C: AsMut<[u8]> + AsRef<[u8]>> SetRow<FFT64> for GGLWECiphertext<C, FFT64> {
122 fn set_row<R: AsRef<[u8]>>(
123 &mut self,
124 module: &Module<FFT64>,
125 row_i: usize,
126 col_j: usize,
127 a: &FourierGLWECiphertext<R, FFT64>,
128 ) {
129 module.mat_znx_dft_set_row(&mut self.data, row_i, col_j, &a.data);
130 }
131}