Add GGSW blind rotation
Pro7ech jeanphilippe.bossuat@gmail.com
Sat, 25 Oct 2025 15:55:06 +0200
2 files changed,
57 insertions(+),
5 deletions(-)
M
poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_rotation.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_rotation.rs
@@ -1,21 +1,64 @@
use poulpy_core::{ GLWECopy, GLWERotate, ScratchTakeCore, - layouts::{GLWE, GLWEToMut}, + layouts::{GGSW, GGSWInfos, GGSWToMut, GLWE, GLWEInfos, GLWEToMut}, }; use poulpy_hal::layouts::{Backend, Scratch}; use crate::tfhe::bdd_arithmetic::{Cmux, GetGGSWBit, UnsignedInteger}; -pub trait BDDRotation<T: UnsignedInteger, BE: Backend> +pub trait GGSWBlindRotation<T: UnsignedInteger, BE: Backend> +where + Self: GLWEBlindRotation<T, BE>, + Scratch<BE>: ScratchTakeCore<BE>, +{ + fn ggsw_blind_rotation<R, K>( + &self, + res: &mut R, + k: &K, + bit_start: usize, + bit_size: usize, + bit_step: usize, + scratch: &mut Scratch<BE>, + ) where + R: GGSWToMut, + K: GetGGSWBit<T, BE>, + Scratch<BE>: ScratchTakeCore<BE>, + { + let res: &mut GGSW<&mut [u8]> = &mut res.to_mut(); + + for row in 0..res.dnum().into() { + for col in 0..(res.rank() + 1).into() { + self.glwe_blind_rotation( + &mut res.at_mut(row, col), + k, + bit_start, + bit_size, + bit_step, + scratch, + ); + } + } + } +} + +pub trait GLWEBlindRotation<T: UnsignedInteger, BE: Backend> where Self: GLWECopy + GLWERotate<BE> + Cmux<BE>, Scratch<BE>: ScratchTakeCore<BE>, { + fn glwe_blind_rotation_tmp_bytes<R, A, B>(&self, res_infos: &R, b_infos: &B) -> usize + where + R: GLWEInfos, + B: GGSWInfos, + { + self.cmux_tmp_bytes(res_infos, res_infos, b_infos) + GLWE::bytes_of_from_infos(res_infos) + } + /// Homomorphic multiplication of res by X^{k[bit_start..bit_start + bit_size] * bit_step}. - fn bdd_rotate<R, K, D>( + fn glwe_blind_rotation<R, K>( &self, res: &mut R, - k: K, + k: &K, bit_start: usize, bit_size: usize, bit_step: usize,
M
poulpy-schemes/src/tfhe/bdd_arithmetic/eval.rs
→
poulpy-schemes/src/tfhe/bdd_arithmetic/eval.rs
@@ -3,7 +3,7 @@
use itertools::Itertools; use poulpy_core::{ GLWEAdd, GLWECopy, GLWEExternalProduct, GLWESub, ScratchTakeCore, - layouts::{GLWE, GLWEToMut, GLWEToRef, LWEInfos, prepared::GGSWPreparedToRef}, + layouts::{GGSWInfos, GLWE, GLWEInfos, GLWEToMut, GLWEToRef, LWEInfos, prepared::GGSWPreparedToRef}, }; use poulpy_hal::layouts::{Backend, DataMut, Module, Scratch, ZnxZero};@@ -148,6 +148,15 @@ where
Self: GLWEExternalProduct<BE> + GLWESub + GLWEAdd, Scratch<BE>: ScratchTakeCore<BE>, { + fn cmux_tmp_bytes<R, A, B>(&self, res_infos: &R, a_infos: &A, b_infos: &B) -> usize + where + R: GLWEInfos, + A: GLWEInfos, + B: GGSWInfos, + { + self.glwe_external_product_tmp_bytes(res_infos, a_infos, b_infos) + } + fn cmux<R, T, F, S>(&self, res: &mut R, t: &T, f: &F, s: &S, scratch: &mut Scratch<BE>) where R: GLWEToMut,