From 0e1b064182f9925660985ccaa9d6c4d59876b58e Mon Sep 17 00:00:00 2001 From: Nicolas Sarlin Date: Tue, 2 Dec 2025 14:42:32 +0100 Subject: [PATCH] chore: fix test vectors lut --- apps/test-vectors/Cargo.toml | 2 +- apps/test-vectors/checksums.sha256 | 8 +++---- apps/test-vectors/data/README.md | 2 +- .../data/toy_params/glwe_after_spec_br.cbor | 2 +- .../data/toy_params/lwe_after_spec_pbs.cbor | 2 +- .../valid_params_128/glwe_after_spec_br.cbor | 2 +- .../valid_params_128/lwe_after_spec_pbs.cbor | 2 +- apps/test-vectors/src/main.rs | 23 ++++++++++++++++++- 8 files changed, 32 insertions(+), 11 deletions(-) diff --git a/apps/test-vectors/Cargo.toml b/apps/test-vectors/Cargo.toml index 9424f089c..581ce5a47 100644 --- a/apps/test-vectors/Cargo.toml +++ b/apps/test-vectors/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tfhe-test-vectors" -version = "0.1.0" +version = "0.2.0" edition = "2024" rust-version.workspace = true diff --git a/apps/test-vectors/checksums.sha256 b/apps/test-vectors/checksums.sha256 index 9ee7f79fb..5ba52ae0e 100644 --- a/apps/test-vectors/checksums.sha256 +++ b/apps/test-vectors/checksums.sha256 @@ -1,4 +1,4 @@ -2abec9dc5d399ece68ac227f67f7cafcb9a6acac36ed734fe3d5244021eb1cda data/toy_params/glwe_after_spec_br.cbor +29b6e3e7d27700004b70dca24d225816500490e2d6ee49b9af05837fd421896b data/valid_params_128/lwe_after_spec_pbs.cbor 2c70d1d78cc3760733850a353ace2b9c4705e840141b75841739e90e51247e18 data/valid_params_128/small_lwe_secret_key.cbor 36c9080b636475fcacca503ce041bbfeee800fd3e1890dee559ea18defff9fe8 data/toy_params/glwe_after_id_br.cbor 377761beeb4216cf5aa2624a8b64b8259f5a75c32d28e850be8bced3a0cdd6f5 data/toy_params/ksk.cbor @@ -10,19 +10,19 @@ 7cc6803f5fbc3d5a1bf597f2b979ce17eecd3d6baca12183dea21022a7b65c52 data/toy_params/bsk.cbor 7f3c40a134623b44779a556212477fea26eaed22450f3b6faeb8721d63699972 data/valid_params_128/lwe_sum.cbor 837b3bd3245d4d0534ed255fdef896fb4fa6998a258a14543dfdadd0bfc9b6dd data/toy_params/lwe_prod.cbor -8ee68ed99dd9103fb62b1e2c7c8cf483706ae2071b792d4bd16f9f93f64871f9 data/toy_params/lwe_after_spec_pbs.cbor -99a19c5d6d5f4fd81d9164d0ff96719ef362eabda256bce6a55cba6cb69e42bf data/valid_params_128/glwe_after_spec_br.cbor aa44aea29efd6d9e4d35a21a625d9cba155672e3f7ed3eddee1e211e62ad146b data/valid_params_128/lwe_ms.cbor b7a037b9eaa88d6385167579b93e26a0cb6976d9b8967416fd1173e113bda199 data/valid_params_128/large_lwe_secret_key.cbor +bd00a8ae7494e400de5753029552ee1647efe7e17409b863a26a13b081099b8c data/toy_params/lwe_after_spec_pbs.cbor c6df98676de04fe54b5ffc2eb30a82ebb706c9d7d5a4e0ed509700fec88761f7 data/toy_params/lwe_ms.cbor c7d5a864d5616a7d8ad50bbf40416e41e6c9b60c546dc14d4aa8fc40a418baa7 data/toy_params/large_lwe_secret_key.cbor c806533b325b1009db38be2f9bef5f3b2fad6b77b4c71f2855ccc9d3b4162e98 data/valid_params_128/lwe_b.cbor c9eb75bd2993639348a679cf48c06e3c38d1a513f48e5b0ce0047cea8cff6bbc data/toy_params/lwe_a.cbor d6da5baef0e787f6be56e218d8354e26904652602db964844156fdff08350ce6 data/toy_params/lwe_ks.cbor -e44ffa6e5a50a03d32721180a051c8ce62f1791d4853aeaebed0200c183a57cf data/valid_params_128/lwe_after_spec_pbs.cbor e591ab9af1b6a0aede273f9a3abb65a4c387feb5fa06a6959e9314058ca0f7e5 data/valid_params_128/ksk.cbor +e628354c81508a2d888016e8282df363dd12f1e19190b6475d4eb9d7ab8ae007 data/valid_params_128/glwe_after_spec_br.cbor e69d2d2c064fc8c0460b39191ca65338146990349954f5ec5ebd01d93610e7eb data/valid_params_128/lwe_a.cbor e76c24b2a0c9a842ad13dda35473c2514f9e7d20983b5ea0759c4521a91626d9 data/valid_params_128/lwe_prod.cbor e9afe7019acba5cda926f13e06df9930571611729d2f2e8ce41956e1f5e1db6f data/valid_params_128/bsk.cbor eadf2eff35133ffba075df11faecddd6e7af9ddc398011ec4568e5528812b3e2 data/toy_params/lwe_b.cbor ee9fcf45f1379ca3a7d7bf2b0e7a1cc920ceb496c0217e8604b0b58d2831749e data/toy_params/small_lwe_secret_key.cbor +f7a89ac440def1c8aa3f42ecc41813632509df38cd4544d1a507711831e629bd data/toy_params/glwe_after_spec_br.cbor diff --git a/apps/test-vectors/data/README.md b/apps/test-vectors/data/README.md index ae0cd8613..34bb7814f 100644 --- a/apps/test-vectors/data/README.md +++ b/apps/test-vectors/data/README.md @@ -1,5 +1,5 @@ # Test vectors for TFHE -These test vectors are generated using [TFHE-rs](https://github.com/zama-ai/tfhe-rs), with the git tag `tfhe-test-vectors-0.1.0`. +These test vectors are generated using [TFHE-rs](https://github.com/zama-ai/tfhe-rs), with the git tag `tfhe-test-vectors-0.2.0`. They are TFHE-rs objects serialized in the [cbor format](https://cbor.io/). You can deserialize them using any cbor library for the language of your choice. For example, using the [cbor2](https://pypi.org/project/cbor2/) program, run: `cbor2 --pretty toy_params/lwe_a.cbor`. diff --git a/apps/test-vectors/data/toy_params/glwe_after_spec_br.cbor b/apps/test-vectors/data/toy_params/glwe_after_spec_br.cbor index 529316301..eaed55519 100644 --- a/apps/test-vectors/data/toy_params/glwe_after_spec_br.cbor +++ b/apps/test-vectors/data/toy_params/glwe_after_spec_br.cbor @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2abec9dc5d399ece68ac227f67f7cafcb9a6acac36ed734fe3d5244021eb1cda +oid sha256:f7a89ac440def1c8aa3f42ecc41813632509df38cd4544d1a507711831e629bd size 4679 diff --git a/apps/test-vectors/data/toy_params/lwe_after_spec_pbs.cbor b/apps/test-vectors/data/toy_params/lwe_after_spec_pbs.cbor index e2649c1d3..2355987c6 100644 --- a/apps/test-vectors/data/toy_params/lwe_after_spec_pbs.cbor +++ b/apps/test-vectors/data/toy_params/lwe_after_spec_pbs.cbor @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ee68ed99dd9103fb62b1e2c7c8cf483706ae2071b792d4bd16f9f93f64871f9 +oid sha256:bd00a8ae7494e400de5753029552ee1647efe7e17409b863a26a13b081099b8c size 2365 diff --git a/apps/test-vectors/data/valid_params_128/glwe_after_spec_br.cbor b/apps/test-vectors/data/valid_params_128/glwe_after_spec_br.cbor index 8b333abb0..3309f2f84 100644 --- a/apps/test-vectors/data/valid_params_128/glwe_after_spec_br.cbor +++ b/apps/test-vectors/data/valid_params_128/glwe_after_spec_br.cbor @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:99a19c5d6d5f4fd81d9164d0ff96719ef362eabda256bce6a55cba6cb69e42bf +oid sha256:e628354c81508a2d888016e8282df363dd12f1e19190b6475d4eb9d7ab8ae007 size 36935 diff --git a/apps/test-vectors/data/valid_params_128/lwe_after_spec_pbs.cbor b/apps/test-vectors/data/valid_params_128/lwe_after_spec_pbs.cbor index 9a2b54cf6..8b590cebc 100644 --- a/apps/test-vectors/data/valid_params_128/lwe_after_spec_pbs.cbor +++ b/apps/test-vectors/data/valid_params_128/lwe_after_spec_pbs.cbor @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e44ffa6e5a50a03d32721180a051c8ce62f1791d4853aeaebed0200c183a57cf +oid sha256:29b6e3e7d27700004b70dca24d225816500490e2d6ee49b9af05837fd421896b size 18493 diff --git a/apps/test-vectors/src/main.rs b/apps/test-vectors/src/main.rs index 8968f9236..cb0062898 100644 --- a/apps/test-vectors/src/main.rs +++ b/apps/test-vectors/src/main.rs @@ -1,5 +1,6 @@ use serde::Serialize; use std::fs::{File, create_dir_all, read_dir, remove_dir_all, remove_file}; +use std::ops::Deref; use std::path::{Path, PathBuf}; use tfhe::core_crypto::commons::generators::DeterministicSeeder; @@ -38,7 +39,7 @@ const ENCODING: Encoding = Encoding { msg_bits: 4, }; -const SPEC_LUT: fn(u64) -> u64 = |x| (x * 2) & (1u64 << ENCODING.msg_bits); +const SPEC_LUT: fn(u64) -> u64 = |x| (x * 2) % (ENCODING.msg_modulus() as u64); const ID_LUT: fn(u64) -> u64 = |x| x; const DATA_DIR: &str = "./data"; @@ -112,6 +113,10 @@ fn store_data>(path: P, data: &Data, name: &str) ciborium::ser::into_writer(data, &mut file).unwrap(); } +fn assert_data_not_zero>(data: &Data) { + assert!(data.as_ref().iter().any(|&x| x != Scalar::ZERO)); +} + #[allow(clippy::too_many_arguments)] fn generate_test_vectors>( path: P, @@ -139,10 +144,12 @@ fn generate_test_vectors>( let glwe_secret_key: GlweSecretKey> = GlweSecretKey::generate_new_binary(glwe_dimension, polynomial_size, &mut secret_generator); let large_lwe_secret_key = glwe_secret_key.as_lwe_secret_key(); + assert_data_not_zero(&large_lwe_secret_key); store_data(path, &large_lwe_secret_key, "large_lwe_secret_key"); let small_lwe_secret_key: LweSecretKey> = LweSecretKey::generate_new_binary(lwe_dimension, &mut secret_generator); + assert_data_not_zero(&small_lwe_secret_key); store_data(path, &small_lwe_secret_key, "small_lwe_secret_key"); let lwe_noise_distribution = Gaussian::from_standard_dev(StandardDev(lwe_noise_stddev), 0.); @@ -156,6 +163,7 @@ fn generate_test_vectors>( encoding.ciphertext_modulus, &mut encryption_generator, ); + assert_data_not_zero(&lwe_a); store_data(path, &lwe_a, "lwe_a"); let plaintext_b = encoding.encode(MSG_B); @@ -166,6 +174,7 @@ fn generate_test_vectors>( encoding.ciphertext_modulus, &mut encryption_generator, ); + assert_data_not_zero(&lwe_b); store_data(path, &lwe_b, "lwe_b"); let mut lwe_sum = LweCiphertext::new( @@ -180,6 +189,7 @@ fn generate_test_vectors>( let res = encoding.decode(decrypted_sum); assert_eq!(res, MSG_A + MSG_B); + assert_data_not_zero(&lwe_sum); store_data(path, &lwe_sum, "lwe_sum"); let mut lwe_prod = LweCiphertext::new( @@ -194,6 +204,7 @@ fn generate_test_vectors>( let res = encoding.decode(decrypted_prod); assert_eq!(res, MSG_A * MSG_B); + assert_data_not_zero(&lwe_prod); store_data(path, &lwe_prod, "lwe_prod"); let ksk = allocate_and_generate_new_lwe_keyswitch_key( @@ -205,6 +216,7 @@ fn generate_test_vectors>( encoding.ciphertext_modulus, &mut encryption_generator, ); + assert_data_not_zero(&ksk); store_data(path, &ksk, "ksk"); let mut lwe_ks = LweCiphertext::new( @@ -218,6 +230,7 @@ fn generate_test_vectors>( let res = encoding.decode(decrypted_ks); assert_eq!(res, MSG_A); + assert_data_not_zero(&lwe_ks); store_data(path, &lwe_ks, "lwe_ks"); let bsk = par_allocate_and_generate_new_lwe_bootstrap_key( @@ -229,6 +242,7 @@ fn generate_test_vectors>( encoding.ciphertext_modulus, &mut encryption_generator, ); + assert_data_not_zero(bsk.deref()); store_data(path, &bsk, "bsk"); let mut fourier_bsk = FourierLweBootstrapKey::new( @@ -246,11 +260,14 @@ fn generate_test_vectors>( let modswitched = lwe_ciphertext_modulus_switch(lwe_in_ms, log_modulus); let lwe_ms = modswitched_to_lwe(&modswitched); + assert_data_not_zero(&lwe_ms); store_data(path, &lwe_ms, "lwe_ms"); let mut id_lut = encoding.encode_lut(glwe_dimension, polynomial_size, ID_LUT); + assert_data_not_zero(&id_lut); blind_rotate_assign(&modswitched, &mut id_lut, &fourier_bsk); + assert_data_not_zero(&id_lut); store_data(path, &id_lut, "glwe_after_id_br"); let mut lwe_pbs_id = LweCiphertext::new( @@ -267,11 +284,14 @@ fn generate_test_vectors>( let res = encoding.decode(decrypted_pbs_id); assert_eq!(res, MSG_A); + assert_data_not_zero(&lwe_pbs_id); store_data(path, &lwe_pbs_id, "lwe_after_id_pbs"); let mut spec_lut = encoding.encode_lut(glwe_dimension, polynomial_size, SPEC_LUT); + assert_data_not_zero(&spec_lut); blind_rotate_assign(&modswitched, &mut spec_lut, &fourier_bsk); + assert_data_not_zero(&spec_lut); store_data(path, &spec_lut, "glwe_after_spec_br"); let mut lwe_pbs_spec = LweCiphertext::new( @@ -288,6 +308,7 @@ fn generate_test_vectors>( let res = encoding.decode(decrypted_pbs_spec); assert_eq!(res, SPEC_LUT(MSG_A)); + assert_data_not_zero(&lwe_pbs_spec); store_data(path, &lwe_pbs_spec, "lwe_after_spec_pbs"); }