Use public key encryption

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 usual case where the same secret key is used to encrypt and decrypt the data. In TFHE-rs, there exists two methods for public key encryptions. First, the usual one, where the public key contains many encryptions of zero. More details can be found in Guide to Fully Homomorphic Encryption over the [Discretized] Torus, Appendix A.. The second method is based on the paper entitled TFHE Public-Key Encryption Revisited. The main advantage of the latter method in comparison with the former lies into the key sizes, which are drastically reduced.

Note that public keys can be compressed

Classical public key

This example shows how to use public keys.

use tfhe::prelude::*;
use tfhe::{ConfigBuilder, generate_keys, set_server_key, 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.

See the guide on ZK proofs to see how to encrypt data using compact public keys and generate a zero knowledge proof of correct encryption at the same time.

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

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

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

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

Last updated