Operators on integers in CRT encoding

Hello all,

I’m trying to add two integers encoded in CRT mode, the code is as follows:

use anyhow::Result;
use tfhe::{integer::{CrtClientKey, ServerKey}, shortint::parameters::PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS};

#[test]
fn test_unsigned_substraction() -> Result<()> {
    let moduli = vec![8, 9, 5];
    let ck = CrtClientKey::new(PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS, moduli);
    let (a, b) = (1, 2);
    let (mut ea, mut be) = (
        ck.encrypt(a as _), ck.encrypt(b as _)
    );
    let sk = ServerKey::new_crt_server_key(&ck);
    sk.is_crt_add_possible(&ea, &eb)?;
    // sk.smart_add(&mut ea, &mut eb);
    Ok(())
}

I still do not know where the errors come from (I’ve skimmed the source of tfhe-rs then it seems that CRT encoding is not supported with GPU) but I always got the abort at sk.is_crt_add_possible(&ea, &be) as

The degree (=16) should not exceed 15

Many thanks for any help.

Hello @tathanhdinh

What is most likely happening here is that the basis you use contains 9 meaning the max value is 8 for the encryption using CRT, when you use the 2_2 parameters which can contain at most 4 bits you get an error when the component for the modulus 9 is done as it could overflow (8 + 8 does not fit in 4 bits)

You can try larger parameters or change your basis to avoid overflowing the 2_2 parameters

Edit: also note CRT is not the encoding we would recommend most at this time

Cheers

1 Like

Thank you @IceTDrinker.

It is indeed the problem. I’ve changed le paramètre 2_2 par 3_3 then it works now. The following test passed:

fn test_unsigned_substraction() -> Result<()> {
    let moduli = vec![8, 9, 5];
    let ck = CrtClientKey::new(PARAM_GPU_MULTI_BIT_MESSAGE_3_CARRY_3_GROUP_3_KS_PBS, moduli);
    let (a, b) = (10, 200);
    let (mut ea, mut be) = (
        ck.encrypt(a as _), ck.encrypt(b as _)
    );
    let sk = ServerKey::new_crt_server_key(&ck);
    sk.is_crt_add_possible(&ea, &eb)?;
    let esum_ab = sk.smart_crt_add(&mut ea, &mut eb);
    assert_eq!(a + b, ck.decrypt(&esum_ab));
    Ok(())
}

Sorry for another question, how to make the server sk.smart_crt_add run under GPU? I’ve supposed that just using PARAM_GPU_... in client key generation is not suffisant?

GPU does not implement CRT primitives so it’s not really possible at the moment, you could try building some CRT primitives by using GPU integer primitives on singles block maybe, but it’s going to require work

1 Like