arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/glwe_trace.rs
core/src/glwe_trace.rsRaw
  1use std::collections::HashMap;
  2
  3use backend::hal::layouts::{Backend, DataMut, DataRef, Module, Scratch};
  4
  5use crate::{
  6    layouts::{GLWECiphertext, prepared::GGLWEAutomorphismKeyExec},
  7    operations::GLWEOperations,
  8};
  9
 10use crate::trait_families::{GLWETraceModuleFamily, GLWETraceScratchFamily};
 11
 12impl GLWECiphertext<Vec<u8>> {
 13    pub fn trace_galois_elements<B: Backend>(module: &Module<B>) -> Vec<i64> {
 14        let mut gal_els: Vec<i64> = Vec::new();
 15        (0..module.log_n()).for_each(|i| {
 16            if i == 0 {
 17                gal_els.push(-1);
 18            } else {
 19                gal_els.push(module.galois_element(1 << (i - 1)));
 20            }
 21        });
 22        gal_els
 23    }
 24
 25    pub fn trace_scratch_space<B: Backend>(
 26        module: &Module<B>,
 27        n: usize,
 28        basek: usize,
 29        out_k: usize,
 30        in_k: usize,
 31        ksk_k: usize,
 32        digits: usize,
 33        rank: usize,
 34    ) -> usize
 35    where
 36        Module<B>: GLWETraceModuleFamily<B>,
 37    {
 38        Self::automorphism_inplace_scratch_space(module, n, basek, out_k.min(in_k), ksk_k, digits, rank)
 39    }
 40
 41    pub fn trace_inplace_scratch_space<B: Backend>(
 42        module: &Module<B>,
 43        n: usize,
 44        basek: usize,
 45        out_k: usize,
 46        ksk_k: usize,
 47        digits: usize,
 48        rank: usize,
 49    ) -> usize
 50    where
 51        Module<B>: GLWETraceModuleFamily<B>,
 52    {
 53        Self::automorphism_inplace_scratch_space(module, n, basek, out_k, ksk_k, digits, rank)
 54    }
 55}
 56
 57impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
 58    pub fn trace<DataLhs: DataRef, DataAK: DataRef, B: Backend>(
 59        &mut self,
 60        module: &Module<B>,
 61        start: usize,
 62        end: usize,
 63        lhs: &GLWECiphertext<DataLhs>,
 64        auto_keys: &HashMap<i64, GGLWEAutomorphismKeyExec<DataAK, B>>,
 65        scratch: &mut Scratch<B>,
 66    ) where
 67        Module<B>: GLWETraceModuleFamily<B>,
 68        Scratch<B>: GLWETraceScratchFamily<B>,
 69    {
 70        self.copy(module, lhs);
 71        self.trace_inplace(module, start, end, auto_keys, scratch);
 72    }
 73
 74    pub fn trace_inplace<DataAK: DataRef, B: Backend>(
 75        &mut self,
 76        module: &Module<B>,
 77        start: usize,
 78        end: usize,
 79        auto_keys: &HashMap<i64, GGLWEAutomorphismKeyExec<DataAK, B>>,
 80        scratch: &mut Scratch<B>,
 81    ) where
 82        Module<B>: GLWETraceModuleFamily<B>,
 83        Scratch<B>: GLWETraceScratchFamily<B>,
 84    {
 85        (start..end).for_each(|i| {
 86            self.rsh(module, 1);
 87
 88            let p: i64;
 89            if i == 0 {
 90                p = -1;
 91            } else {
 92                p = module.galois_element(1 << (i - 1));
 93            }
 94
 95            if let Some(key) = auto_keys.get(&p) {
 96                self.automorphism_add_inplace(module, key, scratch);
 97            } else {
 98                panic!("auto_keys[{}] is empty", p)
 99            }
100        });
101    }
102}