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