arnaucube
arnaucube/poulpyPublic Self-hosted repository
VecZnx: added ring degree switching
Jean-Philippe Bossuat jeanphilippe.bossuat@gmail.com
Fri, 31 Jan 2025 12:01:28 +0100
commit

7704e14d45da2cab4c33e77df5a36ca17203aae6

parent

e10de441c624db3b19dcbdea7f9ab992a7710b1d

M base2k/build.rs → base2k/build.rs

@@ -1,55 +1,6 @@

-//use bindgen; -//use std::env; -//use std::fs; use std::path::absolute; -//use std::path::PathBuf; -//use std::time::SystemTime; fn main() { - /* - - [build-dependencies] - bindgen ="0.71.1" - - // Path to the C header file - let header_paths: [&str; 2] = [ - "spqlios-arithmetic/spqlios/coeffs/coeffs_arithmetic.h", - "spqlios-arithmetic/spqlios/arithmetic/vec_znx_arithmetic.h", - ]; - - let out_path: PathBuf = PathBuf::from(env::var("OUT_DIR").unwrap()); - let bindings_file = out_path.join("bindings.rs"); - - let regenerate: bool = header_paths.iter().any(|header| { - let header_metadata: SystemTime = fs::metadata(header) - .and_then(|m| m.modified()) - .unwrap_or(SystemTime::UNIX_EPOCH); - let bindings_metadata: SystemTime = fs::metadata(&bindings_file) - .and_then(|m| m.modified()) - .unwrap_or(SystemTime::UNIX_EPOCH); - header_metadata > bindings_metadata - }); - - if regenerate { - // Generate the Rust bindings - let mut builder: bindgen::Builder = bindgen::Builder::default(); - for header in header_paths { - builder = builder.header(header); - } - - let bindings = builder - .generate_comments(false) // Optional: includes comments in bindings - .generate_inline_functions(true) // Optional: includes inline functions - .generate() - .expect("Unable to generate bindings"); - - // Write the bindings to the OUT_DIR - bindings - .write_to_file(&bindings_file) - .expect("Couldn't write bindings!"); - } - */ - println!( "cargo:rustc-link-search=native={}", absolute("./spqlios-arithmetic/build/spqlios")
A base2k/src/bindgen.rs

@@ -0,0 +1,36 @@

+/* +[build-dependencies] +bindgen ="0.71.1" + +//use bindgen; +//use std::env; +//use std::fs; +//use std::path::PathBuf; +//use std::time::SystemTime; + +// Path to the C header file +let header_paths: [&str; 2] = [ + "spqlios-arithmetic/spqlios/coeffs/coeffs_arithmetic.h", + "spqlios-arithmetic/spqlios/arithmetic/vec_znx_arithmetic.h", +]; + +let out_path: PathBuf = PathBuf::from(env::var("OUT_DIR").unwrap()); +let bindings_file = out_path.join("bindings.rs"); + +let mut builder: bindgen::Builder = bindgen::Builder::default(); +for header in header_paths { + builder = builder.header(header); +} + +let bindings = builder + .generate_comments(false) // Optional: includes comments in bindings + .generate_inline_functions(true) // Optional: includes inline functions + .generate() + .expect("Unable to generate bindings"); + +// Write the bindings to the OUT_DIR +bindings + .write_to_file(&bindings_file) + .expect("Couldn't write bindings!"); + +*/
M base2k/src/scalar.rs → base2k/src/scalar.rs

@@ -1,9 +1,16 @@

+use crate::Module; use rand::seq::SliceRandom; use rand_core::RngCore; use rand_distr::{Distribution, WeightedIndex}; use sampling::source::Source; pub struct Scalar(pub Vec<i64>); + +impl Module { + pub fn new_scalar(&self) -> Scalar { + Scalar::new(self.n()) + } +} impl Scalar { pub fn new(n: usize) -> Self {
M base2k/src/scalar_vector_product.rs → base2k/src/scalar_vector_product.rs

@@ -2,9 +2,13 @@ use crate::ffi::svp::{delete_svp_ppol, new_svp_ppol, svp_apply_dft, svp_ppol_t, svp_prepare};

use crate::scalar::Scalar; use crate::{Module, VecZnx, VecZnxDft}; -pub struct SvpPPol(pub *mut svp_ppol_t); +pub struct SvpPPol(pub *mut svp_ppol_t, pub usize); impl SvpPPol { + pub fn n(&self) -> usize { + self.1 + } + pub fn delete(self) { unsafe { delete_svp_ppol(self.0) }; let _ = drop(self);

@@ -20,7 +24,7 @@ }

// Allocates a scalar-vector-product prepared-poly (VecZnxBig). pub fn svp_new_ppol(&self) -> SvpPPol { - unsafe { SvpPPol(new_svp_ppol(self.0)) } + unsafe { SvpPPol(new_svp_ppol(self.0), self.n()) } } // Applies a scalar x vector product: res <- a (ppol) x b
M base2k/src/vec_znx.rs → base2k/src/vec_znx.rs

@@ -98,6 +98,10 @@ pub fn at_mut(&mut self, i: usize) -> &mut [i64] {

&mut self.data[i * self.n..(i + 1) * self.n] } + pub fn zero(&mut self) { + unsafe { znx_zero_i64_ref(self.data.len() as u64, self.data.as_mut_ptr()) } + } + pub fn from_i64(&mut self, data: &[i64], log_max: usize) { let size: usize = min(data.len(), self.n()); let k_rem: usize = self.log_base2k - (self.log_q % self.log_base2k);

@@ -361,6 +365,28 @@ *xi /= 1 << k_rem;

}); }) } + } + + pub fn switch_degree(&self, a: &mut VecZnx) { + let (n_in, n_out) = (self.n(), a.n()); + let (gap_in, gap_out): (usize, usize); + + if n_in > n_out { + (gap_in, gap_out) = (n_in / n_out, 1) + } else { + (gap_in, gap_out) = (1, n_out / n_in); + a.zero(); + } + + let limbs = min(self.limbs(), a.limbs()); + + (0..limbs).for_each(|i| { + izip!( + self.at(i).iter().step_by(gap_in), + a.at_mut(i).iter_mut().step_by(gap_out) + ) + .for_each(|(x_in, x_out)| *x_out = *x_in); + }); } }