poulpy/core/src/glwe_ops.rs
core/src/glwe_ops.rsRaw
1use backend::{FFT64, Module, Scratch, VecZnx, VecZnxOps, VecZnxToMut, VecZnxToRef, ZnxZero};
2
3use crate::{
4 elem::{Infos, SetMetaData},
5 glwe_ciphertext::GLWECiphertext,
6};
7
8impl<DataSelf> GLWECiphertext<DataSelf>
9where
10 Self: Infos,
11 VecZnx<DataSelf>: VecZnxToMut,
12{
13 pub fn add<A, B>(&mut self, module: &Module<FFT64>, a: &A, b: &B)
14 where
15 A: VecZnxToRef + Infos,
16 B: VecZnxToRef + Infos,
17 {
18 #[cfg(debug_assertions)]
19 {
20 assert_eq!(a.n(), module.n());
21 assert_eq!(b.n(), module.n());
22 assert_eq!(self.n(), module.n());
23 assert_eq!(a.basek(), b.basek());
24 assert!(self.rank() >= a.rank().max(b.rank()));
25 }
26
27 let min_col: usize = a.rank().min(b.rank()) + 1;
28 let max_col: usize = a.rank().max(b.rank() + 1);
29 let self_col: usize = self.rank() + 1;
30
31 (0..min_col).for_each(|i| {
32 module.vec_znx_add(self, i, a, i, b, i);
33 });
34
35 if a.rank() > b.rank() {
36 (min_col..max_col).for_each(|i| {
37 module.vec_znx_copy(self, i, a, i);
38 });
39 } else {
40 (min_col..max_col).for_each(|i| {
41 module.vec_znx_copy(self, i, b, i);
42 });
43 }
44
45 let size: usize = self.size();
46 let mut self_mut: VecZnx<&mut [u8]> = self.to_mut();
47 (max_col..self_col).for_each(|i| {
48 (0..size).for_each(|j| {
49 self_mut.zero_at(i, j);
50 });
51 });
52
53 self.set_basek(a.basek());
54 self.set_k(a.k().max(b.k()));
55 }
56
57 pub fn add_inplace<A>(&mut self, module: &Module<FFT64>, a: &A)
58 where
59 A: VecZnxToRef + Infos,
60 {
61 #[cfg(debug_assertions)]
62 {
63 assert_eq!(a.n(), module.n());
64 assert_eq!(self.n(), module.n());
65 assert_eq!(self.basek(), a.basek());
66 assert!(self.rank() >= a.rank())
67 }
68
69 (0..a.rank() + 1).for_each(|i| {
70 module.vec_znx_add_inplace(self, i, a, i);
71 });
72
73 self.set_k(a.k().max(self.k()));
74 }
75
76 pub fn sub<A, B>(&mut self, module: &Module<FFT64>, a: &A, b: &B)
77 where
78 A: VecZnxToRef + Infos,
79 B: VecZnxToRef + Infos,
80 {
81 #[cfg(debug_assertions)]
82 {
83 assert_eq!(a.n(), module.n());
84 assert_eq!(b.n(), module.n());
85 assert_eq!(self.n(), module.n());
86 assert_eq!(a.basek(), b.basek());
87 assert!(self.rank() >= a.rank().max(b.rank()));
88 }
89
90 let min_col: usize = a.rank().min(b.rank()) + 1;
91 let max_col: usize = a.rank().max(b.rank() + 1);
92 let self_col: usize = self.rank() + 1;
93
94 (0..min_col).for_each(|i| {
95 module.vec_znx_sub(self, i, a, i, b, i);
96 });
97
98 if a.rank() > b.rank() {
99 (min_col..max_col).for_each(|i| {
100 module.vec_znx_copy(self, i, a, i);
101 });
102 } else {
103 (min_col..max_col).for_each(|i| {
104 module.vec_znx_copy(self, i, b, i);
105 module.vec_znx_negate_inplace(self, i);
106 });
107 }
108
109 let size: usize = self.size();
110 let mut self_mut: VecZnx<&mut [u8]> = self.to_mut();
111 (max_col..self_col).for_each(|i| {
112 (0..size).for_each(|j| {
113 self_mut.zero_at(i, j);
114 });
115 });
116
117 self.set_basek(a.basek());
118 self.set_k(a.k().max(b.k()));
119 }
120
121 pub fn sub_inplace_ab<A>(&mut self, module: &Module<FFT64>, a: &A)
122 where
123 A: VecZnxToRef + Infos,
124 {
125 #[cfg(debug_assertions)]
126 {
127 assert_eq!(a.n(), module.n());
128 assert_eq!(self.n(), module.n());
129 assert_eq!(self.basek(), a.basek());
130 assert!(self.rank() >= a.rank())
131 }
132
133 (0..a.rank() + 1).for_each(|i| {
134 module.vec_znx_sub_ab_inplace(self, i, a, i);
135 });
136
137 self.set_k(a.k().max(self.k()));
138 }
139
140 pub fn sub_inplace_ba<A>(&mut self, module: &Module<FFT64>, a: &A)
141 where
142 A: VecZnxToRef + Infos,
143 {
144 #[cfg(debug_assertions)]
145 {
146 assert_eq!(a.n(), module.n());
147 assert_eq!(self.n(), module.n());
148 assert_eq!(self.basek(), a.basek());
149 assert!(self.rank() >= a.rank())
150 }
151
152 (0..a.rank() + 1).for_each(|i| {
153 module.vec_znx_sub_ba_inplace(self, i, a, i);
154 });
155
156 self.set_k(a.k().max(self.k()));
157 }
158
159 pub fn rotate<A>(&mut self, module: &Module<FFT64>, k: i64, a: &A)
160 where
161 A: VecZnxToRef + Infos,
162 {
163 #[cfg(debug_assertions)]
164 {
165 assert_eq!(a.n(), module.n());
166 assert_eq!(self.n(), module.n());
167 assert_eq!(self.rank(), a.rank())
168 }
169
170 (0..a.rank() + 1).for_each(|i| {
171 module.vec_znx_rotate(k, self, i, a, i);
172 });
173
174 self.set_basek(a.basek());
175 self.set_k(a.k());
176 }
177
178 pub fn rotate_inplace(&mut self, module: &Module<FFT64>, k: i64){
179 #[cfg(debug_assertions)]
180 {
181 assert_eq!(self.n(), module.n());
182 }
183
184 (0..self.rank() + 1).for_each(|i| {
185 module.vec_znx_rotate_inplace(k, self, i);
186 });
187 }
188
189 pub fn copy<A>(&mut self, module: &Module<FFT64>, a: &A)
190 where
191 A: VecZnxToRef + Infos,
192 {
193 #[cfg(debug_assertions)]
194 {
195 assert_eq!(self.n(), module.n());
196 assert_eq!(a.n(), module.n());
197 assert_eq!(self.rank(), a.rank());
198 }
199
200 (0..self.rank() + 1).for_each(|i| {
201 module.vec_znx_copy(self, i, a, i);
202 });
203
204 self.set_k(a.k());
205 self.set_basek(a.basek());
206 }
207
208 pub fn rsh(&mut self, k: usize, scratch: &mut Scratch) {
209 let basek: usize = self.basek();
210 let mut self_mut: VecZnx<&mut [u8]> = self.to_mut();
211 self_mut.rsh(basek, k, scratch);
212 }
213
214 pub fn normalize<A>(&mut self, module: &Module<FFT64>, a: &A, scratch: &mut Scratch)
215 where
216 A: VecZnxToMut + Infos,
217 {
218 #[cfg(debug_assertions)]
219 {
220 assert_eq!(self.n(), module.n());
221 assert_eq!(a.n(), module.n());
222 assert_eq!(self.rank(), a.rank());
223 }
224
225 (0..self.rank() + 1).for_each(|i| {
226 module.vec_znx_normalize(a.basek(), self, i, a, i, scratch);
227 });
228 self.set_basek(a.basek());
229 self.set_k(a.k());
230 }
231
232 pub fn normalize_inplace(&mut self, module: &Module<FFT64>, scratch: &mut Scratch) {
233 #[cfg(debug_assertions)]
234 {
235 assert_eq!(self.n(), module.n());
236 }
237 (0..self.rank() + 1).for_each(|i| {
238 module.vec_znx_normalize_inplace(self.basek(), self, i, scratch);
239 });
240 }
241}
242
243impl GLWECiphertext<Vec<u8>>{
244 pub fn rsh_scratch_space(module: &Module<FFT64>) -> usize{
245 VecZnx::rsh_scratch_space(module.n())
246 }
247}