added vec_znx_split and vec_znx_merge

This commit is contained in:
Jean-Philippe Bossuat
2025-02-07 17:36:30 +01:00
parent 70b70513fb
commit 865c735a3c
2 changed files with 57 additions and 0 deletions

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"cmake.sourceDirectory": "C:/Users/boss_/go/src/github.com/gausslabs/fhe/base2k/spqlios-arithmetic"
}

View File

@@ -406,9 +406,28 @@ pub trait VecZnxOps {
/// a <- phi_k(a) where phi_k: X^i -> X^{i*k} (mod (X^{n} + 1)) /// a <- phi_k(a) where phi_k: X^i -> X^{i*k} (mod (X^{n} + 1))
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.
///
/// # Panics
///
/// This method requires that all [VecZnx] of b have the same ring degree
/// and that b.n() * b.len() <= a.n()
fn vec_znx_split(&self, b: &mut Vec<VecZnx>, a: &VecZnx, buf: &mut VecZnx);
/// Merges the subrings a into b.
///
/// # Panics
///
/// This method requires that all [VecZnx] of a have the same ring degree
/// and that a.n() * a.len() <= b.n()
fn vec_znx_merge(&self, b: &mut VecZnx, a: &Vec<VecZnx>);
} }
impl VecZnxOps for Module { impl VecZnxOps for Module {
fn new_vec_znx(&self, limbs: usize) -> VecZnx { fn new_vec_znx(&self, limbs: usize) -> VecZnx {
VecZnx::new(self.n(), limbs) VecZnx::new(self.n(), limbs)
} }
@@ -572,4 +591,39 @@ impl VecZnxOps for Module {
); );
} }
} }
fn vec_znx_split(&self, b: &mut Vec<VecZnx>, a: &VecZnx, buf: &mut VecZnx){
let (n_in, n_out) = (a.n(), b[0].n());
assert!(n_out < n_in, "invalid a: output ring degree should be smaller");
b[1..].iter().for_each(|bi|{
assert_eq!(bi.n(), n_out, "invalid input a: all VecZnx must have the same degree")
});
b.iter_mut().enumerate().for_each(|(i, bi)|{
if i == 0{
a.switch_degree(bi);
self.vec_znx_rotate(-1, buf, a);
}else{
buf.switch_degree(bi);
self.vec_znx_rotate_inplace(-1, buf);
}
})
}
fn vec_znx_merge(&self, b: &mut VecZnx, a: &Vec<VecZnx>){
let (n_in, n_out) = (b.n(), a[0].n());
assert!(n_out < n_in, "invalid a: output ring degree should be smaller");
a[1..].iter().for_each(|ai|{
assert_eq!(ai.n(), n_out, "invalid input a: all VecZnx must have the same degree")
});
a.iter().enumerate().for_each(|(i, ai)|{
ai.switch_degree(b);
self.vec_znx_rotate_inplace(-1, b);
});
self.vec_znx_rotate_inplace(a.len() as i64, b);
}
} }