use std::collections::HashMap; use backend::hal::{ api::{ ScratchAvailable, TakeVecZnxDft, VecZnxBigAddSmallInplace, VecZnxBigAutomorphismInplace, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxCopy, VecZnxDftAllocBytes, VecZnxDftFromVecZnx, VecZnxDftToVecZnxBigConsume, VecZnxRshInplace, VmpApply, VmpApplyAdd, VmpApplyTmpBytes, }, layouts::{Backend, DataMut, DataRef, Module, Scratch}, }; use crate::{ layouts::{GLWECiphertext, prepared::GGLWEAutomorphismKeyPrepared}, operations::GLWEOperations, }; impl GLWECiphertext> { pub fn trace_galois_elements(module: &Module) -> Vec { let mut gal_els: Vec = Vec::new(); (0..module.log_n()).for_each(|i| { if i == 0 { gal_els.push(-1); } else { gal_els.push(module.galois_element(1 << (i - 1))); } }); gal_els } #[allow(clippy::too_many_arguments)] pub fn trace_scratch_space( module: &Module, n: usize, basek: usize, out_k: usize, in_k: usize, ksk_k: usize, digits: usize, rank: usize, ) -> usize where Module: VecZnxDftAllocBytes + VmpApplyTmpBytes + VecZnxBigNormalizeTmpBytes, { Self::automorphism_inplace_scratch_space(module, n, basek, out_k.min(in_k), ksk_k, digits, rank) } pub fn trace_inplace_scratch_space( module: &Module, n: usize, basek: usize, out_k: usize, ksk_k: usize, digits: usize, rank: usize, ) -> usize where Module: VecZnxDftAllocBytes + VmpApplyTmpBytes + VecZnxBigNormalizeTmpBytes, { Self::automorphism_inplace_scratch_space(module, n, basek, out_k, ksk_k, digits, rank) } } impl GLWECiphertext { pub fn trace( &mut self, module: &Module, start: usize, end: usize, lhs: &GLWECiphertext, auto_keys: &HashMap>, scratch: &mut Scratch, ) where Module: VecZnxDftAllocBytes + VmpApplyTmpBytes + VecZnxBigNormalizeTmpBytes + VmpApply + VmpApplyAdd + VecZnxDftFromVecZnx + VecZnxDftToVecZnxBigConsume + VecZnxBigAddSmallInplace + VecZnxBigNormalize + VecZnxBigAutomorphismInplace + VecZnxRshInplace + VecZnxCopy, Scratch: TakeVecZnxDft + ScratchAvailable, { self.copy(module, lhs); self.trace_inplace(module, start, end, auto_keys, scratch); } pub fn trace_inplace( &mut self, module: &Module, start: usize, end: usize, auto_keys: &HashMap>, scratch: &mut Scratch, ) where Module: VecZnxDftAllocBytes + VmpApplyTmpBytes + VecZnxBigNormalizeTmpBytes + VmpApply + VmpApplyAdd + VecZnxDftFromVecZnx + VecZnxDftToVecZnxBigConsume + VecZnxBigAddSmallInplace + VecZnxBigNormalize + VecZnxBigAutomorphismInplace + VecZnxRshInplace, Scratch: TakeVecZnxDft + ScratchAvailable, { (start..end).for_each(|i| { self.rsh(module, 1); let p: i64 = if i == 0 { -1 } else { module.galois_element(1 << (i - 1)) }; if let Some(key) = auto_keys.get(&p) { self.automorphism_add_inplace(module, key, scratch); } else { panic!("auto_keys[{}] is empty", p) } }); } }