Skip to content

Commit

Permalink
chore(hl): add data tests for heterogeneous lists
Browse files Browse the repository at this point in the history
  • Loading branch information
nsarlin-zama committed Jul 19, 2024
1 parent a6007b1 commit 938d3f5
Showing 1 changed file with 179 additions and 8 deletions.
187 changes: 179 additions & 8 deletions tfhe/tests/backward_compatibility/high_level_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@ use tfhe::backward_compatibility::booleans::{CompactFheBool, CompactFheBoolList}
use tfhe::backward_compatibility::integers::{
CompactFheInt8, CompactFheInt8List, CompactFheUint8, CompactFheUint8List,
};

use tfhe::prelude::{FheDecrypt, FheEncrypt};
use tfhe::shortint::PBSParameters;
use tfhe::{
set_server_key, ClientKey, CompactCiphertextList, CompressedCompactPublicKey,
CompressedFheBool, CompressedFheInt8, CompressedFheUint8, CompressedPublicKey,
CompressedServerKey, FheUint8,
set_server_key, ClientKey, CompactCiphertextList, CompressedCiphertextList,
CompressedCompactPublicKey, CompressedFheBool, CompressedFheInt8, CompressedFheUint8,
CompressedPublicKey, CompressedServerKey, FheBool, FheInt8, FheUint8,
};
use tfhe_backward_compat_data::load::{
load_versioned_auxiliary, DataFormat, TestFailure, TestResult, TestSuccess,
};
use tfhe_backward_compat_data::{
HlBoolCiphertextListTest, HlBoolCiphertextTest, HlCiphertextListTest, HlCiphertextTest,
HlClientKeyTest, HlPublicKeyTest, HlServerKeyTest, HlSignedCiphertextListTest,
HlSignedCiphertextTest, TestMetadata, TestParameterSet, TestType, Testcase,
DataKind, HlBoolCiphertextListTest, HlBoolCiphertextTest, HlCiphertextListTest,
HlCiphertextTest, HlClientKeyTest, HlHeterogeneousCiphertextListTest, HlPublicKeyTest,
HlServerKeyTest, HlSignedCiphertextListTest, HlSignedCiphertextTest, TestMetadata,
TestParameterSet, TestType, Testcase,
};
use tfhe_versionable::Unversionize;

Expand Down Expand Up @@ -257,6 +259,129 @@ pub fn test_hl_bool_ciphertext_list(
}
}

/// Test HL ciphertext list: loads the ciphertext list and compare the decrypted values to the ones
/// in the metadata.
pub fn test_hl_heterogeneous_ciphertext_list(
dir: &Path,
test: &HlHeterogeneousCiphertextListTest,
format: DataFormat,
) -> Result<TestSuccess, TestFailure> {
let key_file = dir.join(&*test.key_filename);
let key = ClientKey::unversionize(
load_versioned_auxiliary(key_file).map_err(|e| test.failure(e, format))?,
)
.map_err(|e| test.failure(e, format))?;

let server_key = key.generate_server_key();
set_server_key(server_key);

if test.compressed {
test_hl_heterogeneous_ciphertext_list_compressed(
load_and_unversionize(dir, test, format)?,
&key,
test,
)
} else {
test_hl_heterogeneous_ciphertext_list_compact(
load_and_unversionize(dir, test, format)?,
&key,
test,
)
}
.map(|_| test.success(format))
.map_err(|msg| test.failure(msg, format))
}

pub fn test_hl_heterogeneous_ciphertext_list_compact(
list: CompactCiphertextList,
key: &ClientKey,
test: &HlHeterogeneousCiphertextListTest,
) -> Result<(), String> {
let ct_list = list.expand().unwrap();

for idx in 0..(ct_list.len()) {
match test.data_kinds[idx] {
DataKind::Bool => {
let ct: FheBool = ct_list.get(idx).unwrap().unwrap();
let clear = ct.decrypt(&key);
if clear != (test.clear_values[idx] != 0) {
return Err(format!(
"Invalid decrypted cleartext:\n Expected :\n{:?}\nGot:\n{:?}",
clear, test.clear_values[idx]
));
}
}
DataKind::Signed => {
let ct: FheInt8 = ct_list.get(idx).unwrap().unwrap();
let clear: i8 = ct.decrypt(&key);
if clear != test.clear_values[idx] as i8 {
return Err(format!(
"Invalid decrypted cleartext:\n Expected :\n{:?}\nGot:\n{:?}",
clear,
(test.clear_values[idx] as i8)
));
}
}
DataKind::Unsigned => {
let ct: FheUint8 = ct_list.get(idx).unwrap().unwrap();
let clear: u8 = ct.decrypt(&key);
if clear != test.clear_values[idx] as u8 {
return Err(format!(
"Invalid decrypted cleartext:\n Expected :\n{:?}\nGot:\n{:?}",
clear, test.clear_values[idx]
));
}
}
};
}
Ok(())
}

pub fn test_hl_heterogeneous_ciphertext_list_compressed(
list: CompressedCiphertextList,
key: &ClientKey,
test: &HlHeterogeneousCiphertextListTest,
) -> Result<(), String> {
let ct_list = list;

for idx in 0..(ct_list.len()) {
match test.data_kinds[idx] {
DataKind::Bool => {
let ct: FheBool = ct_list.get(idx).unwrap().unwrap();
let clear = ct.decrypt(&key);
if clear != (test.clear_values[idx] != 0) {
return Err(format!(
"Invalid decrypted cleartext:\n Expected :\n{:?}\nGot:\n{:?}",
clear, test.clear_values[idx]
));
}
}
DataKind::Signed => {
let ct: FheInt8 = ct_list.get(idx).unwrap().unwrap();
let clear: i8 = ct.decrypt(&key);
if clear != test.clear_values[idx] as i8 {
return Err(format!(
"Invalid decrypted cleartext:\n Expected :\n{:?}\nGot:\n{:?}",
clear,
(test.clear_values[idx] as i8)
));
}
}
DataKind::Unsigned => {
let ct: FheUint8 = ct_list.get(idx).unwrap().unwrap();
let clear: u8 = ct.decrypt(&key);
if clear != test.clear_values[idx] as u8 {
return Err(format!(
"Invalid decrypted cleartext:\n Expected :\n{:?}\nGot:\n{:?}",
clear, test.clear_values[idx]
));
}
}
};
}
Ok(())
}

/// Test HL client key: loads the key and checks the parameters using the values stored in
/// the test metadata.
pub fn test_hl_clientkey(
Expand Down Expand Up @@ -333,8 +458,8 @@ pub fn test_hl_pubkey(
}
}

/// Test HL server key: encrypt to values with a client key, add them using the server key and check
/// that the decrypted sum is valid.
/// Test HL server key: encrypt two values with a client key, add them using the server key and
/// check that the decrypted sum is valid.
pub fn test_hl_serverkey(
dir: &Path,
test: &HlServerKeyTest,
Expand Down Expand Up @@ -376,6 +501,49 @@ pub fn test_hl_serverkey(
}
}

// /// Test HL KeySwitchingKey: encrypt a value with the source key, perform a keyswitch with the
// ksk /// and try to decrypt the value with the destination key.
// pub fn test_hl_ksk(
// dir: &Path,
// test: &HlKskTest,
// format: DataFormat,
// ) -> Result<TestSuccess, TestFailure> {
// let client_key_file = dir.join(&*test.client_key_filename);
// let client_key = ClientKey::unversionize(
// load_versioned_auxiliary(client_key_file).map_err(|e| test.failure(e, format))?,
// )
// .map_err(|e| test.failure(e, format))?;

// let v1 = 73u8;
// let ct1 = FheUint8::encrypt(v1, &client_key);
// let v2 = 102u8;
// let ct2 = FheUint8::encrypt(v2, &client_key);

// let key = if test.compressed {
// let compressed: CompressedServerKey = load_and_unversionize(dir, test, format)?;
// compressed.decompress()
// } else {
// load_and_unversionize(dir, test, format)?
// };
// set_server_key(key);

// let ct_sum = ct1 + ct2;
// let sum: u8 = ct_sum.decrypt(&client_key);

// if sum != v1 + v2 {
// Err(test.failure(
// format!(
// "Invalid result for addition using loaded server key, expected {} got {}",
// v1 + v2,
// sum,
// ),
// format,
// ))
// } else {
// Ok(test.success(format))
// }
// }

pub struct Hl;

impl TestedModule for Hl {
Expand Down Expand Up @@ -406,6 +574,9 @@ impl TestedModule for Hl {
TestMetadata::HlSignedCiphertextList(test) => {
test_hl_signed_ciphertext_list(test_dir.as_ref(), test, format).into()
}
TestMetadata::HlHeterogeneousCiphertextList(test) => {
test_hl_heterogeneous_ciphertext_list(test_dir.as_ref(), test, format).into()
}
TestMetadata::HlClientKey(test) => {
test_hl_clientkey(test_dir.as_ref(), test, format).into()
}
Expand Down

0 comments on commit 938d3f5

Please sign in to comment.