Public key encryption

This document explains public key encryption and provides instructions for 2 methods.

Public key encryption refers to the cryptographic paradigm where the encryption key can be publicly distributed, whereas the decryption key remains secret to the owner. This differs from the usual case where the same secret key is used to encrypt and decrypt the data. In TFHE-rs, there are two methods for public key encryptions:

Public keys can also be compressed to reduce size.

Classical public key

This example shows how to use classical public keys.

use tfhe::prelude::*;
use tfhe::{ConfigBuilder, generate_keys, FheUint8, PublicKey};

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

    let public_key = PublicKey::new(&client_key);

    let a = FheUint8::try_encrypt(255u8, &public_key).unwrap();
    let clear: u8 = a.decrypt(&client_key);
    assert_eq!(clear, 255u8);
}

Compact public key

This example shows how to use compact public keys. The main difference is in the ConfigBuilder where the parameter set has been changed.

For more information on using compact public keys to encrypt data and generate a zero-knowledge proof of correct encryption at the same time, see the guide on ZK proofs.

use tfhe::prelude::*;
use tfhe::{
    generate_keys, CompactCiphertextList, CompactPublicKey, ConfigBuilder, FheUint8,
};


fn main() {
     let config = ConfigBuilder::default()
        .use_custom_parameters(
            tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS,
        )
        .build();
    let (client_key, _) = generate_keys(config);

    let public_key = CompactPublicKey::new(&client_key);
    let compact_list = CompactCiphertextList::builder(&public_key)
        .push(255u8)
        .build();
    let expanded = compact_list.expand().unwrap();
    let a: FheUint8 = expanded.get(0).unwrap().unwrap();

    let clear: u8 = a.decrypt(&client_key);
    assert_eq!(clear, 255u8);
}

Last updated