Skip to content

Commit

Permalink
Fixed an issue related to correction factors.
Browse files Browse the repository at this point in the history
  • Loading branch information
Wei Dai committed Mar 17, 2022
1 parent 8c82bf7 commit e4462eb
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 27 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ Microsoft SEAL itself has a steep learning curve and requires the user to unders
Even if a user is able to program and run a specific computation using Microsoft SEAL, the difference between efficient and inefficient implementations can be several orders of magnitude, and it can be hard for new users to know how to improve the performance of their computation.

Microsoft SEAL comes with two different homomorphic encryption schemes with very different properties.
The BFV scheme allows modular arithmetic to be performed on encrypted integers.
The BFV and BGV schemes allow modular arithmetic to be performed on encrypted integers.
The CKKS scheme allows additions and multiplications on encrypted real or complex numbers, but yields only approximate results.
In applications such as summing up encrypted real numbers, evaluating machine learning models on encrypted data, or computing distances of encrypted locations CKKS is going to be by far the best choice.
For applications where exact values are necessary, the BFV scheme is the only choice.
For applications where exact values are necessary, the BFV and BGV schemes are more suitable.

## Getting Started

Expand Down Expand Up @@ -216,7 +216,7 @@ EVA allows programmers to express desired encrypted computations in Python. It o
EVA is available at [GitHub.com/Microsoft/EVA](https://GitHub.com/Microsoft/EVA).
Try it out, and let us know what you think!

**Note:** EVA only supports the CKKS scheme. There are no immediate plans to support the BFV scheme.
**Note:** EVA only supports the CKKS scheme. There are no immediate plans to support the BFV or BGV scheme.

## Building Microsoft SEAL Manually

Expand Down
51 changes: 27 additions & 24 deletions native/src/seal/evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,42 +194,42 @@ namespace seal
throw logic_error("invalid parameters");
}

// Prepare destination
encrypted1.resize(context_, context_data.parms_id(), max_count);

if (encrypted1.correction_factor() != encrypted2.correction_factor())
{
// Balance correction factors and multiply by scalars before addition in BGV
auto factors = balance_correction_factors(
encrypted1.correction_factor(), encrypted2.correction_factor(), plain_modulus);

multiply_poly_scalar_coeffmod(
ConstPolyIter(encrypted1.data(), coeff_count, coeff_modulus_size), encrypted1.size(), get<1>(factors),
coeff_modulus, PolyIter(encrypted1.data(), coeff_count, coeff_modulus_size));

Ciphertext encrypted2_copy = encrypted2;
multiply_poly_scalar_coeffmod(
ConstPolyIter(encrypted2.data(), coeff_count, coeff_modulus_size), encrypted2.size(), get<2>(factors),
coeff_modulus, PolyIter(encrypted2_copy.data(), coeff_count, coeff_modulus_size));

// Set new correction factor
encrypted1.correction_factor() = get<0>(factors);
encrypted2_copy.correction_factor() = get<0>(factors);

// Add ciphertexts
add_poly_coeffmod(encrypted1, encrypted2_copy, min_count, coeff_modulus, encrypted1);
add_inplace(encrypted1, encrypted2_copy);
}
else
{
// Prepare destination
encrypted1.resize(context_, context_data.parms_id(), max_count);
// Add ciphertexts
add_poly_coeffmod(encrypted1, encrypted2, min_count, coeff_modulus, encrypted1);
}

// Copy the remainding polys of the array with larger count into encrypted1
if (encrypted1_size < encrypted2_size)
{
set_poly_array(
encrypted2.data(min_count), encrypted2_size - encrypted1_size, coeff_count, coeff_modulus_size,
encrypted1.data(encrypted1_size));
// Copy the remainding polys of the array with larger count into encrypted1
if (encrypted1_size < encrypted2_size)
{
set_poly_array(
encrypted2.data(min_count), encrypted2_size - encrypted1_size, coeff_count, coeff_modulus_size,
encrypted1.data(encrypted1_size));
}
}

#ifdef SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT
// Transparent ciphertext output is not allowed.
if (encrypted1.is_transparent())
Expand Down Expand Up @@ -302,9 +302,6 @@ namespace seal
throw logic_error("invalid parameters");
}

// Prepare destination
encrypted1.resize(context_, context_data.parms_id(), max_count);

if (encrypted1.correction_factor() != encrypted2.correction_factor())
{
// Balance correction factors and multiply by scalars before subtraction in BGV
Expand All @@ -314,29 +311,35 @@ namespace seal
multiply_poly_scalar_coeffmod(
ConstPolyIter(encrypted1.data(), coeff_count, coeff_modulus_size), encrypted1.size(), get<1>(factors),
coeff_modulus, PolyIter(encrypted1.data(), coeff_count, coeff_modulus_size));

Ciphertext encrypted2_copy = encrypted2;
multiply_poly_scalar_coeffmod(
ConstPolyIter(encrypted2.data(), coeff_count, coeff_modulus_size), encrypted2.size(), get<2>(factors),
coeff_modulus, PolyIter(encrypted2_copy.data(), coeff_count, coeff_modulus_size));

// Set new correction factor
encrypted1.correction_factor() = get<0>(factors);
encrypted2_copy.correction_factor() = get<0>(factors);

// Subtract ciphertexts
sub_poly_coeffmod(encrypted1, encrypted2_copy, min_count, coeff_modulus, encrypted1);
sub_inplace(encrypted1, encrypted2_copy);
}
else
{
// Prepare destination
encrypted1.resize(context_, context_data.parms_id(), max_count);

// Subtract ciphertexts
sub_poly_coeffmod(encrypted1, encrypted2, min_count, coeff_modulus, encrypted1);
}

// If encrypted2 has larger count, negate remaining entries
if (encrypted1_size < encrypted2_size)
{
negate_poly_coeffmod(
iter(encrypted2) + min_count, encrypted2_size - min_count, coeff_modulus, iter(encrypted1) + min_count);
// If encrypted2 has larger count, negate remaining entries
if (encrypted1_size < encrypted2_size)
{
negate_poly_coeffmod(
iter(encrypted2) + min_count, encrypted2_size - min_count, coeff_modulus,
iter(encrypted1) + min_count);
}
}

#ifdef SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT
// Transparent ciphertext output is not allowed.
if (encrypted1.is_transparent())
Expand Down

0 comments on commit e4462eb

Please sign in to comment.