arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/math/src/ring/impl_u64/trace.rs
math/src/ring/impl_u64/trace.rsRaw
 1use crate::modulus::barrett::Barrett;
 2use crate::modulus::ONCE;
 3use crate::poly::Poly;
 4use crate::ring::Ring;
 5
 6impl Ring<u64> {
 7    pub fn trace_inplace<const NTT: bool>(&self, step_start: usize, a: &mut Poly<u64>) {
 8        assert!(
 9            step_start <= self.log_n(),
10            "invalid argument step_start: step_start={} > self.log_n()={}",
11            step_start,
12            self.log_n()
13        );
14
15        let log_steps: usize = self.log_n() - step_start;
16        let log_nth_root = self.log_n() + 1;
17        let nth_root: usize = 1 << log_nth_root;
18
19        if log_steps > 0 {
20            let n_inv: Barrett<u64> = self
21                .modulus
22                .barrett
23                .prepare(self.modulus.inv(1 << log_steps));
24            self.a_mul_b_scalar_barrett_into_a::<ONCE>(&n_inv, a);
25
26            let mut tmp: Poly<u64> = self.new_poly();
27
28            (step_start..self.log_n()).for_each(|i| {
29                let gal_el: usize = self.galois_element((1 << i) >> 1, i == 0, log_nth_root);
30
31                self.a_apply_automorphism_into_b::<NTT>(a, gal_el, nth_root, &mut tmp);
32                self.a_add_b_into_b::<ONCE>(&tmp, a);
33            });
34        }
35    }
36}