From 787504c230eca54118e4610b92ba1e7cee33f203 Mon Sep 17 00:00:00 2001 From: Pro7ech Date: Tue, 28 Oct 2025 11:04:47 +0100 Subject: [PATCH] Improve GGSW-based blind rotation API --- CHANGELOG.md | 7 +++++- Cargo.lock | 2 +- poulpy-schemes/Cargo.toml | 2 +- .../src/tfhe/bdd_arithmetic/blind_rotation.rs | 25 +++++++++++++------ .../tests/test_suite/ggsw_blind_rotations.rs | 1 + .../tests/test_suite/glwe_blind_rotation.rs | 1 + 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65e0240..bd4b886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,18 @@ ## [0.3.2] - 2025-10-27 +### `poulpy-schemes` + - Added `sign` argument to GGSW-based blind rotation, which enables to choose the rotation direction of the test vector. + +## [0.3.2] - 2025-10-27 + ### `poulpy-hal` - Improved convolution functionality ### `poulpy-core` - Rename `GLWEToLWESwitchingKey` to `GLWEToLWEKey`. - Rename `LWEToGLWESwitchingKey` to `LWEToGLWEKey`. - - Add `GLWESecretTensor` which stores the flattened upper triangular matrix of the pairs `sk[i] * sk[j]`. + - Add `GLWESecretTensor` which stores the flattened upper right of the tensor matrix of the pairs `sk[i] * sk[j]`. - Add `GGLWEToGGSWKey`, `GGLWEToGGSWKeyPrepared`, `GGLWEToGGSWKeyCompressed`, which encrypts the full tensor matrix of all pairs `sk[i] * sk[j]`, with one `GGLWE` per row. - Update `GGLWEToGGSW` API to take `GGLWEToGGSWKey` instead of the `GLWETensorKey` - Add `GLWETensor`, the result of tensoring two `GLWE` of identical rank. diff --git a/Cargo.lock b/Cargo.lock index 2c32176..d0d2744 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,7 +401,7 @@ dependencies = [ [[package]] name = "poulpy-schemes" -version = "0.3.2" +version = "0.3.3" dependencies = [ "byteorder", "criterion", diff --git a/poulpy-schemes/Cargo.toml b/poulpy-schemes/Cargo.toml index 4f8079b..2c025c9 100644 --- a/poulpy-schemes/Cargo.toml +++ b/poulpy-schemes/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "poulpy-schemes" -version = "0.3.2" +version = "0.3.3" edition = "2024" license = "Apache-2.0" readme = "README.md" diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/blind_rotation.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/blind_rotation.rs index 96dc418..3fe36ca 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/blind_rotation.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/blind_rotation.rs @@ -36,7 +36,8 @@ where res: &mut R, a: &A, k: &K, - bit_start: usize, + sign: bool, + bit_rsh: usize, bit_mask: usize, bit_lsh: usize, scratch: &mut Scratch, @@ -58,7 +59,8 @@ where &mut res.at_mut(row, col), &a.at(row, col), k, - bit_start, + sign, + bit_rsh, bit_mask, bit_lsh, scratch, @@ -81,7 +83,8 @@ where res: &mut R, test_vector: &S, k: &K, - bit_start: usize, + sign: bool, + bit_rsh: usize, bit_mask: usize, bit_lsh: usize, scratch: &mut Scratch, @@ -115,7 +118,8 @@ where &mut res.at_mut(row, col), &tmp_glwe, k, - bit_start, + sign, + bit_rsh, bit_mask, bit_lsh, scratch_1, @@ -146,12 +150,13 @@ where } #[allow(clippy::too_many_arguments)] - /// res <- a * X^{((k>>bit_rsh) % 2^bit_mask) << bit_lsh}. + /// res <- a * X^{sign * ((k>>bit_rsh) % 2^bit_mask) << bit_lsh}. fn glwe_to_glwe_blind_rotation( &self, res: &mut R, a: &A, k: &K, + sign: bool, bit_rsh: usize, bit_mask: usize, bit_lsh: usize, @@ -170,7 +175,10 @@ where let (mut tmp_res, scratch_1) = scratch.take_glwe(&res); // a <- a ; b <- a * X^{-2^{i + bit_lsh}} - self.glwe_rotate(-1 << bit_lsh, &mut res, a); + match sign { + true => self.glwe_rotate(1 << bit_lsh, &mut res, a), + false => self.glwe_rotate(-1 << bit_lsh, &mut res, a), + } // b <- (b - a) * GGSW(b[i]) + a self.cmux_inplace(&mut res, a, &k.get_bit(bit_rsh), scratch_1); @@ -187,7 +195,10 @@ where }; // a <- a ; b <- a * X^{-2^{i + bit_lsh}} - self.glwe_rotate(-1 << (i + bit_lsh), b, a); + match sign { + true => self.glwe_rotate(1 << (i + bit_lsh), b, a), + false => self.glwe_rotate(-1 << (i + bit_lsh), b, a), + } // b <- (b - a) * GGSW(b[i]) + a self.cmux_inplace(b, a, &k.get_bit(i + bit_rsh), scratch_1); diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/ggsw_blind_rotations.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/ggsw_blind_rotations.rs index 5a0f6bd..db68180 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/ggsw_blind_rotations.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/ggsw_blind_rotations.rs @@ -121,6 +121,7 @@ where &mut res, &scalar, &k_enc_prep, + false, bit_start, bit_size, bit_step, diff --git a/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/glwe_blind_rotation.rs b/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/glwe_blind_rotation.rs index 7573b49..fce0259 100644 --- a/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/glwe_blind_rotation.rs +++ b/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/glwe_blind_rotation.rs @@ -106,6 +106,7 @@ where &mut res, &test_glwe, &k_enc_prep, + false, bit_start, bit_size, bit_step,