Accumulator in the programmable bootstrapping

Hi!

I’m playing around with bootstrapping explicitly by referring the example using core_crypto (by following “Core Crypto API” in your website)

My question here is that if the function(x) includes, for example, the logarithmic computation of f64 in the argument below will it be handled in encrypted data process?

    // Define accumulator
    let accumulator: GlweCiphertextOwned<u64> = generate_programmable_bootstrap_glwe_lut(
        POLY_SIZE,
        GLWE_DIMENSION.to_glwe_size(),
        message_modulus as usize,
        CIPHERTXT_MODULUS,
        delta,
        |x: u64| function(x),
    );

function(x) for example:

fn function(input: u64) -> u64 {
    let mut rng = rand::thread_rng();
    let u: f64 = rng.gen_range(0.0..5.0);

    return input + (u.log2() as u64);
}

I expected to take large execution time as it’s expected log2 of encrypted f64 but it wasn’t in the reality. So I’m wondering if it’s really handled in the way of homomorphic computations. How is it handled internally if this accumulator is populated into programmable_bootstrap_lwe_ciphertext() together with ciphertext?

BR//Takao

Hello,

The accumulator is a GLWE that contains values trivially encrypted (that is, the value are not encrypted, but just encoded)

The function you give to generate_programmable_bootstrap_glwe_lut is executed in clear, the values are encoded (but not encrypted) and stored into the GLWE

Its is the programmable bootstrap that will output a value that is encrypted based in the input ciphertext, the keys and the GLWE.

Hi, thanks for the reply. But does it really make sense? Input argument for the function (x or input) is ciphertext at the bootstrap execution. How is it possible to execute in advance and stored w/o it? How is it possible to execute the computation of ciphertext and cleartext? How do you guarantee the execution is protected/secured?

As you can see, the generate_programmable_bootstrap_glwe_lut does not take the actual ciphertext as input. It will evaluate the function you pass as argument over all possible values that a ciphertext could encrypt (this is the message_modulus argument), it will call function(x) for x in 0…message_modulus.

The results are stored in the accumulator, which acts as a lookup table, and then the PBS will
use this lookup table to retrieve homomorphically the result depending on the actual input ciphertext encrypted value