poulpy/rlwe/src/elem.rs
rlwe/src/elem.rsRaw
1use base2k::{Infos, Module, VecZnx, VecZnxApi, VecZnxBorrow, VecZnxOps, VmpPMat, VmpPMatOps};
2
3use crate::parameters::Parameters;
4
5impl Parameters {
6 pub fn elem_from_bytes<T>(&self, log_q: usize, rows: usize, bytes: &mut [u8]) -> Elem<T>
7 where
8 T: VecZnxCommon,
9 Elem<T>: Infos + ElemVecZnx<T>,
10 {
11 Elem::<T>::from_bytes(self.module(), self.log_base2k(), log_q, rows, bytes)
12 }
13}
14
15pub struct Elem<T> {
16 pub value: Vec<T>,
17 pub log_base2k: usize,
18 pub log_q: usize,
19 pub log_scale: usize,
20}
21
22pub trait VecZnxCommon: VecZnxApi + Infos {}
23impl VecZnxCommon for VecZnx {}
24impl VecZnxCommon for VecZnxBorrow {}
25
26pub trait ElemVecZnx<T: VecZnxCommon> {
27 fn from_bytes(
28 module: &Module,
29 log_base2k: usize,
30 log_q: usize,
31 rows: usize,
32 bytes: &mut [u8],
33 ) -> Elem<T>;
34 fn bytes_of(module: &Module, log_base2k: usize, log_q: usize, rows: usize) -> usize;
35 fn at(&self, i: usize) -> &T;
36 fn at_mut(&mut self, i: usize) -> &mut T;
37 fn zero(&mut self);
38}
39
40impl<T> ElemVecZnx<T> for Elem<T>
41where
42 T: VecZnxCommon<Owned = T>,
43 Elem<T>: Infos,
44{
45 fn bytes_of(module: &Module, log_base2k: usize, log_q: usize, rows: usize) -> usize {
46 let cols = (log_q + log_base2k - 1) / log_base2k;
47 module.n() * cols * (rows + 1) * 8
48 }
49
50 fn from_bytes(
51 module: &Module,
52 log_base2k: usize,
53 log_q: usize,
54 rows: usize,
55 bytes: &mut [u8],
56 ) -> Elem<T> {
57 assert!(rows > 0);
58 let n: usize = module.n();
59 assert!(bytes.len() >= Self::bytes_of(module, log_base2k, log_q, rows));
60 let mut value: Vec<T> = Vec::new();
61 let limbs: usize = (log_q + log_base2k - 1) / log_base2k;
62 let size = T::bytes_of(n, limbs);
63 let mut ptr: usize = 0;
64 (0..rows).for_each(|_| {
65 value.push(T::from_bytes(n, limbs, &mut bytes[ptr..]));
66 ptr += size
67 });
68 Self {
69 value,
70 log_q,
71 log_base2k,
72 log_scale: 0,
73 }
74 }
75
76 fn at(&self, i: usize) -> &T {
77 assert!(i < self.rows());
78 &self.value[i]
79 }
80
81 fn at_mut(&mut self, i: usize) -> &mut T {
82 assert!(i < self.rows());
83 &mut self.value[i]
84 }
85
86 fn zero(&mut self) {
87 self.value.iter_mut().for_each(|i| i.zero());
88 }
89}
90
91impl<T> Elem<T> {
92 pub fn log_base2k(&self) -> usize {
93 self.log_base2k
94 }
95
96 pub fn log_q(&self) -> usize {
97 self.log_q
98 }
99
100 pub fn log_scale(&self) -> usize {
101 self.log_scale
102 }
103}
104
105impl Infos for Elem<VecZnx> {
106 fn n(&self) -> usize {
107 self.value[0].n()
108 }
109
110 fn log_n(&self) -> usize {
111 self.value[0].log_n()
112 }
113
114 fn rows(&self) -> usize {
115 self.value.len()
116 }
117 fn cols(&self) -> usize {
118 self.value[0].cols()
119 }
120}
121
122impl Infos for Elem<VecZnxBorrow> {
123 fn n(&self) -> usize {
124 self.value[0].n()
125 }
126
127 fn log_n(&self) -> usize {
128 self.value[0].log_n()
129 }
130
131 fn rows(&self) -> usize {
132 self.value.len()
133 }
134 fn cols(&self) -> usize {
135 self.value[0].cols()
136 }
137}
138
139impl Elem<VecZnx> {
140 pub fn new(module: &Module, log_base2k: usize, log_q: usize, rows: usize) -> Self {
141 assert!(rows > 0);
142 let limbs: usize = (log_q + log_base2k - 1) / log_base2k;
143 let mut value: Vec<VecZnx> = Vec::new();
144 (0..rows).for_each(|_| value.push(module.new_vec_znx(limbs)));
145 Self {
146 value,
147 log_q,
148 log_base2k,
149 log_scale: 0,
150 }
151 }
152}
153
154impl Infos for Elem<VmpPMat> {
155 fn n(&self) -> usize {
156 self.value[0].n()
157 }
158
159 fn log_n(&self) -> usize {
160 self.value[0].log_n()
161 }
162
163 fn rows(&self) -> usize {
164 self.value[0].rows()
165 }
166
167 fn cols(&self) -> usize {
168 self.value[0].cols()
169 }
170}
171
172impl Elem<VmpPMat> {
173 pub fn new(module: &Module, log_base2k: usize, rows: usize, cols: usize) -> Self {
174 assert!(rows > 0);
175 assert!(cols > 0);
176 Self {
177 value: Vec::from([module.new_vmp_pmat(rows, cols); 1]),
178 log_q: 0,
179 log_base2k: log_base2k,
180 log_scale: 0,
181 }
182 }
183}