Compressing ciphertexts/keys

This document explains the mechanism and steps to compress ciphertext and keys.

TFHE-rs includes features to compress both keys and ciphertexts, reducing their storage and transmission sizes.

Most TFHE-rs entities contain random numbers generated by a Pseudo Random Number Generator (PRNG). Since a PRNG is deterministic, storing only the random seed used to generate those numbers preserves all necessary information. When decompressing the entity, using the same PRNG and the same seed will reconstruct the full chain of random values.

In TFHE-rs, compressible entities are prefixed with Compressed. For instance, a compressed FheUint256 is declared as CompressedFheUint256.

In the following example code, we use the bincode crate dependency to serialize in a binary format and compare serialized sizes.

Compressed ciphertexts

This example shows how to compress a ciphertext encrypting messages over 16 bits:

use tfhe::prelude::*;
use tfhe::{ConfigBuilder, generate_keys, set_server_key, CompressedFheUint16};

fn main() {
    let config = ConfigBuilder::default().build();
    let (client_key, _) = generate_keys(config);

    let clear = 12_837u16;
    let compressed = CompressedFheUint16::try_encrypt(clear, &client_key).unwrap();
    println!(
        "compressed size  : {}",
        bincode::serialize(&compressed).unwrap().len()
    );
    
    let decompressed = compressed.decompress();
    
    println!(
        "decompressed size: {}",
        bincode::serialize(&decompressed).unwrap().len()
    );

    let clear_decompressed: u16 = decompressed.decrypt(&client_key);
    assert_eq!(clear_decompressed, clear);
}

Compressed server keys

This example shows how to compress the server keys:

Compressed public keys

This example shows how to compress the classical public keys:

circle-exclamation

Compressed compact public key

This example shows how to use compressed compact public keys:

Last updated

Was this helpful?