Files
tfhe-rs/apps/test-vectors/data/README.md
2025-12-03 17:44:46 +01:00

8.4 KiB

Test vectors for TFHE

These test vectors are generated using TFHE-rs, with the git tag tfhe-test-vectors-0.2.0.

They are TFHE-rs objects serialized in the cbor format. You can deserialize them using any cbor library for the language of your choice. For example, using the cbor2 program, run: cbor2 --pretty toy_params/lwe_a.cbor.

You will find 2 folders with test vectors for different parameter sets:

  • valid_params_128: valid classical PBS parameters using a gaussian noise distribution, providing 128bits of security in the IND-CPA model and a bootstrapping probability of failure of 2^{-64}.
  • toy_params: insecure parameters that yield smaller values

The values are generated for the keyswitch -> bootstrap (KS-PBS) atomic pattern. The cleartext inputs are 2 values, A and B defined below.

All the random values are generated from a fixed seed, that can be found in the RAND_SEED constant below. The PRNG used is the one based on the AES block cipher in counter mode, from tfhe tfhe-csprng crate.

The programmable bootstrap is applied twice, with 2 different lut, the identity lut and a specific one (currently a x2 operation)

Vectors

The following values are generated:

Keys

name description TFHE-rs type
large_lwe_secret_key Encryption secret key, before the KS and after the PBS LweSecretKey<Vec<u64>>
small_lwe_secret_key Secret key encrypting ciphertexts between the KS and the PBS LweSecretKey<Vec<u64>>
ksk The keyswitching key to convert a ct from the large key to the small one LweKeyswitchKey<Vec<u64>>
bsk the bootstrapping key to perform a programmable bootstrap on the keyswitched ciphertext LweBootstrapKey<Vec<u64>>

Ciphertexts

name description TFHE-rs type Cleartext
lwe_a Lwe encryption of A LweCiphertext<Vec<u64>> A
lwe_b Lwe encryption of B LweCiphertext<Vec<u64>> B
lwe_sum Lwe encryption of A plus lwe encryption of B LweCiphertext<Vec<u64>> A+B
lwe_prod Lwe encryption of A times cleartext B LweCiphertext<Vec<u64>> A*B
lwe_ms The lwe ciphertext after the modswitch part of the PBS (note) LweCiphertext<Vec<u64>> A
lwe_ks The lwe ciphertext after the keyswitch LweCiphertext<Vec<u64>> A
glwe_after_id_br The glwe returned by the application of the identity blind rotation on the mod switched ciphertexts. GlweCiphertext<Vec<u64>> rot id LUT
lwe_after_id_pbs The lwe returned by the application of the sample extract operation on the output of the id blind rotation LweCiphertext<Vec<u64>> A
glwe_after_spec_br The glwe returned by the application of the spec blind rotation on the mod switched ciphertexts. GlweCiphertext<Vec<u64>> rot spec LUT
lwe_after_spec_pbs The lwe returned by the application of the sample extract operation on the output of the spec blind rotation LweCiphertext<Vec<u64>> spec(A)

Encodings

Non native encoding

Warning: TFHE-rs uses a specific encoding for non native (ie: u32, u64) power of two ciphertext modulus. This encoding puts the encoded value in the high bits of the native integer. For example, the value 37 with a modulus of 64 will be encoded as 0b1001010000000000000000000000000000000000000000000000000000000000. This matters for the post modswitch lwe ciphertext.

Ciphertext modulus

The ciphertext modulus encoding use a specific value for the native modulus: 0. For example, if values are stored on u64 integers, 0 means a ciphertext modulus of 2^64.

Operations

name inputs outputs
large secret key gen PARAMS, RAND_SEED large_lwe_secret_key
small secret key gen PARAMS, RAND_SEED small_lwe_secret_key
keyswitch key gen PARAMS, RAND_SEED, large_lwe_secret_key, small_lwe_secret_key ksk
bootstrap key gen PARAMS, RAND_SEED, small_lwe_secret_key, large_lwe_secret_key bsk
encryption A A, large_lwe_secret_key lwe_a
encryption B B, large_lwe_secret_key lwe_b
E(A)+E(B) lwe_a, lwe_b lwe_sum
E(A)*B lwe_a, B lwe_prod
keyswitch lwe_a, ksk lwe_ks
modulus switch lwe_ks lwe_ms
blind rotation id lut ID_LUT, lwe_ms, bsk glwe_after_id_br
sample extract id lut glwe_after_id_br lwe_after_id_pbs
blind rotation spec lut SPEC_LUT, lwe_ms, bsk glwe_after_spec_br
sample extract spec lut glwe_after_spec_br lwe_after_spec_pbs

Parameters

const RAND_SEED: u128 = 0x74666865;

const MSG_A: u64 = 4;
const MSG_B: u64 = 3;

const VALID_LWE_DIMENSION: LweDimension = LweDimension(833);
const VALID_GLWE_DIMENSION: GlweDimension = GlweDimension(1);
const VALID_POLYNOMIAL_SIZE: PolynomialSize = PolynomialSize(2048);
const VALID_GAUSSIAN_LWE_NOISE_STDDEV: f64 = 3.6158408373309336e-06;
const VALID_GAUSSIAN_GLWE_NOISE_STDDEV: f64 = 2.845267479601915e-15;
const VALID_PBS_DECOMPOSITION_BASE_LOG: DecompositionBaseLog = DecompositionBaseLog(23);
const VALID_PBS_DECOMPOSITION_LEVEL_COUNT: DecompositionLevelCount = DecompositionLevelCount(1);
const VALID_KS_DECOMPOSITION_BASE_LOG: DecompositionBaseLog = DecompositionBaseLog(3);
const VALID_KS_DECOMPOSITION_LEVEL_COUNT: DecompositionLevelCount = DecompositionLevelCount(5);

const TOY_LWE_DIMENSION: LweDimension = LweDimension(10);
const TOY_GLWE_DIMENSION: GlweDimension = GlweDimension(1);
const TOY_POLYNOMIAL_SIZE: PolynomialSize = PolynomialSize(256);
const TOY_GAUSSIAN_LWE_NOISE_STDDEV: f64 = 0.;
const TOY_GAUSSIAN_GLWE_NOISE_STDDEV: f64 = 0.;
const TOY_PBS_DECOMPOSITION_BASE_LOG: DecompositionBaseLog = DecompositionBaseLog(24);
const TOY_PBS_DECOMPOSITION_LEVEL_COUNT: DecompositionLevelCount = DecompositionLevelCount(1);
const TOY_KS_DECOMPOSITION_BASE_LOG: DecompositionBaseLog = DecompositionBaseLog(37);
const TOY_KS_DECOMPOSITION_LEVEL_COUNT: DecompositionLevelCount = DecompositionLevelCount(1);

const CIPHERTEXT_MODULUS: CiphertextModulus<u64> = CiphertextModulus::new_native();
const MSG_BITS: usize = 4;

const SPEC_LUT: fn(u64) -> u64 = |x| (x * 2) % (1u64 << MSG_BITS);
const ID_LUT: fn(u64) -> u64 = |x| x;