Skip to content

Commit

Permalink
chore(integer): addition test based on trivial inputs
Browse files Browse the repository at this point in the history
This adds `overflowing_add` and `add` tests that
are on trivial inputs. As these are faster to run they
can be more extensive than on true encryptions

This also binds the advanced_add_assign functions tests
to include overflow computation

On a standard laptop with 1 test thread it takes ~7 minutes
to run these trivial tests
  • Loading branch information
tmontaigu committed Aug 21, 2024
1 parent 358bcc9 commit d39c35c
Show file tree
Hide file tree
Showing 5 changed files with 537 additions and 109 deletions.
10 changes: 5 additions & 5 deletions tfhe/src/integer/server_key/radix_parallel/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(crate) enum OutputFlag {
/// Request no flag at all
None,
/// The overflow flag is the flag that tells whether the input carry bit onto the last bit
/// is different than the output bit.
/// is different from the output bit.
///
/// This is useful to know if a signed addition overflowed (in 2's complement)
Overflow,
Expand Down Expand Up @@ -666,18 +666,18 @@ impl ServerKey {
if num_blocks == 1 && input_carry.is_some() {
self.key
.unchecked_add_assign(block, input_carry.map(|b| &b.0).unwrap());
} else {
} else if num_blocks > 1 {
self.key.unchecked_add_assign(block, &carry);
}
}

// To be able to use carry_extract_assign in it
carry.clone_from(&lhs[num_blocks - 1]);

// Note that here when num_blocks == 1 && requested_flag != Overflow nothing
// will actually be spawned.
rayon::scope(|s| {
if num_blocks >= 2 {
// To be able to use carry_extract_assign in it
carry.clone_from(&lhs[num_blocks - 1]);

// These would already have been done when the first block was processed
s.spawn(|_| {
self.key.message_extract_assign(&mut lhs[num_blocks - 1]);
Expand Down
19 changes: 10 additions & 9 deletions tfhe/src/integer/server_key/radix_parallel/tests_signed/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub(crate) mod test_shift;
pub(crate) mod test_sub;
pub(crate) mod test_vector_comparisons;

use crate::core_crypto::prelude::SignedInteger;
use crate::integer::keycache::KEY_CACHE;
use crate::integer::server_key::radix_parallel::tests_cases_unsigned::FunctionExecutor;
use crate::integer::server_key::radix_parallel::tests_unsigned::{
Expand Down Expand Up @@ -807,7 +808,7 @@ fn integer_signed_default_scalar_div_rem(param: impl Into<PBSParameters>) {
// Helper functions
//================================================================================

pub(crate) fn signed_add_under_modulus(lhs: i64, rhs: i64, modulus: i64) -> i64 {
pub(crate) fn signed_add_under_modulus<T: SignedInteger>(lhs: T, rhs: T, modulus: T) -> T {
signed_overflowing_add_under_modulus(lhs, rhs, modulus).0
}

Expand All @@ -816,12 +817,12 @@ pub(crate) fn signed_add_under_modulus(lhs: i64, rhs: i64, modulus: i64) -> i64
// This is to 'simulate' i8, i16, ixy using i64 integers
//
// lhs and rhs must be in [-modulus..modulus[
pub(crate) fn signed_overflowing_add_under_modulus(
lhs: i64,
rhs: i64,
modulus: i64,
) -> (i64, bool) {
assert!(modulus > 0);
pub(crate) fn signed_overflowing_add_under_modulus<T: SignedInteger>(
lhs: T,
rhs: T,
modulus: T,
) -> (T, bool) {
assert!(modulus > T::ZERO);
assert!((-modulus..modulus).contains(&lhs));

// The code below requires rhs and lhs to be in range -modulus..modulus
Expand All @@ -831,14 +832,14 @@ pub(crate) fn signed_overflowing_add_under_modulus(
(lhs + rhs, false)
} else {
// 2*modulus to get all the bits
(lhs + (rhs % (2 * modulus)), true)
(lhs + (rhs % (T::TWO * modulus)), true)
};

if res < -modulus {
// rem_euclid(modulus) would also work
res = modulus + (res - -modulus);
overflowed = true;
} else if res > modulus - 1 {
} else if res > modulus - T::ONE {
res = -modulus + (res - modulus);
overflowed = true;
}
Expand Down
Loading

0 comments on commit d39c35c

Please sign in to comment.