use rand_distr::Distribution; use crate::{ layouts::{Backend, ScalarZnxToRef, Scratch, VecZnxToMut, VecZnxToRef}, source::Source, }; pub trait VecZnxNormalizeTmpBytes { /// Returns the minimum number of bytes necessary for normalization. fn vec_znx_normalize_tmp_bytes(&self, n: usize) -> usize; } pub trait VecZnxNormalize { /// Normalizes the selected column of `a` and stores the result into the selected column of `res`. fn vec_znx_normalize(&self, basek: usize, res: &mut R, res_col: usize, a: &A, a_col: usize, scratch: &mut Scratch) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxNormalizeInplace { /// Normalizes the selected column of `a`. fn vec_znx_normalize_inplace(&self, basek: usize, a: &mut A, a_col: usize, scratch: &mut Scratch) where A: VecZnxToMut; } pub trait VecZnxAdd { /// Adds the selected column of `a` to the selected column of `b` and writes the result on the selected column of `res`. fn vec_znx_add(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize) where R: VecZnxToMut, A: VecZnxToRef, B: VecZnxToRef; } pub trait VecZnxAddInplace { /// Adds the selected column of `a` to the selected column of `res` and writes the result on the selected column of `res`. fn vec_znx_add_inplace(&self, res: &mut R, res_col: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxAddScalarInplace { /// Adds the selected column of `a` on the selected column and limb of `res`. fn vec_znx_add_scalar_inplace(&self, res: &mut R, res_col: usize, res_limb: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: ScalarZnxToRef; } pub trait VecZnxSub { /// Subtracts the selected column of `b` from the selected column of `a` and writes the result on the selected column of `res`. fn vec_znx_sub(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize) where R: VecZnxToMut, A: VecZnxToRef, B: VecZnxToRef; } pub trait VecZnxSubABInplace { /// Subtracts the selected column of `a` from the selected column of `res` inplace. /// /// res\[res_col\] -= a\[a_col\] fn vec_znx_sub_ab_inplace(&self, res: &mut R, res_col: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxSubBAInplace { /// Subtracts the selected column of `res` from the selected column of `a` and inplace mutates `res` /// /// res\[res_col\] = a\[a_col\] - res\[res_col\] fn vec_znx_sub_ba_inplace(&self, res: &mut R, res_col: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxSubScalarInplace { /// Subtracts the selected column of `a` on the selected column and limb of `res`. fn vec_znx_sub_scalar_inplace(&self, res: &mut R, res_col: usize, res_limb: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: ScalarZnxToRef; } pub trait VecZnxNegate { // Negates the selected column of `a` and stores the result in `res_col` of `res`. fn vec_znx_negate(&self, res: &mut R, res_col: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxNegateInplace { /// Negates the selected column of `a`. fn vec_znx_negate_inplace(&self, a: &mut A, a_col: usize) where A: VecZnxToMut; } pub trait VecZnxLshInplace { /// Left shift by k bits all columns of `a`. fn vec_znx_lsh_inplace(&self, basek: usize, k: usize, a: &mut A) where A: VecZnxToMut; } pub trait VecZnxRshInplace { /// Right shift by k bits all columns of `a`. fn vec_znx_rsh_inplace(&self, basek: usize, k: usize, a: &mut A) where A: VecZnxToMut; } pub trait VecZnxRotate { /// Multiplies the selected column of `a` by X^k and stores the result in `res_col` of `res`. fn vec_znx_rotate(&self, k: i64, res: &mut R, res_col: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxRotateInplace { /// Multiplies the selected column of `a` by X^k. fn vec_znx_rotate_inplace(&self, k: i64, a: &mut A, a_col: usize) where A: VecZnxToMut; } pub trait VecZnxAutomorphism { /// Applies the automorphism X^i -> X^ik on the selected column of `a` and stores the result in `res_col` column of `res`. fn vec_znx_automorphism(&self, k: i64, res: &mut R, res_col: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxAutomorphismInplace { /// Applies the automorphism X^i -> X^ik on the selected column of `a`. fn vec_znx_automorphism_inplace(&self, k: i64, a: &mut A, a_col: usize) where A: VecZnxToMut; } pub trait VecZnxMulXpMinusOne { fn vec_znx_mul_xp_minus_one(&self, p: i64, r: &mut R, r_col: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxMulXpMinusOneInplace { fn vec_znx_mul_xp_minus_one_inplace(&self, p: i64, r: &mut R, r_col: usize) where R: VecZnxToMut; } pub trait VecZnxSplit { /// Splits the selected columns of `b` into subrings and copies them them into the selected column of `res`. /// /// # Panics /// /// This method requires that all [crate::layouts::VecZnx] of b have the same ring degree /// and that b.n() * b.len() <= a.n() fn vec_znx_split(&self, res: &mut [R], res_col: usize, a: &A, a_col: usize, scratch: &mut Scratch) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxMerge { /// Merges the subrings of the selected column of `a` into the selected column of `res`. /// /// # Panics /// /// This method requires that all [crate::layouts::VecZnx] of a have the same ring degree /// and that a.n() * a.len() <= b.n() fn vec_znx_merge(&self, res: &mut R, res_col: usize, a: &[A], a_col: usize) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxSwithcDegree { fn vec_znx_switch_degree(&self, res: &mut R, res_col: usize, a: &A, col_a: usize) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxCopy { fn vec_znx_copy(&self, res: &mut R, res_col: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: VecZnxToRef; } pub trait VecZnxFillUniform { /// Fills the first `size` size with uniform values in \[-2^{basek-1}, 2^{basek-1}\] fn vec_znx_fill_uniform(&self, basek: usize, res: &mut R, res_col: usize, k: usize, source: &mut Source) where R: VecZnxToMut; } #[allow(clippy::too_many_arguments)] pub trait VecZnxFillDistF64 { fn vec_znx_fill_dist_f64>( &self, basek: usize, res: &mut R, res_col: usize, k: usize, source: &mut Source, dist: D, bound: f64, ) where R: VecZnxToMut; } #[allow(clippy::too_many_arguments)] pub trait VecZnxAddDistF64 { /// Adds vector sampled according to the provided distribution, scaled by 2^{-k} and bounded to \[-bound, bound\]. fn vec_znx_add_dist_f64>( &self, basek: usize, res: &mut R, res_col: usize, k: usize, source: &mut Source, dist: D, bound: f64, ) where R: VecZnxToMut; } #[allow(clippy::too_many_arguments)] pub trait VecZnxFillNormal { fn vec_znx_fill_normal( &self, basek: usize, res: &mut R, res_col: usize, k: usize, source: &mut Source, sigma: f64, bound: f64, ) where R: VecZnxToMut; } #[allow(clippy::too_many_arguments)] pub trait VecZnxAddNormal { /// Adds a discrete normal vector scaled by 2^{-k} with the provided standard deviation and bounded to \[-bound, bound\]. fn vec_znx_add_normal( &self, basek: usize, res: &mut R, res_col: usize, k: usize, source: &mut Source, sigma: f64, bound: f64, ) where R: VecZnxToMut; }