arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/layouts/prepared/gglwe_ct.rs
poulpy-core/src/layouts/prepared/gglwe_ct.rsRaw
  1use poulpy_hal::{
  2    api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
  3    layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
  4};
  5
  6use crate::layouts::{
  7    GGLWECiphertext, Infos,
  8    prepared::{Prepare, PrepareAlloc},
  9};
 10
 11#[derive(PartialEq, Eq)]
 12pub struct GGLWECiphertextPrepared<D: Data, B: Backend> {
 13    pub(crate) data: VmpPMat<D, B>,
 14    pub(crate) basek: usize,
 15    pub(crate) k: usize,
 16    pub(crate) digits: usize,
 17}
 18
 19impl<B: Backend> GGLWECiphertextPrepared<Vec<u8>, B> {
 20    #[allow(clippy::too_many_arguments)]
 21    pub fn alloc(module: &Module<B>, basek: usize, k: usize, rows: usize, digits: usize, rank_in: usize, rank_out: usize) -> Self
 22    where
 23        Module<B>: VmpPMatAlloc<B>,
 24    {
 25        let size: usize = k.div_ceil(basek);
 26        debug_assert!(
 27            size > digits,
 28            "invalid gglwe: ceil(k/basek): {} <= digits: {}",
 29            size,
 30            digits
 31        );
 32
 33        assert!(
 34            rows * digits <= size,
 35            "invalid gglwe: rows: {} * digits:{} > ceil(k/basek): {}",
 36            rows,
 37            digits,
 38            size
 39        );
 40
 41        Self {
 42            data: module.vmp_pmat_alloc(rows, rank_in, rank_out + 1, size),
 43            basek,
 44            k,
 45            digits,
 46        }
 47    }
 48
 49    #[allow(clippy::too_many_arguments)]
 50    pub fn bytes_of(
 51        module: &Module<B>,
 52        basek: usize,
 53        k: usize,
 54        rows: usize,
 55        digits: usize,
 56        rank_in: usize,
 57        rank_out: usize,
 58    ) -> usize
 59    where
 60        Module<B>: VmpPMatAllocBytes,
 61    {
 62        let size: usize = k.div_ceil(basek);
 63        debug_assert!(
 64            size > digits,
 65            "invalid gglwe: ceil(k/basek): {} <= digits: {}",
 66            size,
 67            digits
 68        );
 69
 70        assert!(
 71            rows * digits <= size,
 72            "invalid gglwe: rows: {} * digits:{} > ceil(k/basek): {}",
 73            rows,
 74            digits,
 75            size
 76        );
 77
 78        module.vmp_pmat_alloc_bytes(rows, rank_in, rank_out + 1, rows)
 79    }
 80}
 81
 82impl<D: Data, B: Backend> Infos for GGLWECiphertextPrepared<D, B> {
 83    type Inner = VmpPMat<D, B>;
 84
 85    fn inner(&self) -> &Self::Inner {
 86        &self.data
 87    }
 88
 89    fn basek(&self) -> usize {
 90        self.basek
 91    }
 92
 93    fn k(&self) -> usize {
 94        self.k
 95    }
 96}
 97
 98impl<D: Data, B: Backend> GGLWECiphertextPrepared<D, B> {
 99    pub fn rank(&self) -> usize {
100        self.data.cols_out() - 1
101    }
102
103    pub fn digits(&self) -> usize {
104        self.digits
105    }
106
107    pub fn rank_in(&self) -> usize {
108        self.data.cols_in()
109    }
110
111    pub fn rank_out(&self) -> usize {
112        self.data.cols_out() - 1
113    }
114}
115
116impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWECiphertext<DR>> for GGLWECiphertextPrepared<D, B>
117where
118    Module<B>: VmpPrepare<B>,
119{
120    fn prepare(&mut self, module: &Module<B>, other: &GGLWECiphertext<DR>, scratch: &mut Scratch<B>) {
121        module.vmp_prepare(&mut self.data, &other.data, scratch);
122        self.basek = other.basek;
123        self.k = other.k;
124        self.digits = other.digits;
125    }
126}
127
128impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWECiphertextPrepared<Vec<u8>, B>> for GGLWECiphertext<D>
129where
130    Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
131{
132    fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWECiphertextPrepared<Vec<u8>, B> {
133        let mut atk_prepared: GGLWECiphertextPrepared<Vec<u8>, B> = GGLWECiphertextPrepared::alloc(
134            module,
135            self.basek(),
136            self.k(),
137            self.rows(),
138            self.digits(),
139            self.rank_in(),
140            self.rank_out(),
141        );
142        atk_prepared.prepare(module, self, scratch);
143        atk_prepared
144    }
145}