zama-ai / tfhe-rs

TFHE-rs: A Pure Rust implementation of the TFHE Scheme for Boolean and Integer Arithmetics Over Encrypted Data.
Other
917 stars 142 forks source link

Performing WoPBS with ciphertext a trivial encryption of zero fails #1010

Closed Juul-Mc-Goa closed 6 months ago

Juul-Mc-Goa commented 6 months ago

Describe the bug Trying to perform pbs with ciphertext being a trivial encryption of zero panics.

To Reproduce Steps to reproduce the behaviour:

  1. Using the integer API, create a WopbsKey, then call generate_lut_radix() with that key,
  2. Apply the WopbsKey::wopbs() method with the lut and a trivial encryption of zero as ciphertext,

Expected behaviour The wopbs() method returns (an encryption of) the lookup table at index zero.

Evidence Here's a minimal example:

use tfhe::{
    integer::{gen_keys_radix, wopbs::WopbsKey, RadixCiphertext, RadixClientKey, ServerKey},
    shortint::{
        parameters::parameters_wopbs_message_carry::WOPBS_PARAM_MESSAGE_2_CARRY_2_KS_PBS,
        prelude::PARAM_MESSAGE_2_CARRY_2_KS_PBS,
    },
};

fn generate_keys() -> (RadixClientKey, ServerKey, WopbsKey) {
    let (ck, sk) = gen_keys_radix(PARAM_MESSAGE_2_CARRY_2_KS_PBS, 16);
    let wopbs_key = WopbsKey::new_wopbs_key(&ck, &sk, &WOPBS_PARAM_MESSAGE_2_CARRY_2_KS_PBS);
    (ck, sk, wopbs_key)
}

fn main() {
    let (ck, sk, wopbs_key) = generate_keys();
    let ct_max_arg: RadixCiphertext = sk.create_trivial_radix(8u64, 4);
    let f = |x: u64| -> u64 { 5 + x };
    let lut = wopbs_key.generate_lut_radix(&ct_max_arg, f);
    let apply_lut = |encrypted_id: &RadixCiphertext| -> RadixCiphertext {
        let ct = wopbs_key.keyswitch_to_wopbs_params(&sk, encrypted_id);
        let ct_res = wopbs_key.wopbs(&ct, &lut);
        wopbs_key.keyswitch_to_pbs_params(&ct_res)
    };
    let lut_at_2 = apply_lut(&sk.create_trivial_radix(2u64, 4)); // succeeds
    assert_eq!(ck.decrypt::<u64>(&lut_at_2), 7);
    let lut_at_1 = apply_lut(&sk.create_trivial_radix(1u64, 4)); // succeeds
    assert_eq!(ck.decrypt::<u64>(&lut_at_1), 6);
    let lut_at_0 = apply_lut(&sk.create_trivial_radix(0u64, 4)); // fails with obscure error
    println!("{}", ck.decrypt::<u64>(&lut_at_0));
}

And here's the error:

thread 'main' panicked at /home/juul_mc_goa/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tfhe-0.5.3/src/core_crypto/fft_impl/fft64/crypto/wop_pbs/mod.rs:672:5:
Got empty `lwe_list_in`

Configuration(please complete the following information):

Additional context The issue may be caused by:

  1. trivial encryptions of zero being optimized as pointed out by this comment,
  2. PBS requiring the input bit-width to be the same as the output bit-width as mentioned in the same thread.
IceTDrinker commented 6 months ago

thanks for following up here

IceTDrinker commented 6 months ago

@Juul-Mc-Goa you are hitting a debug assert try running with --release and tell me if it works, if so the debug assert is not necessary and we'll remove it

Juul-Mc-Goa commented 6 months ago

@IceTDrinker just runned with --release and indeed, it works.

IceTDrinker commented 6 months ago

Thanks for confirming, also release will be much much faster than than debug builds