arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/base2k/src/svp.rs
base2k/src/svp.rsRaw
 1use crate::ffi::svp::{delete_svp_ppol, new_svp_ppol, svp_apply_dft, svp_ppol_t, svp_prepare};
 2use crate::scalar::Scalar;
 3use crate::{Free, Module, VecZnx, VecZnxDft};
 4
 5pub struct SvpPPol(pub *mut svp_ppol_t, pub usize);
 6
 7/// A prepared [crate::Scalar] for [ScalarVectorProduct::svp_apply_dft].
 8/// An [SvpPPol] an be seen as a [VecZnxDft] of one limb.
 9/// The backend array of an [SvpPPol] is allocated in C and must be freed manually.
10impl SvpPPol {
11    /// Returns the ring degree of the [SvpPPol].
12    pub fn n(&self) -> usize {
13        self.1
14    }
15
16    /// Returns the number of limbs of the [SvpPPol], which is always 1.
17    pub fn limbs(&self) -> usize {
18        1
19    }
20}
21
22impl Free for SvpPPol {
23    fn free(self) {
24        unsafe { delete_svp_ppol(self.0) };
25        let _ = drop(self);
26    }
27}
28
29pub trait ScalarVectorProduct {
30    /// Prepares a [crate::Scalar] for a [ScalarVectorProduct::svp_apply_dft].
31    fn svp_prepare(&self, svp_ppol: &mut SvpPPol, a: &Scalar);
32
33    /// Allocates a new [SvpPPol].
34    fn svp_new_ppol(&self) -> SvpPPol;
35
36    /// Applies the [SvpPPol] x [VecZnxDft] product, where each limb of
37    /// the [VecZnxDft] is multiplied with [SvpPPol].
38    fn svp_apply_dft(&self, c: &mut VecZnxDft, a: &SvpPPol, b: &VecZnx);
39}
40
41impl Module {
42    pub fn svp_prepare(&self, svp_ppol: &mut SvpPPol, a: &Scalar) {
43        unsafe { svp_prepare(self.0, svp_ppol.0, a.as_ptr()) }
44    }
45
46    pub fn svp_new_ppol(&self) -> SvpPPol {
47        unsafe { SvpPPol(new_svp_ppol(self.0), self.n()) }
48    }
49
50    pub fn svp_apply_dft(&self, c: &mut VecZnxDft, a: &SvpPPol, b: &VecZnx) {
51        let limbs: u64 = b.limbs() as u64;
52        assert!(
53            c.limbs() as u64 >= limbs,
54            "invalid c_vector: c_vector.limbs()={} < b.limbs()={}",
55            c.limbs(),
56            limbs
57        );
58        unsafe { svp_apply_dft(self.0, c.0, limbs, a.0, b.as_ptr(), limbs, b.n() as u64) }
59    }
60}