Updated vec_znx_ops doc

This commit is contained in:
Jean-Philippe Bossuat
2025-04-29 12:46:25 +02:00
parent 2f9a1cf6d9
commit 48cfc0027b

View File

@@ -8,49 +8,72 @@ pub trait VecZnxOps {
/// # Arguments /// # Arguments
/// ///
/// * `cols`: the number of polynomials. /// * `cols`: the number of polynomials.
/// * `size`: the number of size per polynomial (a.k.a small polynomials). /// * `size`: the number small polynomials per column.
fn new_vec_znx(&self, cols: usize, size: usize) -> VecZnx; fn new_vec_znx(&self, cols: usize, size: usize) -> VecZnx;
/// Instantiates a new [VecZnx] from a slice of bytes.
/// The returned [VecZnx] takes ownership of the slice of bytes.
///
/// # Arguments
///
/// * `cols`: the number of polynomials.
/// * `size`: the number small polynomials per column.
///
/// # Panic
/// Requires the slice of bytes to be equal to [VecZnxOps::bytes_of_vec_znx].
fn new_vec_znx_from_bytes(&self, cols: usize, size: usize, bytes: &mut [u8]) -> VecZnx; fn new_vec_znx_from_bytes(&self, cols: usize, size: usize, bytes: &mut [u8]) -> VecZnx;
/// Instantiates a new [VecZnx] from a slice of bytes.
/// The returned [VecZnx] does take ownership of the slice of bytes.
///
/// # Arguments
///
/// * `cols`: the number of polynomials.
/// * `size`: the number small polynomials per column.
///
/// # Panic
/// Requires the slice of bytes to be equal to [VecZnxOps::bytes_of_vec_znx].
fn new_vec_znx_from_bytes_borrow(&self, cols: usize, size: usize, tmp_bytes: &mut [u8]) -> VecZnx; fn new_vec_znx_from_bytes_borrow(&self, cols: usize, size: usize, tmp_bytes: &mut [u8]) -> VecZnx;
/// Returns the minimum number of bytes necessary to allocate /// Returns the number of bytes necessary to allocate
/// a new [VecZnx] through [VecZnx::from_bytes]. /// a new [VecZnx] through [VecZnxOps::new_vec_znx_from_bytes]
/// or [VecZnxOps::new_vec_znx_from_bytes_borrow].
fn bytes_of_vec_znx(&self, cols: usize, size: usize) -> usize; fn bytes_of_vec_znx(&self, cols: usize, size: usize) -> usize;
/// Returns the minimum number of bytes necessary for normalization.
fn vec_znx_normalize_tmp_bytes(&self, cols: usize) -> usize; fn vec_znx_normalize_tmp_bytes(&self, cols: usize) -> usize;
/// c <- a + b. /// Adds `a` to `b` and write the result on `c`.
fn vec_znx_add(&self, c: &mut VecZnx, a: &VecZnx, b: &VecZnx); fn vec_znx_add(&self, c: &mut VecZnx, a: &VecZnx, b: &VecZnx);
/// b <- b + a. /// Adds `a` to `b` and write the result on `b`.
fn vec_znx_add_inplace(&self, b: &mut VecZnx, a: &VecZnx); fn vec_znx_add_inplace(&self, b: &mut VecZnx, a: &VecZnx);
/// c <- a - b. /// Subtracts `b` to `a` and write the result on `c`.
fn vec_znx_sub(&self, c: &mut VecZnx, a: &VecZnx, b: &VecZnx); fn vec_znx_sub(&self, c: &mut VecZnx, a: &VecZnx, b: &VecZnx);
/// b <- a - b. /// Subtracts `a` to `b` and write the result on `b`.
fn vec_znx_sub_ab_inplace(&self, b: &mut VecZnx, a: &VecZnx); fn vec_znx_sub_ab_inplace(&self, b: &mut VecZnx, a: &VecZnx);
/// b <- b - a. /// Subtracts `b` to `a` and write the result on `b`.
fn vec_znx_sub_ba_inplace(&self, b: &mut VecZnx, a: &VecZnx); fn vec_znx_sub_ba_inplace(&self, b: &mut VecZnx, a: &VecZnx);
/// b <- -a. // Negates `a` and stores the result on `b`.
fn vec_znx_negate(&self, b: &mut VecZnx, a: &VecZnx); fn vec_znx_negate(&self, b: &mut VecZnx, a: &VecZnx);
/// b <- -b. /// Negages `a` and stores the result on `a`.
fn vec_znx_negate_inplace(&self, a: &mut VecZnx); fn vec_znx_negate_inplace(&self, a: &mut VecZnx);
/// b <- a * X^k (mod X^{n} + 1) /// Multiplies `a` by X^k and stores the result on `b`.
fn vec_znx_rotate(&self, k: i64, b: &mut VecZnx, a: &VecZnx); fn vec_znx_rotate(&self, k: i64, b: &mut VecZnx, a: &VecZnx);
/// a <- a * X^k (mod X^{n} + 1) /// Multiplies `a` by X^k and stores the result on `a`.
fn vec_znx_rotate_inplace(&self, k: i64, a: &mut VecZnx); fn vec_znx_rotate_inplace(&self, k: i64, a: &mut VecZnx);
/// b <- phi_k(a) where phi_k: X^i -> X^{i*k} (mod (X^{n} + 1)) /// Applies the automorphism X^i -> X^ik on `a` and stores the result on `b`.
fn vec_znx_automorphism(&self, k: i64, b: &mut VecZnx, a: &VecZnx); fn vec_znx_automorphism(&self, k: i64, b: &mut VecZnx, a: &VecZnx);
/// a <- phi_k(a) where phi_k: X^i -> X^{i*k} (mod (X^{n} + 1)) /// Applies the automorphism X^i -> X^ik on `a` and stores the result on `a`.
fn vec_znx_automorphism_inplace(&self, k: i64, a: &mut VecZnx); fn vec_znx_automorphism_inplace(&self, k: i64, a: &mut VecZnx);
/// Splits b into subrings and copies them them into a. /// Splits b into subrings and copies them them into a.
@@ -179,18 +202,6 @@ impl<B: Backend> VecZnxOps for Module<B> {
} }
} }
/// Maps X^i to X^{ik} mod X^{n}+1. The mapping is applied independently on each size.
///
/// # Arguments
///
/// * `a`: input.
/// * `b`: output.
/// * `k`: the power to which to map each coefficients.
/// * `a_size`: the number of a_size on which to apply the mapping.
///
/// # Panics
///
/// The method will panic if the argument `a` is greater than `a.size()`.
fn vec_znx_automorphism(&self, k: i64, b: &mut VecZnx, a: &VecZnx) { fn vec_znx_automorphism(&self, k: i64, b: &mut VecZnx, a: &VecZnx) {
let op = ffi_binary_op_factory_type_1( let op = ffi_binary_op_factory_type_1(
self.ptr, self.ptr,
@@ -204,17 +215,6 @@ impl<B: Backend> VecZnxOps for Module<B> {
vec_znx_apply_unary_op::<B>(self, b, a, op); vec_znx_apply_unary_op::<B>(self, b, a, op);
} }
/// Maps X^i to X^{ik} mod X^{n}+1. The mapping is applied independently on each size.
///
/// # Arguments
///
/// * `a`: input and output.
/// * `k`: the power to which to map each coefficients.
/// * `a_size`: the number of size on which to apply the mapping.
///
/// # Panics
///
/// The method will panic if the argument `size` is greater than `self.size()`.
fn vec_znx_automorphism_inplace(&self, k: i64, a: &mut VecZnx) { fn vec_znx_automorphism_inplace(&self, k: i64, a: &mut VecZnx) {
unsafe { unsafe {
let a_ptr: *mut VecZnx = a as *mut VecZnx; let a_ptr: *mut VecZnx = a as *mut VecZnx;
@@ -357,14 +357,11 @@ pub fn vec_znx_apply_binary_op<B: Backend, const NEGATE: bool>(
assert_eq!(c.n(), module.n()); assert_eq!(c.n(), module.n());
assert_ne!(a.as_ptr(), b.as_ptr()); assert_ne!(a.as_ptr(), b.as_ptr());
} }
let a_cols: usize = a.cols(); let a_cols: usize = a.cols();
let b_cols: usize = b.cols(); let b_cols: usize = b.cols();
let c_cols: usize = c.cols(); let c_cols: usize = c.cols();
let min_ab_cols: usize = min(a_cols, b_cols); let min_ab_cols: usize = min(a_cols, b_cols);
let min_cols: usize = min(c_cols, min_ab_cols); let min_cols: usize = min(c_cols, min_ab_cols);
// Applies over shared cols between (a, b, c) // Applies over shared cols between (a, b, c)
(0..min_cols).for_each(|i| op(c.at_poly_mut(i, 0), a.at_poly(i, 0), b.at_poly(i, 0))); (0..min_cols).for_each(|i| op(c.at_poly_mut(i, 0), a.at_poly(i, 0), b.at_poly(i, 0)));
// Copies/Negates/Zeroes the remaining cols if op is not inplace. // Copies/Negates/Zeroes the remaining cols if op is not inplace.
@@ -620,25 +617,30 @@ mod tests {
let min_cols: usize = min(*c_cols, min_ab_cols); let min_cols: usize = min(*c_cols, min_ab_cols);
let min_size: usize = min(c_size, min(a_size, b_size)); let min_size: usize = min(c_size, min(a_size, b_size));
// Allocats a and populates with random values.
let mut a: VecZnx = module.new_vec_znx(*a_cols, a_size); let mut a: VecZnx = module.new_vec_znx(*a_cols, a_size);
(0..*a_cols).for_each(|i| { (0..*a_cols).for_each(|i| {
module.fill_uniform(3, &mut a, i, a_size, &mut source); module.fill_uniform(3, &mut a, i, a_size, &mut source);
}); });
// Allocats b and populates with random values.
let mut b: VecZnx = module.new_vec_znx(*b_cols, b_size); let mut b: VecZnx = module.new_vec_znx(*b_cols, b_size);
(0..*b_cols).for_each(|i| { (0..*b_cols).for_each(|i| {
module.fill_uniform(3, &mut b, i, b_size, &mut source); module.fill_uniform(3, &mut b, i, b_size, &mut source);
}); });
// Allocats c and populates with random values.
let mut c_have: VecZnx = module.new_vec_znx(*c_cols, c_size); let mut c_have: VecZnx = module.new_vec_znx(*c_cols, c_size);
(0..c_have.cols()).for_each(|i| { (0..c_have.cols()).for_each(|i| {
module.fill_uniform(3, &mut c_have, i, c_size, &mut source); module.fill_uniform(3, &mut c_have, i, c_size, &mut source);
}); });
// Applies the function to test
func_have(&mut c_have, &a, &b); func_have(&mut c_have, &a, &b);
let mut c_want: VecZnx = module.new_vec_znx(*c_cols, c_size); let mut c_want: VecZnx = module.new_vec_znx(*c_cols, c_size);
// Applies the reference function and expected behavior.
// Adds with the minimum matching columns // Adds with the minimum matching columns
(0..min_cols).for_each(|i| { (0..min_cols).for_each(|i| {
// Adds with th eminimum matching size // Adds with th eminimum matching size
@@ -687,11 +689,13 @@ mod tests {
let min_cols: usize = min(*b_cols, *a_cols); let min_cols: usize = min(*b_cols, *a_cols);
let min_size: usize = min(b_size, a_size); let min_size: usize = min(b_size, a_size);
// Allocats a and populates with random values.
let mut a: VecZnx = module.new_vec_znx(*a_cols, a_size); let mut a: VecZnx = module.new_vec_znx(*a_cols, a_size);
(0..*a_cols).for_each(|i| { (0..*a_cols).for_each(|i| {
module.fill_uniform(3, &mut a, i, a_size, &mut source); module.fill_uniform(3, &mut a, i, a_size, &mut source);
}); });
// Allocats b and populates with random values.
let mut b_have: VecZnx = module.new_vec_znx(*b_cols, b_size); let mut b_have: VecZnx = module.new_vec_znx(*b_cols, b_size);
(0..*b_cols).for_each(|i| { (0..*b_cols).for_each(|i| {
module.fill_uniform(3, &mut b_have, i, b_size, &mut source); module.fill_uniform(3, &mut b_have, i, b_size, &mut source);
@@ -700,8 +704,10 @@ mod tests {
let mut b_want: VecZnx = module.new_vec_znx(*b_cols, b_size); let mut b_want: VecZnx = module.new_vec_znx(*b_cols, b_size);
b_want.raw_mut().copy_from_slice(b_have.raw()); b_want.raw_mut().copy_from_slice(b_have.raw());
// Applies the function to test.
func_have(&mut b_have, &a); func_have(&mut b_have, &a);
// Applies the reference function and expected behavior.
// Applies with the minimum matching columns // Applies with the minimum matching columns
(0..min_cols).for_each(|i| { (0..min_cols).for_each(|i| {
// Adds with th eminimum matching size // Adds with th eminimum matching size
@@ -732,11 +738,13 @@ mod tests {
let min_cols: usize = min(*b_cols, *a_cols); let min_cols: usize = min(*b_cols, *a_cols);
let min_size: usize = min(b_size, a_size); let min_size: usize = min(b_size, a_size);
// Allocats a and populates with random values.
let mut a: VecZnx = module.new_vec_znx(*a_cols, a_size); let mut a: VecZnx = module.new_vec_znx(*a_cols, a_size);
(0..a.cols()).for_each(|i| { (0..a.cols()).for_each(|i| {
module.fill_uniform(3, &mut a, i, a_size, &mut source); module.fill_uniform(3, &mut a, i, a_size, &mut source);
}); });
// Allocats b and populates with random values.
let mut b_have: VecZnx = module.new_vec_znx(*b_cols, b_size); let mut b_have: VecZnx = module.new_vec_znx(*b_cols, b_size);
(0..b_have.cols()).for_each(|i| { (0..b_have.cols()).for_each(|i| {
module.fill_uniform(3, &mut b_have, i, b_size, &mut source); module.fill_uniform(3, &mut b_have, i, b_size, &mut source);
@@ -744,8 +752,10 @@ mod tests {
let mut b_want: VecZnx = module.new_vec_znx(*b_cols, b_size); let mut b_want: VecZnx = module.new_vec_znx(*b_cols, b_size);
// Applies the function to test.
func_have(&mut b_have, &a); func_have(&mut b_have, &a);
// Applies the reference function and expected behavior.
// Applies on the minimum matching columns // Applies on the minimum matching columns
(0..min_cols).for_each(|i| { (0..min_cols).for_each(|i| {
// Applies on the minimum matching size // Applies on the minimum matching size
@@ -778,11 +788,14 @@ mod tests {
module.fill_uniform(3, &mut a_have, i, a_size, &mut source); module.fill_uniform(3, &mut a_have, i, a_size, &mut source);
}); });
// Allocats a and populates with random values.
let mut a_want: VecZnx = module.new_vec_znx(*a_cols, a_size); let mut a_want: VecZnx = module.new_vec_znx(*a_cols, a_size);
a_have.raw_mut().copy_from_slice(a_want.raw()); a_have.raw_mut().copy_from_slice(a_want.raw());
// Applies the function to test.
func_have(&mut a_have); func_have(&mut a_have);
// Applies the reference function and expected behavior.
// Applies on the minimum matching columns // Applies on the minimum matching columns
(0..*a_cols).for_each(|i| { (0..*a_cols).for_each(|i| {
// Applies on the minimum matching size // Applies on the minimum matching size