use std::collections::HashMap; use backend::hal::layouts::{Backend, DataMut, DataRef, Module, Scratch}; use crate::{ layouts::{GLWECiphertext, prepared::GGLWEAutomorphismKeyExec}, operations::GLWEOperations, }; use crate::trait_families::{GLWETraceModuleFamily, GLWETraceScratchFamily}; 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 } 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: GLWETraceModuleFamily, { 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: GLWETraceModuleFamily, { 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: GLWETraceModuleFamily, Scratch: GLWETraceScratchFamily, { 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: GLWETraceModuleFamily, Scratch: GLWETraceScratchFamily, { (start..end).for_each(|i| { self.rsh(module, 1); let p: i64; if i == 0 { p = -1; } else { p = 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) } }); } }