mirror of
https://github.com/arnaucube/fhe-study.git
synced 2026-01-24 04:33:52 +01:00
(TFHE): add TLWE encryption & decryption
This commit is contained in:
@@ -30,4 +30,10 @@ pub trait Ring:
|
||||
fn from_vec(coeffs: Vec<Self::C>) -> Self;
|
||||
|
||||
fn decompose(&self, beta: u32, l: u32) -> Vec<Self>;
|
||||
|
||||
/// returns [ [(num/den) * self].round() ] mod q
|
||||
/// ie. performs the multiplication and division over f64, and then it
|
||||
/// rounds the result, only applying the mod Q (if the ring is mod Q) at the
|
||||
/// end.
|
||||
fn mul_div_round(&self, num: u64, den: u64) -> Self;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,19 @@ impl<const N: usize> Ring for R<N> {
|
||||
unimplemented!();
|
||||
// array::from_fn(|i| self.coeffs[i].decompose(beta, l))
|
||||
}
|
||||
|
||||
// performs the multiplication and division over f64, and then it rounds the
|
||||
// result, only applying the mod Q at the end
|
||||
fn mul_div_round(&self, num: u64, den: u64) -> Self {
|
||||
unimplemented!()
|
||||
// fn mul_div_round<const Q: u64>(&self, num: u64, den: u64) -> crate::Rq<Q, N> {
|
||||
// let r: Vec<f64> = self
|
||||
// .coeffs()
|
||||
// .iter()
|
||||
// .map(|e| ((num as f64 * *e as f64) / den as f64).round())
|
||||
// .collect();
|
||||
// crate::Rq::<Q, N>::from_vec_f64(r)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const Q: u64, const N: usize> From<crate::ring_nq::Rq<Q, N>> for R<N> {
|
||||
@@ -74,16 +87,6 @@ impl<const N: usize> R<N> {
|
||||
pub fn mul_by_i64(&self, s: i64) -> Self {
|
||||
Self(array::from_fn(|i| self.0[i] * s))
|
||||
}
|
||||
// performs the multiplication and division over f64, and then it rounds the
|
||||
// result, only applying the mod Q at the end
|
||||
pub fn mul_div_round<const Q: u64>(&self, num: u64, den: u64) -> crate::Rq<Q, N> {
|
||||
let r: Vec<f64> = self
|
||||
.coeffs()
|
||||
.iter()
|
||||
.map(|e| ((num as f64 * *e as f64) / den as f64).round())
|
||||
.collect();
|
||||
crate::Rq::<Q, N>::from_vec_f64(r)
|
||||
}
|
||||
|
||||
pub fn infinity_norm(&self) -> u64 {
|
||||
self.coeffs()
|
||||
|
||||
@@ -70,6 +70,18 @@ impl<const Q: u64, const N: usize> Ring for Rq<Q, N> {
|
||||
// convert it to Rq<Q,N>
|
||||
r.iter().map(|a_i| Self::from_vec(a_i.clone())).collect()
|
||||
}
|
||||
|
||||
// returns [ [(num/den) * self].round() ] mod q
|
||||
// ie. performs the multiplication and division over f64, and then it rounds the
|
||||
// result, only applying the mod Q at the end
|
||||
fn mul_div_round(&self, num: u64, den: u64) -> Self {
|
||||
let r: Vec<f64> = self
|
||||
.coeffs()
|
||||
.iter()
|
||||
.map(|e| ((num as f64 * e.0 as f64) / den as f64).round())
|
||||
.collect();
|
||||
Rq::<Q, N>::from_vec_f64(r)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const Q: u64, const N: usize> From<crate::ring_n::R<N>> for Rq<Q, N> {
|
||||
@@ -231,17 +243,6 @@ impl<const Q: u64, const N: usize> Rq<Q, N> {
|
||||
.collect();
|
||||
Rq::<Q, N>::from_vec_f64(r)
|
||||
}
|
||||
// returns [ [(num/den) * self].round() ] mod q
|
||||
// ie. performs the multiplication and division over f64, and then it rounds the
|
||||
// result, only applying the mod Q at the end
|
||||
pub fn mul_div_round(&self, num: u64, den: u64) -> Self {
|
||||
let r: Vec<f64> = self
|
||||
.coeffs()
|
||||
.iter()
|
||||
.map(|e| ((num as f64 * e.0 as f64) / den as f64).round())
|
||||
.collect();
|
||||
Rq::<Q, N>::from_vec_f64(r)
|
||||
}
|
||||
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// TODO simplify
|
||||
|
||||
@@ -49,6 +49,18 @@ impl<const N: usize> Ring for Tn<N> {
|
||||
// convert it to Tn<N>
|
||||
r.iter().map(|a_i| Self::from_vec(a_i.clone())).collect()
|
||||
}
|
||||
|
||||
/// returns [ [(num/den) * self].round() ] mod q
|
||||
/// ie. performs the multiplication and division over f64, and then it rounds the
|
||||
/// result, only applying the mod Q at the end
|
||||
fn mul_div_round(&self, num: u64, den: u64) -> Self {
|
||||
let r: Vec<T64> = self
|
||||
.coeffs()
|
||||
.iter()
|
||||
.map(|e| T64(((num as f64 * e.0 as f64) / den as f64).round() as u64))
|
||||
.collect();
|
||||
Self::from_vec(r)
|
||||
}
|
||||
}
|
||||
|
||||
// apply mod (X^N+1)
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
//! This file implements the struct for an Tuple of Ring Rq elements and its
|
||||
//! operations.
|
||||
//! operations, which are performed element-wise.
|
||||
|
||||
use anyhow::Result;
|
||||
use itertools::zip_eq;
|
||||
use rand::{distributions::Distribution, Rng};
|
||||
use rand_distr::{Normal, Uniform};
|
||||
use std::iter::Sum;
|
||||
use std::{array, ops};
|
||||
use std::{
|
||||
array,
|
||||
ops::{Add, Mul, Sub},
|
||||
};
|
||||
|
||||
use crate::Ring;
|
||||
|
||||
@@ -34,7 +37,7 @@ impl<R: Ring, const K: usize> TR<R, K> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Ring, const K: usize> ops::Add<TR<R, K>> for TR<R, K> {
|
||||
impl<R: Ring, const K: usize> Add<TR<R, K>> for TR<R, K> {
|
||||
type Output = Self;
|
||||
fn add(self, other: Self) -> Self {
|
||||
Self(
|
||||
@@ -45,7 +48,7 @@ impl<R: Ring, const K: usize> ops::Add<TR<R, K>> for TR<R, K> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Ring, const K: usize> ops::Sub<TR<R, K>> for TR<R, K> {
|
||||
impl<R: Ring, const K: usize> Sub<TR<R, K>> for TR<R, K> {
|
||||
type Output = Self;
|
||||
fn sub(self, other: Self) -> Self {
|
||||
Self(zip_eq(self.0, other.0).map(|(s, o)| s - o).collect())
|
||||
@@ -54,13 +57,13 @@ impl<R: Ring, const K: usize> ops::Sub<TR<R, K>> for TR<R, K> {
|
||||
|
||||
/// for (TR,TR), the Mul operation is defined as:
|
||||
/// for A, B \in R^k, result = Σ A_i * B_i \in R
|
||||
impl<R: Ring, const K: usize> ops::Mul<TR<R, K>> for TR<R, K> {
|
||||
impl<R: Ring, const K: usize> Mul<TR<R, K>> for TR<R, K> {
|
||||
type Output = R;
|
||||
fn mul(self, other: Self) -> R {
|
||||
zip_eq(self.0, other.0).map(|(s, o)| s * o).sum()
|
||||
}
|
||||
}
|
||||
impl<R: Ring, const K: usize> ops::Mul<&TR<R, K>> for &TR<R, K> {
|
||||
impl<R: Ring, const K: usize> Mul<&TR<R, K>> for &TR<R, K> {
|
||||
type Output = R;
|
||||
fn mul(self, other: &TR<R, K>) -> R {
|
||||
zip_eq(self.0.clone(), other.0.clone())
|
||||
@@ -71,13 +74,13 @@ impl<R: Ring, const K: usize> ops::Mul<&TR<R, K>> for &TR<R, K> {
|
||||
|
||||
/// for (TR, R), the Mul operation is defined as each element of TR is
|
||||
/// multiplied by R
|
||||
impl<R: Ring, const K: usize> ops::Mul<R> for TR<R, K> {
|
||||
impl<R: Ring, const K: usize> Mul<R> for TR<R, K> {
|
||||
type Output = TR<R, K>;
|
||||
fn mul(self, other: R) -> TR<R, K> {
|
||||
Self(self.0.iter().map(|s| s.clone() * other.clone()).collect())
|
||||
}
|
||||
}
|
||||
impl<R: Ring, const K: usize> ops::Mul<&R> for &TR<R, K> {
|
||||
impl<R: Ring, const K: usize> Mul<&R> for &TR<R, K> {
|
||||
type Output = TR<R, K>;
|
||||
fn mul(self, other: &R) -> TR<R, K> {
|
||||
TR::<R, K>(self.0.iter().map(|s| s.clone() * other.clone()).collect())
|
||||
|
||||
Reference in New Issue
Block a user