arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/gglwe/ciphertext.rs
core/src/gglwe/ciphertext.rsRaw
  1use backend::{Backend, FFT64, MatZnxDft, MatZnxDftAlloc, MatZnxDftOps, Module};
  2
  3use crate::{FourierGLWECiphertext, GetRow, Infos, SetRow, div_ceil};
  4
  5pub struct GGLWECiphertext<C, B: Backend> {
  6    pub(crate) data: MatZnxDft<C, B>,
  7    pub(crate) basek: usize,
  8    pub(crate) k: usize,
  9    pub(crate) digits: usize,
 10}
 11
 12impl<B: Backend> GGLWECiphertext<Vec<u8>, B> {
 13    pub fn alloc(
 14        module: &Module<B>,
 15        basek: usize,
 16        k: usize,
 17        rows: usize,
 18        digits: usize,
 19        rank_in: usize,
 20        rank_out: usize,
 21    ) -> Self {
 22        let size: usize = div_ceil(k, basek);
 23        debug_assert!(
 24            size > digits,
 25            "invalid gglwe: ceil(k/basek): {} <= digits: {}",
 26            size,
 27            digits
 28        );
 29
 30        assert!(
 31            rows * digits <= size,
 32            "invalid gglwe: rows: {} * digits:{} > ceil(k/basek): {}",
 33            rows,
 34            digits,
 35            size
 36        );
 37
 38        Self {
 39            data: module.new_mat_znx_dft(rows, rank_in, rank_out + 1, size),
 40            basek: basek,
 41            k,
 42            digits,
 43        }
 44    }
 45
 46    pub fn bytes_of(
 47        module: &Module<FFT64>,
 48        basek: usize,
 49        k: usize,
 50        rows: usize,
 51        digits: usize,
 52        rank_in: usize,
 53        rank_out: usize,
 54    ) -> usize {
 55        let size: usize = div_ceil(k, basek);
 56        debug_assert!(
 57            size > digits,
 58            "invalid gglwe: ceil(k/basek): {} <= digits: {}",
 59            size,
 60            digits
 61        );
 62
 63        assert!(
 64            rows * digits <= size,
 65            "invalid gglwe: rows: {} * digits:{} > ceil(k/basek): {}",
 66            rows,
 67            digits,
 68            size
 69        );
 70
 71        module.bytes_of_mat_znx_dft(rows, rank_in, rank_out + 1, rows)
 72    }
 73}
 74
 75impl<T, B: Backend> Infos for GGLWECiphertext<T, B> {
 76    type Inner = MatZnxDft<T, B>;
 77
 78    fn inner(&self) -> &Self::Inner {
 79        &self.data
 80    }
 81
 82    fn basek(&self) -> usize {
 83        self.basek
 84    }
 85
 86    fn k(&self) -> usize {
 87        self.k
 88    }
 89}
 90
 91impl<T, B: Backend> GGLWECiphertext<T, B> {
 92    pub fn rank(&self) -> usize {
 93        self.data.cols_out() - 1
 94    }
 95
 96    pub fn digits(&self) -> usize {
 97        self.digits
 98    }
 99
100    pub fn rank_in(&self) -> usize {
101        self.data.cols_in()
102    }
103
104    pub fn rank_out(&self) -> usize {
105        self.data.cols_out() - 1
106    }
107}
108
109impl<C: AsRef<[u8]>> GetRow<FFT64> for GGLWECiphertext<C, FFT64> {
110    fn get_row<R: AsMut<[u8]> + AsRef<[u8]>>(
111        &self,
112        module: &Module<FFT64>,
113        row_i: usize,
114        col_j: usize,
115        res: &mut FourierGLWECiphertext<R, FFT64>,
116    ) {
117        module.mat_znx_dft_get_row(&mut res.data, &self.data, row_i, col_j);
118    }
119}
120
121impl<C: AsMut<[u8]> + AsRef<[u8]>> SetRow<FFT64> for GGLWECiphertext<C, FFT64> {
122    fn set_row<R: AsRef<[u8]>>(
123        &mut self,
124        module: &Module<FFT64>,
125        row_i: usize,
126        col_j: usize,
127        a: &FourierGLWECiphertext<R, FFT64>,
128    ) {
129        module.mat_znx_dft_set_row(&mut self.data, row_i, col_j, &a.data);
130    }
131}