tfhe: add external prod TGSW * TLWE, also TLev * Vec<T64>

This commit is contained in:
2025-07-27 20:58:32 +00:00
parent f053e9a904
commit e4717da5b0
5 changed files with 136 additions and 17 deletions

View File

@@ -1,4 +1,5 @@
use anyhow::Result;
use itertools::zip_eq;
use rand::Rng;
use rand_distr::{Normal, Uniform};
use std::ops::{Add, Mul};
@@ -7,8 +8,6 @@ use arith::{Ring, TR};
use crate::glwe::{PublicKey, SecretKey, GLWE};
const ERR_SIGMA: f64 = 3.2;
// l GLWEs
#[derive(Clone, Debug)]
pub struct GLev<R: Ring, const K: usize>(pub(crate) Vec<GLWE<R, K>>);
@@ -52,6 +51,21 @@ impl<R: Ring, const K: usize> GLev<R, K> {
}
}
// dot product between a GLev and Vec<R>.
// Used for operating decompositions with KSK_i.
// GLev * Vec<R> --> GLWE
impl<R: Ring, const K: usize> Mul<Vec<R>> for GLev<R, K> {
type Output = GLWE<R, K>;
fn mul(self, v: Vec<R>) -> GLWE<R, K> {
// l times GLWES
let glwes: Vec<GLWE<R, K>> = self.0;
// l iterations
let r: GLWE<R, K> = zip_eq(v, glwes).map(|(v_i, glwe_i)| glwe_i * v_i).sum();
r
}
}
#[cfg(test)]
mod tests {
use anyhow::Result;

View File

@@ -12,7 +12,8 @@ use arith::{Ring, Rq, Zq, TR};
use crate::glev::GLev;
const ERR_SIGMA: f64 = 3.2;
// const ERR_SIGMA: f64 = 3.2;
const ERR_SIGMA: f64 = 0.0; // TODO WIP
/// GLWE implemented over the `Ring` trait, so that it can be also instantiated
/// over the Torus polynomials 𝕋_<N,q>[X] = 𝕋_q[X]/ (X^N+1).
@@ -68,22 +69,11 @@ impl<R: Ring, const K: usize> GLWE<R, K> {
// K iterations, ksk.0 contains K times GLev
let rhs: GLWE<R, K> = zip_eq(a.0, ksk.0.clone())
.map(|(a_i, ksk_i)| Self::dot_prod(a_i.decompose(beta, l), ksk_i))
.map(|(a_i, ksk_i)| ksk_i * a_i.decompose(beta, l)) // dot_product
.sum();
lhs - rhs
}
// note: a_decomp is of length N
fn dot_prod(a_decomp: Vec<R>, ksk_i: GLev<R, K>) -> GLWE<R, K> {
// l times GLWES
let glwes: Vec<GLWE<R, K>> = ksk_i.0;
// l iterations
let r: GLWE<R, K> = zip_eq(a_decomp, glwes)
.map(|(a_d_i, glwe_i)| glwe_i * a_d_i)
.sum();
r
}
// encrypts with the given SecretKey (instead of PublicKey)
pub fn encrypt_s(