Skip to content

Commit

Permalink
chore(core): fix noise generation which could overflow the custom mod…
Browse files Browse the repository at this point in the history
…ulus

- updated some function name (for modulus checking) to be clearer on what
they do and when to use them
  • Loading branch information
IceTDrinker committed Nov 15, 2023
1 parent 0453b9b commit 6d8f5cf
Show file tree
Hide file tree
Showing 28 changed files with 645 additions and 229 deletions.
37 changes: 36 additions & 1 deletion tfhe/src/core_crypto/algorithms/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,30 @@ pub fn torus_modular_diff<T: UnsignedInteger>(
}
}

/// Compute the distance over the torus, taking the absolute value of the smallest distance between
/// two torus values.
pub fn modular_distance<T: UnsignedInteger>(first: T, other: T) -> T {
let d0 = first.wrapping_sub(other);
let d1 = other.wrapping_sub(first);
d0.min(d1)
}

/// Compute the distance over the torus, taking the absolute value of the smallest distance between
/// two torus values, considering a non native modulus.
///
/// # Note
///
/// first and other must already be in `0..custom_modulus`.
pub fn modular_distance_custom_mod<T: UnsignedInteger>(first: T, other: T, custom_modulus: T) -> T {
let d0 = first.wrapping_sub_custom_mod(other, custom_modulus);
let d1 = other.wrapping_sub_custom_mod(first, custom_modulus);
d0.min(d1)
}

// Our representation of non native power of 2 moduli puts the information in the MSBs and leaves
// the LSBs empty, this is what this function is checking
pub fn check_content_respects_mod<Scalar: UnsignedInteger, Input: AsRef<[Scalar]>>(
#[track_caller]
pub fn check_encrypted_content_respects_mod<Scalar: UnsignedInteger, Input: AsRef<[Scalar]>>(
input: &Input,
modulus: CiphertextModulus<Scalar>,
) -> bool {
Expand All @@ -132,6 +153,20 @@ pub fn check_content_respects_mod<Scalar: UnsignedInteger, Input: AsRef<[Scalar]
}
}

#[track_caller]
pub fn check_clear_content_respects_mod<Scalar: UnsignedInteger, Input: AsRef<[Scalar]>>(
input: &Input,
modulus: CiphertextModulus<Scalar>,
) -> bool {
if modulus.is_native_modulus() {
true
} else {
let scalar_modulus: Scalar = modulus.get_custom_modulus().cast_into();

input.as_ref().iter().all(|&x| x < scalar_modulus)
}
}

/// This function converts an unsigned integer to a float value but does so selecting the truncated
/// value of the input integer, meaning it will not try to round to the closest representable
/// integer by the floating point type, it will always select the closest representable integer by
Expand Down
20 changes: 16 additions & 4 deletions tfhe/src/core_crypto/algorithms/test/ggsw_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,10 @@ fn ggsw_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Sca
&mut rsc.encryption_random_generator,
);

assert!(check_content_respects_mod(&ggsw, ciphertext_modulus));
assert!(check_encrypted_content_respects_mod(
&ggsw,
ciphertext_modulus
));

let decoded = decrypt_constant_ggsw_ciphertext(&glwe_sk, &ggsw);

Expand Down Expand Up @@ -285,7 +288,10 @@ fn ggsw_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Send + Sync>(
&mut rsc.encryption_random_generator,
);

assert!(check_content_respects_mod(&ggsw, ciphertext_modulus));
assert!(check_encrypted_content_respects_mod(
&ggsw,
ciphertext_modulus
));

let decoded = decrypt_constant_ggsw_ciphertext(&glwe_sk, &ggsw);

Expand Down Expand Up @@ -348,7 +354,10 @@ fn ggsw_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar

let ggsw = seeded_ggsw.decompress_into_ggsw_ciphertext();

assert!(check_content_respects_mod(&ggsw, ciphertext_modulus));
assert!(check_encrypted_content_respects_mod(
&ggsw,
ciphertext_modulus
));

let decoded = decrypt_constant_ggsw_ciphertext(&glwe_sk, &ggsw);

Expand Down Expand Up @@ -413,7 +422,10 @@ fn ggsw_seeded_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Sync + Sen

let ggsw = seeded_ggsw.decompress_into_ggsw_ciphertext();

assert!(check_content_respects_mod(&ggsw, ciphertext_modulus));
assert!(check_encrypted_content_respects_mod(
&ggsw,
ciphertext_modulus
));

let decoded = decrypt_constant_ggsw_ciphertext(&glwe_sk, &ggsw);

Expand Down
34 changes: 26 additions & 8 deletions tfhe/src/core_crypto/algorithms/test/glwe_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ fn glwe_encrypt_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar
&mut rsc.encryption_random_generator,
);

assert!(check_content_respects_mod(&glwe, ciphertext_modulus));
assert!(check_encrypted_content_respects_mod(
&glwe,
ciphertext_modulus
));

let mut plaintext_list =
PlaintextList::new(Scalar::ZERO, PlaintextCount(glwe.polynomial_size().0));
Expand Down Expand Up @@ -101,7 +104,10 @@ fn glwe_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Sca
&mut rsc.encryption_random_generator,
);

assert!(check_content_respects_mod(&glwe, ciphertext_modulus));
assert!(check_encrypted_content_respects_mod(
&glwe,
ciphertext_modulus
));

let mut plaintext_list =
PlaintextList::new(Scalar::ZERO, PlaintextCount(glwe.polynomial_size().0));
Expand Down Expand Up @@ -168,7 +174,10 @@ fn glwe_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParam
&mut rsc.encryption_random_generator,
);

assert!(check_content_respects_mod(&glwe_list, ciphertext_modulus));
assert!(check_encrypted_content_respects_mod(
&glwe_list,
ciphertext_modulus
));

let mut plaintext_list = PlaintextList::new(
Scalar::ZERO,
Expand Down Expand Up @@ -226,7 +235,10 @@ fn glwe_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPa

trivially_encrypt_glwe_ciphertext(&mut glwe, &plaintext_list);

assert!(check_content_respects_mod(&glwe, ciphertext_modulus));
assert!(check_encrypted_content_respects_mod(
&glwe,
ciphertext_modulus
));

let mut plaintext_list =
PlaintextList::new(Scalar::ZERO, PlaintextCount(glwe.polynomial_size().0));
Expand Down Expand Up @@ -280,7 +292,10 @@ fn glwe_allocate_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
ciphertext_modulus,
);

assert!(check_content_respects_mod(&ct, ciphertext_modulus));
assert!(check_encrypted_content_respects_mod(
&ct,
ciphertext_modulus
));

let mut output_plaintext_list =
PlaintextList::new(Scalar::ZERO, PlaintextCount(polynomial_size.0));
Expand Down Expand Up @@ -341,11 +356,14 @@ fn glwe_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar
rsc.seeder.as_mut(),
);

assert!(check_content_respects_mod(&seeded_glwe, ciphertext_modulus));
assert!(check_encrypted_content_respects_mod(
&seeded_glwe,
ciphertext_modulus
));

let decompressed_glwe = seeded_glwe.decompress_into_glwe_ciphertext();

assert!(check_content_respects_mod(
assert!(check_encrypted_content_respects_mod(
&decompressed_glwe,
ciphertext_modulus
));
Expand Down Expand Up @@ -418,7 +436,7 @@ fn glwe_seeded_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Te
rsc.seeder.as_mut(),
);

assert!(check_content_respects_mod(
assert!(check_encrypted_content_respects_mod(
&glwe_seeded_list,
ciphertext_modulus
));
Expand Down
Loading

0 comments on commit 6d8f5cf

Please sign in to comment.