Skip to content

Commit

Permalink
add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
serendipity-crypto committed Jan 3, 2025
1 parent 6144281 commit 3abb9b7
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 3 deletions.
15 changes: 14 additions & 1 deletion algebra/src/polynomial/field/coeff/mul.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::ops::MulAssign;

use crate::{
modulus::ShoupFactor,
reduce::{ReduceAddAssign, ReduceMul, ReduceMulAdd, ReduceMulAssign},
Field,
Field, NttField,
};

use super::FieldPolynomial;
Expand Down Expand Up @@ -56,3 +58,14 @@ impl<F: Field> FieldPolynomial<F> {
});
}
}

impl<F: NttField> FieldPolynomial<F> {
/// Multiply `self` with the a polynomial.
#[inline]
pub fn mul(self, rhs: Self, ntt_table: &<F as NttField>::Table) -> Self {
let mut a = self.into_ntt_poly(ntt_table);
let b = rhs.into_ntt_poly(ntt_table);
a.mul_assign(&b);
a.into_coeff_poly(ntt_table)
}
}
18 changes: 16 additions & 2 deletions boolean_fhe/src/evaluate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ pub enum KeySwitchingKey<C: UnsignedInteger, Q: NttField> {
PowOf2DimensionLwe(LweKeySwitchingKeyRlweMode<Q>),
/// The key switching is based on LWE constant multiplication.
PowOf2ModulusLwe(PowOf2LweKeySwitchingKey<C>),
/// The key switching is based on non power of 2 modulus LWE.
NonPowOf2ModulusLwe(NonPowOf2LweKeySwitchingKey<<Q as Field>::ValueT>),
/// No key switching.
None,
}

impl<C: UnsignedInteger, Q: NttField> KeySwitchingKey<C, Q> {
/// Returns an `Option` containing a reference to the
/// `LweKeySwitchingKeyRlweMode<Q>` if the key is in `PowOf2DimensionLwe` mode, otherwise `None`.
#[inline]
pub fn as_pow_of_2_dimension_lwe(&self) -> Option<&LweKeySwitchingKeyRlweMode<Q>> {
if let Self::PowOf2DimensionLwe(v) = self {
Expand All @@ -37,6 +40,8 @@ impl<C: UnsignedInteger, Q: NttField> KeySwitchingKey<C, Q> {
}
}

/// Returns an `Option` containing a reference to the
/// `PowOf2LweKeySwitchingKey<C>` if the key is in `PowOf2ModulusLwe` mode, otherwise `None`.
#[inline]
pub fn as_pow_of_2_modulus_lwe(&self) -> Option<&PowOf2LweKeySwitchingKey<C>> {
if let Self::PowOf2ModulusLwe(v) = self {
Expand All @@ -46,6 +51,9 @@ impl<C: UnsignedInteger, Q: NttField> KeySwitchingKey<C, Q> {
}
}

/// Attempts to convert the key into an
/// `LweKeySwitchingKeyRlweMode<Q>`. Returns `Ok` with the key if successful, otherwise returns
/// `Err` with the original key.
#[inline]
pub fn try_into_pow_of_2_dimension_lwe(self) -> Result<LweKeySwitchingKeyRlweMode<Q>, Self> {
if let Self::PowOf2DimensionLwe(v) = self {
Expand All @@ -55,6 +63,9 @@ impl<C: UnsignedInteger, Q: NttField> KeySwitchingKey<C, Q> {
}
}

/// Attempts to convert the key into a
/// `PowOf2LweKeySwitchingKey<C>`. Returns `Ok` with the key if successful, otherwise returns
/// `Err` with the original key.
#[inline]
pub fn try_into_pow_of_2_modulus_lwe(self) -> Result<PowOf2LweKeySwitchingKey<C>, Self> {
if let Self::PowOf2ModulusLwe(v) = self {
Expand All @@ -64,6 +75,9 @@ impl<C: UnsignedInteger, Q: NttField> KeySwitchingKey<C, Q> {
}
}

/// Returns an `Option` containing a reference to the
/// `NonPowOf2LweKeySwitchingKey<<Q as Field>::ValueT>` if the key is in `NonPowOf2ModulusLwe` mode,
/// otherwise `None`.
#[inline]
pub fn as_non_pow_of_2_modulus_lwe(
&self,
Expand Down Expand Up @@ -496,7 +510,7 @@ impl<C: UnsignedInteger, Q: NttField> Evaluator<C, Q> {
/// * Input: ciphertext `c1`, with message `b`.
/// * Input: ciphertext `c2`, with message `c`.
/// * Output: ciphertext with message `(a & b) | (b & c) | (a & c)`.
/// If there are two or three `true`(resp. `false`) in `a`, `b` and `c`, it will return `true`(resp. `false`).
/// If there are two or three `true`(resp. `false`) in `a`, `b` and `c`, it will return `true`(resp. `false`).
pub fn majority<M>(
&self,
c0: &LweCiphertext<C>,
Expand Down Expand Up @@ -528,7 +542,7 @@ impl<C: UnsignedInteger, Q: NttField> Evaluator<C, Q> {
/// * Input: ciphertext `c1`, with message `b`.
/// * Input: ciphertext `c2`, with message `c`.
/// * Output: ciphertext with message `if a {b} else {c}`.
/// If `a` is `true`, it will return `b`. If `a` is `false`, it will return `c`.
/// If `a` is `true`, it will return `b`. If `a` is `false`, it will return `c`.
pub fn mux<M>(
&self,
c0: &LweCiphertext<C>,
Expand Down
5 changes: 5 additions & 0 deletions boolean_fhe/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![deny(missing_docs)]

//! Boolean FHE is a library for homomorphic encryption of boolean values.
mod parameter;

mod evaluate;
Expand Down
3 changes: 3 additions & 0 deletions boolean_fhe/src/lut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ use std::iter::once;
use algebra::{polynomial::FieldPolynomial, reduce::ReduceNeg, Field};
use itertools::Itertools;

/// A helper trait for creating look-up tables.
pub trait LookUpTable<Q: Field> {
/// Generates the negacyclic look-up table.
fn negacyclic_lut(&self, coeff_count: usize, log_t: u32) -> FieldPolynomial<Q>;
/// Generates the non-cyclic look-up table.
fn half_lut(&self, coeff_count: usize, log_t: u32) -> FieldPolynomial<Q>;
}

Expand Down
1 change: 1 addition & 0 deletions boolean_fhe/src/parameter/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub static DEFAULT_128_BITS_PARAMETERS: LazyLock<BooleanFheParameters<u16, Fp>>
.unwrap()
});

/// Default 128-bits security Parameters without key switching
pub static NO_KEY_SWITCHING: LazyLock<BooleanFheParameters<u16, Fp>> = LazyLock::new(|| {
BooleanFheParameters::<u16, Fp>::new(ConstParameters {
lwe_dimension: 1024,
Expand Down
3 changes: 3 additions & 0 deletions boolean_fhe/src/parameter/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! The parameters of the fully homomorphic encryption scheme.
use algebra::decompose::NonPowOf2ApproxSignedBasis;
use algebra::integer::Bits;
use algebra::random::DiscreteGaussian;
Expand Down Expand Up @@ -285,6 +287,7 @@ impl<C: UnsignedInteger, Q: NttField> BooleanFheParameters<C, Q> {
&self.lwe_params
}

/// Generates the NTT table.
#[inline]
pub fn generate_ntt_table_for_rlwe(&self) -> <Q as NttField>::Table {
Q::generate_ntt_table(self.ring_dimension().trailing_zeros()).unwrap()
Expand Down
3 changes: 3 additions & 0 deletions boolean_fhe/src/secret_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ impl<C: UnsignedInteger, Q: NttField> SecretKeyPack<C, Q> {
self.parameters.lwe_params()
}

/// Encrypts a message with cipher modulus and random number generator.
#[inline]
pub fn encrypt<M, R>(
&self,
Expand All @@ -122,6 +123,7 @@ impl<C: UnsignedInteger, Q: NttField> SecretKeyPack<C, Q> {
.encrypt(message, self.lwe_params(), cipher_modulus, rng)
}

/// Decrypts the cipher text.
#[inline]
pub fn decrypt<M>(
&self,
Expand All @@ -135,6 +137,7 @@ impl<C: UnsignedInteger, Q: NttField> SecretKeyPack<C, Q> {
.decrypt(cipher_text, self.lwe_params(), cipher_modulus)
}

/// Decrypts the cipher text and calculates the noise.
#[inline]
pub fn decrypt_with_noise<M>(
&self,
Expand Down

0 comments on commit 3abb9b7

Please sign in to comment.