Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new key switch method and support q>2N #135

Merged
merged 21 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"algebra_derive",
"fhe_core",
"lattice",
"fhe",
"pcs",
"zkfhe",
"zkp",
Expand Down
2 changes: 1 addition & 1 deletion algebra/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
algebra_derive = { path = "../algebra_derive" }
algebra_derive = { path = "../algebra_derive", default-features = false }

thiserror = { workspace = true }
num-traits = { workspace = true }
Expand Down
3 changes: 1 addition & 2 deletions algebra/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ pub use polynomial::multivariate::{
SparsePolynomial,
};
pub use polynomial::univariate::{
ntt_add_mul_assign, ntt_add_mul_assign_fast, ntt_add_mul_inplace, ntt_mul_assign,
ntt_mul_inplace, NTTPolynomial, Polynomial,
ntt_add_mul_assign, ntt_add_mul_assign_fast, ntt_add_mul_inplace, NTTPolynomial, Polynomial,
};
pub use primitive::{div_ceil, AsFrom, AsInto, Bits, Widening, WrappingOps};
pub use random::{
Expand Down
3 changes: 1 addition & 2 deletions algebra/src/polynomial/univariate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ mod ntt_polynomial;

pub use native_polynomial::Polynomial;
pub use ntt_polynomial::{
ntt_add_mul_assign, ntt_add_mul_assign_fast, ntt_add_mul_inplace, ntt_mul_assign,
ntt_mul_inplace, NTTPolynomial,
ntt_add_mul_assign, ntt_add_mul_assign_fast, ntt_add_mul_inplace, NTTPolynomial,
};
60 changes: 42 additions & 18 deletions algebra/src/polynomial/univariate/native_polynomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ impl<F: Field> Polynomial<F> {
&mut self.data
}

/// Get the coefficient counts of polynomial.
#[inline]
pub fn coeff_count(&self) -> usize {
self.data.len()
}

/// Creates a [`Polynomial<F>`] with all coefficients equal to zero.
#[inline]
pub fn zero(coeff_count: usize) -> Self {
Expand Down Expand Up @@ -119,24 +125,6 @@ impl<F: Field> Polynomial<F> {
self.data.as_mut_slice()
}

/// Multiply `self` with the a scalar.
#[inline]
pub fn mul_scalar(&self, scalar: F) -> Self {
Self::new(self.iter().map(|&v| v * scalar).collect())
}

/// Multiply `self` with the a scalar inplace.
#[inline]
pub fn mul_scalar_assign(&mut self, scalar: F) {
self.iter_mut().for_each(|v| *v *= scalar)
}

/// Get the coefficient counts of polynomial.
#[inline]
pub fn coeff_count(&self) -> usize {
self.data.len()
}

/// Returns an iterator that allows reading each value or coefficient of the polynomial.
#[inline]
pub fn iter(&self) -> Iter<F> {
Expand Down Expand Up @@ -170,6 +158,42 @@ impl<F: Field> Polynomial<F> {
self.data.resize_with(new_degree, f);
}

/// Multiply `self` with the a scalar.
#[inline]
pub fn mul_scalar(&self, scalar: F) -> Self {
Self::new(self.iter().map(|&v| v * scalar).collect())
}

/// Multiply `self` with the a scalar inplace.
#[inline]
pub fn mul_scalar_assign(&mut self, scalar: F) {
self.iter_mut().for_each(|v| *v *= scalar)
}

/// Performs addition operation:`self + rhs`,
/// and puts the result to the `destination`.
#[inline]
pub fn add_inplace(&self, rhs: &Self, destination: &mut Self) {
self.iter()
.zip(rhs)
.zip(destination)
.for_each(|((&x, &y), z)| {
*z = x + y;
})
}

/// Performs subtraction operation:`self - rhs`,
/// and puts the result to the `destination`.
#[inline]
pub fn sub_inplace(&self, rhs: &Self, destination: &mut Self) {
self.iter()
.zip(rhs)
.zip(destination)
.for_each(|((&x, &y), z)| {
*z = x - y;
})
}

/// Performs the unary `-` operation.
#[inline]
pub fn neg_assign(&mut self) {
Expand Down
122 changes: 64 additions & 58 deletions algebra/src/polynomial/univariate/ntt_polynomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ impl<F: Field> NTTPolynomial<F> {
&mut self.data
}

/// Get the coefficient counts of polynomial.
#[inline]
pub fn coeff_count(&self) -> usize {
self.data.len()
}

/// Creates a [`NTTPolynomial<F>`] with all coefficients equal to zero.
#[inline]
pub fn zero(coeff_count: usize) -> Self {
Expand Down Expand Up @@ -113,24 +119,6 @@ impl<F: Field> NTTPolynomial<F> {
self.data.as_mut_slice()
}

/// Get the coefficient counts of polynomial.
#[inline]
pub fn coeff_count(&self) -> usize {
self.data.len()
}

/// Multiply `self` with the a scalar.
#[inline]
pub fn mul_scalar(&self, scalar: F) -> Self {
Self::new(self.iter().map(|&v| v * scalar).collect())
}

/// Multiply `self` with the a scalar inplace.
#[inline]
pub fn mul_scalar_assign(&mut self, scalar: F) {
self.iter_mut().for_each(|v| *v *= scalar)
}

/// Returns an iterator that allows reading each value or coefficient of the polynomial.
#[inline]
pub fn iter(&self) -> Iter<F> {
Expand Down Expand Up @@ -164,6 +152,54 @@ impl<F: Field> NTTPolynomial<F> {
self.data.resize_with(new_degree, f);
}

/// Multiply `self` with the a scalar.
#[inline]
pub fn mul_scalar(&self, scalar: F) -> Self {
Self::new(self.iter().map(|&v| v * scalar).collect())
}

/// Multiply `self` with the a scalar inplace.
#[inline]
pub fn mul_scalar_assign(&mut self, scalar: F) {
self.iter_mut().for_each(|v| *v *= scalar)
}

/// Performs addition operation:`self + rhs`,
/// and puts the result to the `destination`.
#[inline]
pub fn add_inplace(&self, rhs: &Self, destination: &mut Self) {
self.iter()
.zip(rhs)
.zip(destination)
.for_each(|((&x, &y), z)| {
*z = x + y;
})
}

/// Performs subtraction operation:`self - rhs`,
/// and puts the result to the `destination`.
#[inline]
pub fn sub_inplace(&self, rhs: &Self, destination: &mut Self) {
self.iter()
.zip(rhs)
.zip(destination)
.for_each(|((&x, &y), z)| {
*z = x - y;
})
}

/// Performs subtraction operation:`self * rhs`,
/// and puts the result to the `destination`.
#[inline]
pub fn mul_inplace(&self, rhs: &Self, destination: &mut Self) {
self.iter()
.zip(rhs)
.zip(destination)
.for_each(|((&x, &y), z)| {
*z = x * y;
})
}

/// Performs the unary `-` operation.
#[inline]
pub fn neg_assign(&mut self) {
Expand Down Expand Up @@ -447,11 +483,8 @@ impl<F: Field> Mul<&NTTPolynomial<F>> for &NTTPolynomial<F> {
impl<F: NTTField> MulAssign<Polynomial<F>> for NTTPolynomial<F> {
#[inline]
fn mul_assign(&mut self, rhs: Polynomial<F>) {
let coeff_count = self.coeff_count();
debug_assert_eq!(coeff_count, rhs.coeff_count());

let rhs = rhs.into_ntt_polynomial();
ntt_mul_assign(self, &rhs);
debug_assert_eq!(self.coeff_count(), rhs.coeff_count());
*self *= rhs.into_ntt_polynomial();
}
}

Expand Down Expand Up @@ -486,13 +519,8 @@ impl<F: NTTField> Mul<Polynomial<F>> for &NTTPolynomial<F> {

#[inline]
fn mul(self, rhs: Polynomial<F>) -> Self::Output {
let coeff_count = self.coeff_count();
debug_assert_eq!(coeff_count, rhs.coeff_count());
debug_assert!(coeff_count.is_power_of_two());

let log_n = coeff_count.trailing_zeros();
let ntt_table = F::get_ntt_table(log_n).unwrap();
ntt_table.transform_inplace(rhs) * self
debug_assert_eq!(self.coeff_count(), rhs.coeff_count());
NTTPolynomial::from(rhs) * self
}
}

Expand Down Expand Up @@ -547,30 +575,10 @@ impl<F: Field> Inv for &NTTPolynomial<F> {
}
}

/// Performs enrty-wise mul operation.
#[inline]
pub fn ntt_mul_assign<F: NTTField>(x: &mut NTTPolynomial<F>, y: &NTTPolynomial<F>) {
x.iter_mut().zip(y).for_each(|(a, b)| *a *= b);
}

/// Performs enrty-wise mul operation.
#[inline]
pub fn ntt_mul_inplace<F: NTTField>(
x: &NTTPolynomial<F>,
y: &NTTPolynomial<F>,
des: &mut NTTPolynomial<F>,
) {
des.iter_mut()
.zip(x)
.zip(y)
.for_each(|((d, &a), &b)| *d = a * b);
}

/// Performs enrty-wise add_mul operation.
///
/// Treats three iterators as [`NTTPolynomial<F>`]'s iterators,
/// then multiply enrty-wise over last two iterators, and add back to the first
/// iterator.
/// Multiply enrty-wise over last two [NTTPolynomial<F>], and add back to the first
/// [NTTPolynomial<F>].
#[inline]
pub fn ntt_add_mul_assign<F: NTTField>(
x: &mut NTTPolynomial<F>,
Expand All @@ -585,9 +593,8 @@ pub fn ntt_add_mul_assign<F: NTTField>(

/// Performs enrty-wise add_mul operation.
///
/// Treats four iterators as [`NTTPolynomial<F>`]'s iterators,
/// then multiply enrty-wise over last two iterators, and add the second
/// iterator, store the result to first iterator.
/// Multiply enrty-wise over middle two [NTTPolynomial<F>], and add the first
/// [NTTPolynomial<F>], store the result to last [NTTPolynomial<F>].
#[inline]
pub fn ntt_add_mul_inplace<F: NTTField>(
x: &NTTPolynomial<F>,
Expand All @@ -604,9 +611,8 @@ pub fn ntt_add_mul_inplace<F: NTTField>(

/// Performs enrty-wise add_mul fast operation.
///
/// Treats three iterators as [`NTTPolynomial<F>`]'s iterators,
/// then multiply enrty-wise over last two iterators, and add back to the first
/// iterator.
/// Multiply enrty-wise over last two [NTTPolynomial<F>], and add back to the first
/// [NTTPolynomial<F>].
///
/// The result coefficients may be in [0, 2*modulus) for some case,
/// and fall back to [0, modulus) for normal case.
Expand Down
5 changes: 5 additions & 0 deletions algebra_derive/src/fhe_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ fn impl_fhe_field(input: Input) -> TokenStream {

quote! {
impl ::algebra::FheField for #name{
#[inline]
fn lazy_new(value: Self::Value) -> Self {
Self(value)
}

#[inline]
fn add_mul(self, a: Self, b: Self) -> Self {
use ::algebra::Widening;
Expand Down
32 changes: 32 additions & 0 deletions fhe/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "fhe"
version = "0.1.0"
edition = "2021"

[dependencies]
algebra = { path = "../algebra", default-features = false }
lattice = { path = "../lattice", default-features = false }
fhe_core = { path = "../fhe_core", default-features = false }

rand = { workspace = true }
rayon = { workspace = true }
once_cell = { workspace = true }

[features]
default = ["concrete-ntt"]
concrete-ntt = [
"algebra/concrete-ntt",
"lattice/concrete-ntt",
"fhe_core/concrete-ntt",
]
nightly = ["algebra/nightly", "lattice/nightly", "fhe_core/nightly"]
count_ntt = ["algebra/count_ntt"]

[dev-dependencies]
criterion = { workspace = true }

[package.metadata.docs.rs]
all-features = true
# enable unstable features in the documentation
rustdoc-args = ["--cfg", "docsrs"]
# RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features --no-deps
1 change: 1 addition & 0 deletions fhe/src/bfhe/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions fhe/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod bfhe;
4 changes: 2 additions & 2 deletions fhe_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ version = "0.1.0"
edition = "2021"

[dependencies]
algebra = { path = "../algebra" }
lattice = { path = "../lattice" }
algebra = { path = "../algebra", default-features = false }
lattice = { path = "../lattice", default-features = false }

thiserror = { workspace = true }
num-traits = { workspace = true }
Expand Down
Loading