arnaucube
arnaucube/poulpyPublic Self-hosted repository
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<A>(&mut self, module: &Module<FFT64>, k: i64)
179    where
180        A: VecZnxToRef + Infos,
181    {
182        #[cfg(debug_assertions)]
183        {
184            assert_eq!(self.n(), module.n());
185        }
186
187        (0..self.rank() + 1).for_each(|i| {
188            module.vec_znx_rotate_inplace(k, self, i);
189        });
190    }
191
192    pub fn copy<A>(&mut self, module: &Module<FFT64>, a: &A)
193    where
194        A: VecZnxToRef + Infos,
195    {
196        #[cfg(debug_assertions)]
197        {
198            assert_eq!(self.n(), module.n());
199            assert_eq!(a.n(), module.n());
200            assert_eq!(self.rank(), a.rank());
201        }
202
203        (0..self.rank() + 1).for_each(|i| {
204            module.vec_znx_copy(self, i, a, i);
205        });
206
207        self.set_k(a.k());
208        self.set_basek(a.basek());
209    }
210
211    pub fn rsh(&mut self, k: usize, scratch: &mut Scratch) {
212        let basek: usize = self.basek();
213        let mut self_mut: VecZnx<&mut [u8]> = self.to_mut();
214        self_mut.rsh(basek, k, scratch);
215    }
216
217    pub fn normalize<A>(&mut self, module: &Module<FFT64>, a: &A, scratch: &mut Scratch)
218    where
219        A: VecZnxToMut + Infos,
220    {
221        #[cfg(debug_assertions)]
222        {
223            assert_eq!(self.n(), module.n());
224            assert_eq!(a.n(), module.n());
225            assert_eq!(self.rank(), a.rank());
226        }
227
228        (0..self.rank() + 1).for_each(|i| {
229            module.vec_znx_normalize(a.basek(), self, i, a, i, scratch);
230        });
231        self.set_basek(a.basek());
232        self.set_k(a.k());
233    }
234
235    pub fn normalize_inplace(&mut self, module: &Module<FFT64>, scratch: &mut Scratch) {
236        #[cfg(debug_assertions)]
237        {
238            assert_eq!(self.n(), module.n());
239        }
240        (0..self.rank() + 1).for_each(|i| {
241            module.vec_znx_normalize_inplace(self.basek(), self, i, scratch);
242        });
243    }
244}