Skip to main content

poulpy_ckks/default/
pow2.rs

1use anyhow::Result;
2use poulpy_core::layouts::GLWEToBackendMut;
3use poulpy_core::{
4    GLWECopy, GLWEShift,
5    layouts::{GLWEInfos, LWEInfos},
6};
7use poulpy_hal::layouts::{Backend, ScratchArena};
8
9use crate::GLWEToBackendRef;
10
11use crate::{CKKSInfos, SetCKKSInfos, checked_log_budget_sub, ckks_offset_unary};
12
13pub trait CKKSPow2Default<BE: Backend> {
14    fn ckks_mul_pow2_tmp_bytes_default(&self) -> usize
15    where
16        Self: GLWEShift<BE>,
17    {
18        self.glwe_shift_tmp_bytes()
19    }
20
21    fn ckks_div_pow2_tmp_bytes_default(&self) -> usize
22    where
23        Self: GLWEShift<BE>,
24    {
25        self.glwe_shift_tmp_bytes()
26    }
27
28    fn ckks_mul_pow2_into_default<Dst, Src>(
29        &self,
30        dst: &mut Dst,
31        src: &Src,
32        bits: usize,
33        scratch: &mut ScratchArena<'_, BE>,
34    ) -> Result<()>
35    where
36        Self: GLWEShift<BE>,
37        Dst: GLWEToBackendMut<BE> + LWEInfos + CKKSInfos + SetCKKSInfos,
38        Src: GLWEToBackendRef<BE> + GLWEInfos + LWEInfos + CKKSInfos,
39    {
40        let offset = ckks_offset_unary(dst, src);
41        self.glwe_lsh(dst, src, bits + offset, scratch);
42        dst.set_meta(src.meta());
43        dst.set_log_budget(checked_log_budget_sub("mul_pow2", dst.log_budget(), offset)?);
44        Ok(())
45    }
46
47    fn ckks_mul_pow2_assign_default<Dst>(&self, dst: &mut Dst, bits: usize, scratch: &mut ScratchArena<'_, BE>) -> Result<()>
48    where
49        Self: GLWEShift<BE>,
50        Dst: GLWEToBackendMut<BE> + LWEInfos + CKKSInfos + SetCKKSInfos,
51    {
52        self.glwe_lsh_assign(dst, bits, scratch);
53        Ok(())
54    }
55
56    fn ckks_div_pow2_into_default<Dst, Src>(
57        &self,
58        dst: &mut Dst,
59        src: &Src,
60        bits: usize,
61        scratch: &mut ScratchArena<'_, BE>,
62    ) -> Result<()>
63    where
64        Self: GLWEShift<BE> + GLWECopy<BE>,
65        Dst: GLWEToBackendMut<BE> + LWEInfos + CKKSInfos + SetCKKSInfos,
66        Src: GLWEToBackendRef<BE> + GLWEInfos + LWEInfos + CKKSInfos,
67    {
68        let offset = ckks_offset_unary(dst, src);
69        self.glwe_lsh(dst, src, offset, scratch);
70        dst.set_meta(src.meta());
71        dst.set_log_budget(checked_log_budget_sub("div_pow2", dst.log_budget(), bits + offset)?);
72        dst.set_log_delta(dst.log_delta() + bits);
73        Ok(())
74    }
75
76    fn ckks_div_pow2_assign_default<Dst>(&self, dst: &mut Dst, bits: usize) -> Result<()>
77    where
78        Dst: GLWEToBackendMut<BE> + LWEInfos + CKKSInfos + SetCKKSInfos,
79    {
80        dst.set_log_budget(checked_log_budget_sub("div_pow2_assign", dst.log_budget(), bits)?);
81        Ok(())
82    }
83}