Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: mod_switch_to_next throws transparent ciphertext exception when using CKKS #179

Closed
s0l0ist opened this issue May 31, 2020 · 1 comment

Comments

@s0l0ist
Copy link
Contributor

s0l0ist commented May 31, 2020

Hello all,

An exception is thrown (erroneously) when attempting to perform a modulus switch on a ciphertext when using the overload accepting a destination parameter: evaluator.mod_switch_to_next

This appears to occur when using the CKKS scheme.

Example C++ code:

int main()
{
    std::cout << "Running main..." << std::endl;
    EncryptionParameters parms(scheme_type::CKKS);
    size_t poly_modulus_degree = 4096;
    parms.set_poly_modulus_degree(poly_modulus_degree);
    parms.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));
    //parms.set_plain_modulus(786433);
    auto context = SEALContext::Create(parms);
    KeyGenerator keygen(context);
    PublicKey public_key = keygen.public_key();
    SecretKey secret_key = keygen.secret_key();
    CKKSEncoder ckks_encoder(context);
    Encryptor encryptor(context, public_key);
    Evaluator evaluator(context);
    Decryptor decryptor(context, secret_key);

    size_t slot_count = ckks_encoder.slot_count();
    vector<double> vect(slot_count, 3.3);

    Plaintext plain;
    ckks_encoder.encode(vect, pow(2.0, 24), plain);

    Ciphertext cipher, cipher_dest;
    encryptor.encrypt(plain, cipher);

    try {
        std::cout << "Attempting to switch modulus..." << std::endl;
        evaluator.mod_switch_to_next(cipher, cipher_dest); // <---- throws "result ciphertext is transparent"
        // evaluator.mod_switch_to_next_inplace(cipher); // <---- works

        // This code never gets executed unless the `inplace` method is used instead
        Plaintext plain_result;
        decryptor.decrypt(cipher_dest, plain_result);

        vector<double> vect_result;
        ckks_encoder.decode(plain_result, vect_result);

        std::cout << "Result [0]: " << vect_result[0] << std::endl;
    }
    catch (exception& e) {
        std::cout << "An exception occurred: " << e.what() << std::endl;
    }
    return 0;
}

Build settings:

cmake \
  -DSEAL_USE_CXX17=ON \
  -DSEAL_USE_INTRIN=OFF \
  -DSEAL_USE_ZLIB=ON \
  -DSEAL_USE_MSGSL=ON \
  -DSEAL_BUILD_EXAMPLES=OFF \
  -DSEAL_BUILD_TESTS=OFF \
  -DBUILD_SHARED_LIBS=OFF \
  -DCMAKE_BUILD_TYPE=Release \
  .
@kimlaine
Copy link
Contributor

Thanks for reporting this immediately. There was a mistake in a variadic lambda function resolving argument to "wrong" type -- oops. While looking into this, I noticed another bug in util::IterTuple that I fixed as well. I'll put out 3.5.3 right away with these fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants