mirror of
https://github.com/arnaucube/fhe-study.git
synced 2026-01-24 04:33:52 +01:00
Rm const generics (#2)
* arith: get rid of constant generics. Reason: using constant generics was great for allocating the arrays in the stack, which is faster, but when started to use bigger parameter values, in some cases it was overflowing the stack. This commit removes all the constant generics in all of the `arith` crate, which in some cases slows a bit the performance, but allows for bigger parameter values (on the ones that affect lengths, like N and K). * bfv: get rid of constant generics (reason in previous commit) * ckks: get rid of constant generics (reason in two commits ago) * group ring params under a single struct * gfhe: get rid of constant generics * tfhe: get rid of constant generics * polish & clean a bit * add methods for encoding constants for ct-pt-multiplication
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
use anyhow::Result;
|
||||
|
||||
use arith::{Matrix, Ring, Rq, C, R};
|
||||
use arith::{Matrix, Rq, C, R};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SecretKey<const Q: u64, const N: usize>(Rq<Q, N>);
|
||||
pub struct SecretKey(Rq);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PublicKey<const Q: u64, const N: usize>(Rq<Q, N>, Rq<Q, N>);
|
||||
pub struct PublicKey(Rq, Rq);
|
||||
|
||||
pub struct Encoder<const Q: u64, const N: usize> {
|
||||
pub struct Encoder {
|
||||
n: usize,
|
||||
scale_factor: C<f64>, // Δ (delta)
|
||||
primitive: C<f64>,
|
||||
basis: Matrix<C<f64>>,
|
||||
@@ -34,13 +35,14 @@ fn vandermonde(n: usize, w: C<f64>) -> Matrix<C<f64>> {
|
||||
}
|
||||
Matrix::<C<f64>>(v)
|
||||
}
|
||||
impl<const Q: u64, const N: usize> Encoder<Q, N> {
|
||||
pub fn new(scale_factor: C<f64>) -> Self {
|
||||
let primitive: C<f64> = primitive_root_of_unity(2 * N);
|
||||
let basis = vandermonde(N, primitive);
|
||||
impl Encoder {
|
||||
pub fn new(n: usize, scale_factor: C<f64>) -> Self {
|
||||
let primitive: C<f64> = primitive_root_of_unity(2 * n);
|
||||
let basis = vandermonde(n, primitive);
|
||||
let basis_t = basis.transpose();
|
||||
|
||||
Self {
|
||||
n,
|
||||
scale_factor,
|
||||
primitive,
|
||||
basis,
|
||||
@@ -52,7 +54,7 @@ impl<const Q: u64, const N: usize> Encoder<Q, N> {
|
||||
/// from $\mathbb{C}^{N/2} \longrightarrow \mathbb{Z_q}[X]/(X^N +1) = R$
|
||||
// TODO use alg.1 from 2018-1043,
|
||||
// or as in 2018-1073: $f(x) = 1N (U^T.conj() m + U^T m.conj())$
|
||||
pub fn encode(&self, z: &[C<f64>]) -> Result<R<N>> {
|
||||
pub fn encode(&self, z: &[C<f64>]) -> Result<R> {
|
||||
// $pi^{-1}: \mathbb{C}^{N/2} \longrightarrow \mathbb{H}$
|
||||
let expanded = self.pi_inv(z);
|
||||
|
||||
@@ -93,10 +95,10 @@ impl<const Q: u64, const N: usize> Encoder<Q, N> {
|
||||
|
||||
// TMP: naive round, maybe do gaussian
|
||||
let coeffs = r.iter().map(|e| e.re.round() as i64).collect::<Vec<i64>>();
|
||||
Ok(R::from_vec(coeffs))
|
||||
Ok(R::from_vec(self.n, coeffs))
|
||||
}
|
||||
|
||||
pub fn decode(&self, p: &R<N>) -> Result<Vec<C<f64>>> {
|
||||
pub fn decode(&self, p: &R) -> Result<Vec<C<f64>>> {
|
||||
let p: Vec<C<f64>> = p
|
||||
.coeffs()
|
||||
.iter()
|
||||
@@ -110,7 +112,7 @@ impl<const Q: u64, const N: usize> Encoder<Q, N> {
|
||||
|
||||
/// pi: \mathbb{H} \longrightarrow \mathbb{C}^{N/2}
|
||||
fn pi(&self, z: &[C<f64>]) -> Vec<C<f64>> {
|
||||
z[..N / 2].to_vec()
|
||||
z[..self.n / 2].to_vec()
|
||||
}
|
||||
/// pi^{-1}: \mathbb{C}^{N/2} \longrightarrow \mathbb{H}
|
||||
fn pi_inv(&self, z: &[C<f64>]) -> Vec<C<f64>> {
|
||||
@@ -154,6 +156,7 @@ mod tests {
|
||||
fn test_encode_decode() -> Result<()> {
|
||||
const Q: u64 = 1024;
|
||||
const N: usize = 32;
|
||||
let n: usize = 32;
|
||||
|
||||
let T = 128; // WIP
|
||||
let mut rng = rand::thread_rng();
|
||||
@@ -166,9 +169,9 @@ mod tests {
|
||||
.collect();
|
||||
|
||||
let delta = C::<f64>::new(64.0, 0.0); // delta = scaling factor
|
||||
let encoder = Encoder::<Q, N>::new(delta);
|
||||
let encoder = Encoder::new(n, delta);
|
||||
|
||||
let m: R<N> = encoder.encode(&z)?; // polynomial (encoded vec) \in R
|
||||
let m: R = encoder.encode(&z)?; // polynomial (encoded vec) \in R
|
||||
|
||||
let z_decoded = encoder.decode(&m)?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user