Skip to content

Complex-values Bootstrapping #11

@lawrencekhlim

Description

@lawrencekhlim

Dear authors of FIDESlib,

I have few questions regarding bootstrapping: I wanted to support complex-values in my application using FIDESlib. I noticed that OpenFHE only supported complex values starting in version 1.3.0, which is the version right after FIDESlib interoperates with OpenFHE, which is version 1.2.4. So at the commit where complex values were supported in OpenFHE, I tweaked it to be compatible with FIDESlib. You can see my modifications to OpenFHE here. There are a few minor tweaks to FIDESlib as well to enable compilation. (I am happy to share them with you if you are interested.)

This mostly worked, and I was able to get additions, multiplications, rotations, and conjugations on complex-values with FIDESlib to work. However, I was only able to somewhat get bootstrapping to work. I say somewhat because some configurations of parameters work while other do not. As far as I can tell, between OpenFHE version 1.2.4 and the commit that added complex-valued support, not much is changed about bootstrapping (but I may be wrong), so it's puzzling to me that it sometimes works but other times does not.

My main questions are:

  1. What should we modify about FIDESlib to get complex-valued support for bootstrapping?
  2. What are the main differences between the OpenFHE's bootstrapping (on version 1.2.4) and FIDESlib's bootstrapping?

Here are some parameters that I've tested (all of the below work on OpenFHE with little error):

This one has bootstrapping working correctly:

    constexpr uint32_t ring_dim = 1 << 16;
    constexpr uint32_t num_slots = ring_dim / 2;
    const std::vector<uint32_t> level_budget = {3, 3};

    constexpr uint32_t scale_mod_size = 59;
    constexpr uint32_t first_mod = 60;
    constexpr uint32_t num_large_digits = 5;

    lbcrypto::CCParams<lbcrypto::CryptoContextCKKSRNS> parameters;
    parameters.SetScalingModSize(scale_mod_size);
    parameters.SetFirstModSize(first_mod);
    parameters.SetRingDim(ring_dim);
    parameters.SetBatchSize(num_slots); 
    parameters.SetSecurityLevel(lbcrypto::HEStd_NotSet);
    parameters.SetScalingTechnique(lbcrypto::FLEXIBLEAUTO);
    parameters.SetNumLargeDigits(num_large_digits);
    parameters.SetCKKSDataType(lbcrypto::COMPLEX);

    // Default secret key distribution.
    // parameters.SetSecretKeyDist(secretKeyDist);

    // Parámetros bootstrap.
    constexpr uint32_t levelsAvailableAfterBootstrap = 12;

    usint depth = levelsAvailableAfterBootstrap + lbcrypto::FHECKKSRNS::GetBootstrapDepth(level_budget, parameters.GetSecretKeyDist());
    parameters.SetMultiplicativeDepth(depth);

But set the secret key distribution to sparse ternary, and it does not decrypt properly.

auto secretKeyDist = lbcrypto::SecretKeyDist::SPARSE_TERNARY;
parameters.SetSecretKeyDist(secretKeyDist);

Setting the modulus sizes to be smaller with the default secret key distribution also does not decrypt properly (but this one is at least within an order of magnitude):

    constexpr uint32_t scale_mod_size = 49;
    constexpr uint32_t first_mod = 52;

    // Later    

    // Default secret key distribution.
    // parameters.SetSecretKeyDist(secretKeyDist);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions