SEAL
SEAL copied to clipboard
[Bugs] Undefined behaviour occurs in ckks scheme
/usr/local/include/SEAL-4.1/seal/ckks.h:512:56: runtime error: inf is outside the range of representable values of type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/local/include/SEAL-4.1/seal/ckks.h:512:56 in
/usr/local/include/SEAL-4.1/seal/ckks.h:534:71: runtime error: inf is outside the range of representable values of type 'unsigned long'
Both of these bugs appear to be caused by numerical issues. In one case, a boundary check is performed, but an overflow still passes the check, which could potentially lead to serious consequences.
My CMake flags are:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O1 -fsanitize=address,undefined,signed-integer-overflow -fno-omit-frame-pointer")
I found two bugs that causes overflow in CKKS mode. The MWE is as follows:
#include "seal/ckks.h"
#include "seal/context.h"
#include "seal/modulus.h"
#include <vector>
#include <complex>
using namespace seal;
using namespace seal::util;
int main() {
size_t slots = 16;
std::vector<std::complex<double>> values = {
{-8.01058e-113, 0.0},
{1.75577e-305, 0.0},
{-8.01058e-113, 0.0},
{-8.45655e-116, 0.0},
{-8.01058e-113, 0.0},
{-8.65801e+306, 0.0},
{3.09548e+267, 0.0},
{3.02669e+267, 0.0},
{3.02669e+267, 0.0},
{-9.36336e-97, 0.0},
{-1.67792e-93, 0.0},
{1.48447e-308, 0.0},
{2.122e-313, 0.0},
{3.23791e-318, 0.0},
{1.3961e-308, 0.0},
{2.12203e-313, 0.0}
};
EncryptionParameters parms(scheme_type::ckks);
parms.set_poly_modulus_degree(slots << 1);
bool use_40bit_primes = 1;
if (use_40bit_primes) {
parms.set_coeff_modulus(CoeffModulus::Create(slots << 1, {40, 40, 40, 40}));
} else {
parms.set_coeff_modulus(CoeffModulus::Create(slots << 1, {60, 60, 60}));
}
SEALContext context(parms, false, sec_level_type::none);
CKKSEncoder encoder(context);
double delta = 1 << 16;
Plaintext plain;
encoder.encode(values, context.first_parms_id(), delta, plain);
std::vector<std::complex<double>> result;
encoder.decode(plain, result);
for (size_t i = 0; i < slots; ++i) {
if (std::abs(values[i].real() - result[i].real()) >= 0.5) {
abort();
}
}
return 0;
}
Thanks for reporting this!! Were you able to create a fix? If so, please submit a PR.
Of couse. I will submit a PR soon!