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

Refine the codebase #154

Merged
merged 4 commits into from
Nov 20, 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
67 changes: 38 additions & 29 deletions bool/src/bfhe/evaluate.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use algebra::{NTTField, Polynomial};
use fhe_core::{
lwe_modulus_switch, lwe_modulus_switch_assign_between_modulus, lwe_modulus_switch_inplace,
BlindRotationKey, BlindRotationType, KeySwitchingKeyEnum, KeySwitchingLWEKey,
KeySwitchingRLWEKey, LWECiphertext, LWEModulusType, Parameters, ProcessType, SecretKeyPack,
Steps,
BlindRotationKey, KeySwitchingKeyEnum, KeySwitchingLWEKey, KeySwitchingRLWEKey, LWECiphertext,
LWEModulusType, Parameters, SecretKeyPack, Steps,
};

/// The evaluator of the homomorphic encryption scheme.
Expand All @@ -24,10 +23,29 @@ impl<C: LWEModulusType, Q: NTTField> EvaluationKey<C, Q> {
&self.parameters
}

/// Compute the lookup table step.
#[inline]
pub fn lut_step(&self) -> usize {
let q: usize = self
.parameters
.lwe_cipher_modulus_value()
.try_into()
.ok()
.unwrap();
let twice_ring_dim = self.parameters.ring_dimension() << 1;

if twice_ring_dim % q == 0 {
twice_ring_dim / q
} else if q % twice_ring_dim == 0 {
1
} else {
unimplemented!()
}
}

/// Creates a new [`EvaluationKey`] from the given [`SecretKeyPack`].
pub fn new(secret_key_pack: &SecretKeyPack<C, Q>) -> Self {
let parameters = secret_key_pack.parameters();
assert_eq!(parameters.blind_rotation_type(), BlindRotationType::RLWE);

let blind_rotation_key = BlindRotationKey::generate(secret_key_pack);

Expand All @@ -51,23 +69,14 @@ impl<C: LWEModulusType, Q: NTTField> EvaluationKey<C, Q> {
/// Complete the bootstrapping operation with LWE Ciphertext *`c`* and lookup table `lut`.
pub fn bootstrap(&self, mut c: LWECiphertext<C>, lut: Polynomial<Q>) -> LWECiphertext<C> {
let parameters = self.parameters();
let pre = parameters.process_before_blind_rotation();

match pre.process() {
ProcessType::ModulusSwitch => {
lwe_modulus_switch_assign_between_modulus(
&mut c,
parameters.lwe_cipher_modulus_value(),
pre.twice_ring_dimension_value(),
);
}
ProcessType::Scale { ratio } => {
let ratio = C::as_from(ratio as u64);
c.a_mut().iter_mut().for_each(|v| *v = *v * ratio);
*c.b_mut() = c.b() * ratio;
}
ProcessType::Noop => (),
}
let twice_ring_dimension_value = C::try_from((parameters.ring_dimension() << 1) as u64)
.ok()
.unwrap();
lwe_modulus_switch_assign_between_modulus(
&mut c,
parameters.lwe_cipher_modulus_value(),
twice_ring_dimension_value,
);

let mut acc =
self.blind_rotation_key
Expand Down Expand Up @@ -170,7 +179,7 @@ impl<C: LWEModulusType, Q: NTTField> Evaluator<C, Q> {

let add = c0.add_reduce_component_wise_ref(c1, lwe_modulus);

let lut = init_nand_lut(parameters.ring_dimension(), parameters.lut_step());
let lut = init_nand_lut(parameters.ring_dimension(), self.ek.lut_step());

self.bootstrap(add, lut)
}
Expand All @@ -189,7 +198,7 @@ impl<C: LWEModulusType, Q: NTTField> Evaluator<C, Q> {
let add = c0.add_reduce_component_wise_ref(c1, lwe_modulus);

let lut: Polynomial<Q> =
init_and_majority_lut(parameters.ring_dimension(), parameters.lut_step());
init_and_majority_lut(parameters.ring_dimension(), self.ek.lut_step());

self.bootstrap(add, lut)
}
Expand All @@ -207,7 +216,7 @@ impl<C: LWEModulusType, Q: NTTField> Evaluator<C, Q> {

let add = c0.add_reduce_component_wise_ref(c1, lwe_modulus);

let lut = init_or_lut(parameters.ring_dimension(), parameters.lut_step());
let lut = init_or_lut(parameters.ring_dimension(), self.ek.lut_step());

self.bootstrap(add, lut)
}
Expand All @@ -225,7 +234,7 @@ impl<C: LWEModulusType, Q: NTTField> Evaluator<C, Q> {

let add = c0.add_reduce_component_wise_ref(c1, lwe_modulus);

let lut = init_nor_lut(parameters.ring_dimension(), parameters.lut_step());
let lut = init_nor_lut(parameters.ring_dimension(), self.ek.lut_step());

self.bootstrap(add, lut)
}
Expand All @@ -244,7 +253,7 @@ impl<C: LWEModulusType, Q: NTTField> Evaluator<C, Q> {
let mut sub = c0.sub_reduce_component_wise_ref(c1, lwe_modulus);
sub.scalar_mul_reduce_inplace(C::TWO, lwe_modulus);

let lut = init_xor_lut(parameters.ring_dimension(), parameters.lut_step());
let lut = init_xor_lut(parameters.ring_dimension(), self.ek.lut_step());

self.bootstrap(sub, lut)
}
Expand All @@ -263,7 +272,7 @@ impl<C: LWEModulusType, Q: NTTField> Evaluator<C, Q> {
let mut sub = c0.sub_reduce_component_wise_ref(c1, lwe_modulus);
sub.scalar_mul_reduce_inplace(C::TWO, lwe_modulus);

let lut = init_xnor_lut(parameters.ring_dimension(), parameters.lut_step());
let lut = init_xnor_lut(parameters.ring_dimension(), self.ek.lut_step());

self.bootstrap(sub, lut)
}
Expand All @@ -289,7 +298,7 @@ impl<C: LWEModulusType, Q: NTTField> Evaluator<C, Q> {
let mut add = c0.add_reduce_component_wise_ref(c1, lwe_modulus);
add.add_reduce_inplace_component_wise(c2, lwe_modulus);

let lut = init_and_majority_lut(parameters.ring_dimension(), parameters.lut_step());
let lut = init_and_majority_lut(parameters.ring_dimension(), self.ek.lut_step());

self.bootstrap(add, lut)
}
Expand Down Expand Up @@ -319,7 +328,7 @@ impl<C: LWEModulusType, Q: NTTField> Evaluator<C, Q> {
// (a & b) | (!a & c)
t0.add_reduce_inplace_component_wise(&t1, lwe_modulus);

let lut = init_or_lut(parameters.ring_dimension(), parameters.lut_step());
let lut = init_or_lut(parameters.ring_dimension(), self.ek.lut_step());

self.bootstrap(t0, lut)
}
Expand Down
5 changes: 1 addition & 4 deletions bool/src/bfhe/parameters.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use algebra::Field;
use fhe_core::{
BlindRotationType, ConstParameters, DefaultFieldU32, LWESecretKeyType, Parameters,
RingSecretKeyType, Steps,
ConstParameters, DefaultFieldU32, LWESecretKeyType, Parameters, RingSecretKeyType, Steps,
};
use once_cell::sync::Lazy;

Expand All @@ -14,7 +13,6 @@ pub static DEFAULT_TERNARY_128_BITS_PARAMETERS: Lazy<Parameters<u16, DefaultFiel
lwe_plain_modulus: 4,
lwe_noise_standard_deviation: 3.20,
lwe_secret_key_type: LWESecretKeyType::Ternary,
blind_rotation_type: BlindRotationType::RLWE,
ring_dimension: 1024,
ring_modulus: DefaultFieldU32::MODULUS_VALUE,
ring_noise_standard_deviation: 3.20 * ((1 << 1) as f64),
Expand All @@ -36,7 +34,6 @@ pub static CUSTOM_TERNARY_128_BITS_PARAMETERS: Lazy<Parameters<u16, DefaultField
lwe_plain_modulus: 4,
lwe_noise_standard_deviation: 3.20,
lwe_secret_key_type: LWESecretKeyType::Ternary,
blind_rotation_type: BlindRotationType::RLWE,
ring_dimension: 1024,
ring_modulus: DefaultFieldU32::MODULUS_VALUE,
ring_noise_standard_deviation: 3.20 * ((1 << 1) as f64),
Expand Down
6 changes: 0 additions & 6 deletions fhe_core/src/ciphertext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,3 @@ pub type RLWECiphertext<F> = lattice::RLWE<F>;

/// NTT version RLWE Ciphertext
pub type NTTRLWECiphertext<F> = lattice::NTTRLWE<F>;

/// NTRU Ciphertext
pub type NTRUCiphertext<F> = lattice::NTRU<F>;

/// NTT version NTRU Ciphertext
pub type NTTNTRUCiphertext<F> = lattice::NTTNTRU<F>;
File renamed without changes.
67 changes: 11 additions & 56 deletions fhe_core/src/key_switch/rlwe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ use std::slice::ChunksExact;
use algebra::{Basis, NTTField, NTTPolynomial, Polynomial};
use lattice::{DecompositionSpace, NTTGadgetRLWE, PolynomialSpace, LWE, NTTRLWE, RLWE};

use crate::{LWEModulusType, NTRUCiphertext, SecretKeyPack};

#[derive(Debug, Clone, Copy)]
enum Operation {
AddAMulS,
SubAMulS,
}
use crate::{LWEModulusType, SecretKeyPack};

/// The Key Switching Key.
///
Expand Down Expand Up @@ -145,30 +139,7 @@ impl<Q: NTTField> KeySwitchingRLWEKey<Q> {

let iter = ciphertext.a_slice().chunks_exact(extended_lwe_dimension);

self.key_switch_inner(extended_lwe_dimension, init, iter, Operation::SubAMulS)
}

/// Performs key switching operation.
pub fn key_switch_for_ntru(&self, mut ciphertext: NTRUCiphertext<Q>) -> LWE<Q> {
let extended_lwe_dimension = self.lwe_dimension.next_power_of_two();

// Because the lwe ciphertext extracted from a ntru ciphertext always has `b = 0`.
let init = <NTTRLWE<Q>>::zero(extended_lwe_dimension);

if ciphertext.as_slice().len() != extended_lwe_dimension {
let a = ciphertext.as_mut_slice();
a[0] = -a[0];
a[1..].reverse();
a.chunks_exact_mut(extended_lwe_dimension)
.for_each(|chunk| {
chunk[0] = -chunk[0];
chunk[1..].reverse();
});
}

let iter = ciphertext.as_slice().chunks_exact(extended_lwe_dimension);

self.key_switch_inner(extended_lwe_dimension, init, iter, Operation::AddAMulS)
self.key_switch_inner(extended_lwe_dimension, init, iter)
}

/// Performs key switching operation.
Expand All @@ -195,43 +166,27 @@ impl<Q: NTTField> KeySwitchingRLWEKey<Q> {

let iter = ciphertext.a().chunks_exact(extended_lwe_dimension);

self.key_switch_inner(extended_lwe_dimension, init, iter, Operation::SubAMulS)
self.key_switch_inner(extended_lwe_dimension, init, iter)
}

fn key_switch_inner(
&self,
extended_lwe_dimension: usize,
mut init: NTTRLWE<Q>,
iter: ChunksExact<Q>,
op: Operation,
) -> LWE<Q> {
let mut polynomial_space = PolynomialSpace::new(extended_lwe_dimension);
let mut decompose_space = DecompositionSpace::new(extended_lwe_dimension);

match op {
Operation::AddAMulS => {
self.key.iter().zip(iter).for_each(|(k_i, a_i)| {
polynomial_space.copy_from(a_i);
self.key.iter().zip(iter).for_each(|(k_i, a_i)| {
polynomial_space.copy_from(a_i);

init.add_assign_gadget_rlwe_mul_polynomial_inplace_fast(
k_i,
&mut polynomial_space,
&mut decompose_space,
);
});
}
Operation::SubAMulS => {
self.key.iter().zip(iter).for_each(|(k_i, a_i)| {
polynomial_space.copy_from(a_i);

init.sub_assign_gadget_rlwe_mul_polynomial_inplace_fast(
k_i,
&mut polynomial_space,
&mut decompose_space,
);
});
}
}
init.sub_assign_gadget_rlwe_mul_polynomial_inplace_fast(
k_i,
&mut polynomial_space,
&mut decompose_space,
);
});

<RLWE<Q>>::from(init).extract_partial_lwe_locally(self.lwe_dimension)
}
Expand Down
9 changes: 2 additions & 7 deletions fhe_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,9 @@ pub mod utils;

pub use error::FHECoreError;

pub use parameter::{
BlindRotationType, ConstParameters, DefaultFieldU32, DefaultQks, Parameters,
ProcessBeforeBlindRotation, ProcessType, Steps,
};
pub use parameter::{ConstParameters, DefaultFieldU32, DefaultQks, Parameters, Steps};

pub use ciphertext::{
LWECiphertext, NTRUCiphertext, NTTNTRUCiphertext, NTTRLWECiphertext, RLWECiphertext,
};
pub use ciphertext::{LWECiphertext, NTTRLWECiphertext, RLWECiphertext};
pub use plaintext::{decode, encode, LWEModulusType, LWEMsgType};

pub use secret_key::{
Expand Down
Loading