SEAL icon indicating copy to clipboard operation
SEAL copied to clipboard

[Bugs] Undefined behaviour occurs in ckks scheme

Open Wowblk opened this issue 4 months ago • 2 comments

/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;
}

Wowblk avatar Sep 11 '25 19:09 Wowblk

Thanks for reporting this!! Were you able to create a fix? If so, please submit a PR.

kimlaine avatar Sep 12 '25 21:09 kimlaine

Of couse. I will submit a PR soon!

Wowblk avatar Sep 15 '25 03:09 Wowblk