added from_bytes for SvpPPol

This commit is contained in:
Jean-Philippe Bossuat
2025-02-10 16:01:30 +01:00
parent 83fa66f8f4
commit 0519510667
5 changed files with 53 additions and 25 deletions

View File

@@ -1,8 +1,7 @@
use base2k::{ use base2k::{
Encoding, Free, Infos, Matrix3D, Module, VecZnx, VecZnxBig, VecZnxDft, VecZnxOps, VmpPMat, Encoding, Free, Infos, Module, VecZnx, VecZnxBig, VecZnxDft, VecZnxOps, VmpPMat, VmpPMatOps,
VmpPMatOps, FFT64, FFT64,
}; };
use std::cmp::min;
fn main() { fn main() {
let log_n = 5; let log_n = 5;

View File

@@ -68,6 +68,10 @@ impl SvpPPol {
self.1 self.1
} }
pub fn from_bytes(size: usize, bytes: &mut [u8]) -> SvpPPol {
SvpPPol(bytes.as_mut_ptr() as *mut svp::svp_ppol_t, size)
}
/// Returns the number of limbs of the [SvpPPol], which is always 1. /// Returns the number of limbs of the [SvpPPol], which is always 1.
pub fn limbs(&self) -> usize { pub fn limbs(&self) -> usize {
1 1
@@ -75,26 +79,34 @@ impl SvpPPol {
} }
pub trait SvpPPolOps { pub trait SvpPPolOps {
/// Prepares a [crate::Scalar] for a [SvpPPolOps::svp_apply_dft].
fn svp_prepare(&self, svp_ppol: &mut SvpPPol, a: &Scalar);
/// Allocates a new [SvpPPol]. /// Allocates a new [SvpPPol].
fn svp_new_ppol(&self) -> SvpPPol; fn svp_new_ppol(&self) -> SvpPPol;
/// Returns the minimum number of bytes necessary to allocate
/// a new [SvpPPol] through [SvpPPol::from_bytes].
fn bytes_of_svp_ppol(&self) -> usize;
/// Prepares a [crate::Scalar] for a [SvpPPolOps::svp_apply_dft].
fn svp_prepare(&self, svp_ppol: &mut SvpPPol, a: &Scalar);
/// Applies the [SvpPPol] x [VecZnxDft] product, where each limb of /// Applies the [SvpPPol] x [VecZnxDft] product, where each limb of
/// the [VecZnxDft] is multiplied with [SvpPPol]. /// the [VecZnxDft] is multiplied with [SvpPPol].
fn svp_apply_dft(&self, c: &mut VecZnxDft, a: &SvpPPol, b: &VecZnx); fn svp_apply_dft(&self, c: &mut VecZnxDft, a: &SvpPPol, b: &VecZnx);
} }
impl SvpPPolOps for Module { impl SvpPPolOps for Module {
fn svp_prepare(&self, svp_ppol: &mut SvpPPol, a: &Scalar) {
unsafe { svp::svp_prepare(self.0, svp_ppol.0, a.as_ptr()) }
}
fn svp_new_ppol(&self) -> SvpPPol { fn svp_new_ppol(&self) -> SvpPPol {
unsafe { SvpPPol(svp::new_svp_ppol(self.0), self.n()) } unsafe { SvpPPol(svp::new_svp_ppol(self.0), self.n()) }
} }
fn bytes_of_svp_ppol(&self) -> usize {
unsafe { svp::bytes_of_svp_ppol(self.0) as usize }
}
fn svp_prepare(&self, svp_ppol: &mut SvpPPol, a: &Scalar) {
unsafe { svp::svp_prepare(self.0, svp_ppol.0, a.as_ptr()) }
}
fn svp_apply_dft(&self, c: &mut VecZnxDft, a: &SvpPPol, b: &VecZnx) { fn svp_apply_dft(&self, c: &mut VecZnxDft, a: &SvpPPol, b: &VecZnx) {
let limbs: u64 = b.limbs() as u64; let limbs: u64 = b.limbs() as u64;
assert!( assert!(

View File

@@ -21,19 +21,21 @@ impl VecZnx {
pub fn new(n: usize, limbs: usize) -> Self { pub fn new(n: usize, limbs: usize) -> Self {
Self { Self {
n: n, n: n,
data: vec![i64::default(); Self::buffer_size(n, limbs)], data: vec![i64::default(); n * limbs],
} }
} }
/// Returns the minimum size of the [i64] array required to assign a /// Returns the minimum size of the [u8] array required to assign a
/// new backend array to a [VecZnx] through [VecZnx::from_buffer]. /// new backend array to a [VecZnx] through [VecZnx::from_bytes].
pub fn buffer_size(n: usize, limbs: usize) -> usize { pub fn bytes(n: usize, limbs: usize) -> usize {
n * limbs n * limbs * 8
} }
/// Assigns a new backing array to a [VecZnx]. /// Returns a new [VecZnx] with the provided data as backing array.
pub fn from_buffer(&mut self, n: usize, limbs: usize, buf: &mut [i64]) { /// User must ensure that data is properly alligned and that
let size = Self::buffer_size(n, limbs); /// the size of data is at least equal to [Module::bytes_of_vec_znx].
pub fn from_bytes(n: usize, limbs: usize, buf: &mut [u8]) -> VecZnx {
let size = Self::bytes(n, limbs);
assert!( assert!(
buf.len() >= size, buf.len() >= size,
"invalid buffer: buf.len()={} < self.buffer_size(n={}, limbs={})={}", "invalid buffer: buf.len()={} < self.buffer_size(n={}, limbs={})={}",
@@ -42,8 +44,11 @@ impl VecZnx {
limbs, limbs,
size size
); );
self.n = n;
self.data = Vec::from(&buf[..size]) VecZnx {
n: n,
data: Vec::from(cast_mut_u8_to_mut_i64_slice(&mut buf[..size])),
}
} }
/// Copies the coefficients of `a` on the receiver. /// Copies the coefficients of `a` on the receiver.
@@ -377,6 +382,10 @@ pub trait VecZnxOps {
/// * `limbs`: the number of limbs. /// * `limbs`: the number of limbs.
fn new_vec_znx(&self, limbs: usize) -> VecZnx; fn new_vec_znx(&self, limbs: usize) -> VecZnx;
/// Returns the minimum number of bytes necessary to allocate
/// a new [VecZnx] through [VecZnx::from_bytes].
fn bytes_of_vec_znx(&self, limbs: usize) -> usize;
/// c <- a + b. /// c <- a + b.
fn vec_znx_add(&self, c: &mut VecZnx, a: &VecZnx, b: &VecZnx); fn vec_znx_add(&self, c: &mut VecZnx, a: &VecZnx, b: &VecZnx);
@@ -429,6 +438,10 @@ impl VecZnxOps for Module {
VecZnx::new(self.n(), limbs) VecZnx::new(self.n(), limbs)
} }
fn bytes_of_vec_znx(&self, limbs: usize) -> usize {
self.n() * limbs * 8
}
// c <- a + b // c <- a + b
fn vec_znx_add(&self, c: &mut VecZnx, a: &VecZnx, b: &VecZnx) { fn vec_znx_add(&self, c: &mut VecZnx, a: &VecZnx, b: &VecZnx) {
unsafe { unsafe {
@@ -630,7 +643,7 @@ impl VecZnxOps for Module {
) )
}); });
a.iter().enumerate().for_each(|(i, ai)| { a.iter().enumerate().for_each(|(_, ai)| {
ai.switch_degree(b); ai.switch_degree(b);
self.vec_znx_rotate_inplace(-1, b); self.vec_znx_rotate_inplace(-1, b);
}); });

View File

@@ -5,10 +5,10 @@ use crate::{Infos, Module, VecZnx, VecZnxDft};
pub struct VecZnxBig(pub *mut vec_znx_big::vec_znx_bigcoeff_t, pub usize); pub struct VecZnxBig(pub *mut vec_znx_big::vec_znx_bigcoeff_t, pub usize);
impl VecZnxBig { impl VecZnxBig {
/// Casts a contiguous array of [u8] into as a [VecZnxDft]. /// Returns a new [VecZnxBig] with the provided data as backing array.
/// User must ensure that data is properly alligned and that /// User must ensure that data is properly alligned and that
/// the size of data is at least equal to [Module::bytes_of_vec_znx_big]. /// the size of data is at least equal to [Module::bytes_of_vec_znx_big].
pub fn from_bytes(&self, limbs: usize, data: &mut [u8]) -> VecZnxBig { pub fn from_bytes(limbs: usize, data: &mut [u8]) -> VecZnxBig {
VecZnxBig( VecZnxBig(
data.as_mut_ptr() as *mut vec_znx_big::vec_znx_bigcoeff_t, data.as_mut_ptr() as *mut vec_znx_big::vec_znx_bigcoeff_t,
limbs, limbs,
@@ -29,6 +29,8 @@ impl Module {
unsafe { VecZnxBig(vec_znx_big::new_vec_znx_big(self.0, limbs as u64), limbs) } unsafe { VecZnxBig(vec_znx_big::new_vec_znx_big(self.0, limbs as u64), limbs) }
} }
/// Returns the minimum number of bytes necessary to allocate
/// a new [VecZnxBig] through [VecZnxBig::from_bytes].
pub fn bytes_of_vec_znx_big(&self, limbs: usize) -> usize { pub fn bytes_of_vec_znx_big(&self, limbs: usize) -> usize {
unsafe { vec_znx_big::bytes_of_vec_znx_big(self.0, limbs as u64) as usize } unsafe { vec_znx_big::bytes_of_vec_znx_big(self.0, limbs as u64) as usize }
} }

View File

@@ -6,10 +6,10 @@ use crate::{Module, VecZnxBig};
pub struct VecZnxDft(pub *mut vec_znx_dft::vec_znx_dft_t, pub usize); pub struct VecZnxDft(pub *mut vec_znx_dft::vec_znx_dft_t, pub usize);
impl VecZnxDft { impl VecZnxDft {
/// Casts a contiguous array of [u8] into as a [VecZnxDft]. /// Returns a new [VecZnxDft] with the provided data as backing array.
/// User must ensure that data is properly alligned and that /// User must ensure that data is properly alligned and that
/// the size of data is at least equal to [Module::bytes_of_vec_znx_dft]. /// the size of data is at least equal to [Module::bytes_of_vec_znx_dft].
pub fn from_bytes(&self, limbs: usize, data: &mut [u8]) -> VecZnxDft { pub fn from_bytes(limbs: usize, data: &mut [u8]) -> VecZnxDft {
VecZnxDft(data.as_mut_ptr() as *mut vec_znx_dft::vec_znx_dft_t, limbs) VecZnxDft(data.as_mut_ptr() as *mut vec_znx_dft::vec_znx_dft_t, limbs)
} }
@@ -30,6 +30,8 @@ impl Module {
unsafe { VecZnxDft(vec_znx_dft::new_vec_znx_dft(self.0, limbs as u64), limbs) } unsafe { VecZnxDft(vec_znx_dft::new_vec_znx_dft(self.0, limbs as u64), limbs) }
} }
/// Returns the minimum number of bytes necessary to allocate
/// a new [VecZnxDft] through [VecZnxDft::from_bytes].
pub fn bytes_of_vec_znx_dft(&self, limbs: usize) -> usize { pub fn bytes_of_vec_znx_dft(&self, limbs: usize) -> usize {
unsafe { bytes_of_vec_znx_dft(self.0, limbs as u64) as usize } unsafe { bytes_of_vec_znx_dft(self.0, limbs as u64) as usize }
} }