From f1a33096c25dd9f5375b6bc4782aa29342c39ab7 Mon Sep 17 00:00:00 2001 From: youben11 Date: Fri, 8 Nov 2024 15:26:37 +0100 Subject: [PATCH] docs(frontend): update TFHE-rs guide --- docs/guides/tfhers/README.md | 27 +++++----------- docs/guides/tfhers/serialization.md | 31 ++++++++----------- docs/guides/tfhers/shared-key.md | 27 ++++++---------- .../examples/tfhers/example.py | 4 ++- 4 files changed, 32 insertions(+), 57 deletions(-) diff --git a/docs/guides/tfhers/README.md b/docs/guides/tfhers/README.md index 3e0c601e8c..d2220207eb 100644 --- a/docs/guides/tfhers/README.md +++ b/docs/guides/tfhers/README.md @@ -1,6 +1,5 @@ # TFHE-rs Interoperability - {% hint style="warning" %} This feature is currently in beta version. Please note that the API may change in future Concrete releases. @@ -27,28 +26,16 @@ When working with a TFHE-rs integer type in Concrete, you can use the `.encode(. ```python from concrete.fhe import tfhers -# don't worry about the API, we will have better examples later. -# we just want to show the encoding here -tfhers_params = tfhers.CryptoParams( - lwe_dimension=909, - glwe_dimension=1, - polynomial_size=4096, - pbs_base_log=15, - pbs_level=2, - lwe_noise_distribution=9.743962418842052e-07, - glwe_noise_distribution=2.168404344971009e-19, - encryption_key_choice=tfhers.EncryptionKeyChoice.BIG, -) - -# TFHERSInteger using this type will be represented as a vector of 8/2=4 integers -tfhers_type = tfhers.TFHERSIntegerType( +# This will create a TFHE-rs unsigned integer of 8 bits +# using the parameters from the json file +tfhers_type = tfhers.get_type_from_params( + "tfhers_params.json", is_signed=False, - bit_width=8, - carry_width=3, - msg_width=2, - params=tfhers_params, + precision=8, ) +# Encoding could change depending on the parameters saved in 'tfhers_params.json' +# You should have the same result if message_modulus was equal to 4 assert (tfhers_type.encode(123) == [3, 2, 3, 1]).all() assert tfhers_type.decode([3, 2, 3, 1]) == 123 diff --git a/docs/guides/tfhers/serialization.md b/docs/guides/tfhers/serialization.md index bb4edfd597..f8a8bee892 100644 --- a/docs/guides/tfhers/serialization.md +++ b/docs/guides/tfhers/serialization.md @@ -6,18 +6,19 @@ Concrete already has its serilization functions (e.g. `tfhers_bridge.export_valu ## Ciphertexts -We can deserialize `FheUint8` (and similarly other types) using `bincode` +We should deserialize `FheUint8` using safe serialization functions from TFHE-rs ```rust use tfhe::FheUint8; +use tfhe::safe_serialization::{safe_deserialize, safe_serialize}; + +const SERIALIZE_SIZE_LIMIT: u64 = 1_000_000_000; /// ... fn load_fheuint8(path: &String) -> FheUint8 { - let path_fheuint: &Path = Path::new(path); - let serialized_fheuint = fs::read(path_fheuint).unwrap(); - let mut serialized_data = Cursor::new(serialized_fheuint); - bincode::deserialize_from(&mut serialized_data).unwrap() + let file = fs::File::open(path).unwrap(); + safe_deserialize(file, SERIALIZE_SIZE_LIMIT).unwrap() } ``` @@ -25,16 +26,14 @@ To serialize ```rust fn save_fheuint8(fheuint: FheUint8, path: &String) { - let mut serialized_ct = Vec::new(); - bincode::serialize_into(&mut serialized_ct, &fheuint).unwrap(); - let path_ct: &Path = Path::new(path); - fs::write(path_ct, serialized_ct).unwrap(); + let file = fs::File::create(path).unwrap(); + safe_serialize(fheuint, file, SERIALIZE_SIZE_LIMIT).unwrap() } ``` ## Secret Key -We can deserialize `LweSecretKey` using `bincode` +TFHE-rs safe serialization doesn't yet support this key so we should deserialize `LweSecretKey` using `bincode` ```rust use tfhe::core_crypto::prelude::LweSecretKey; @@ -42,10 +41,8 @@ use tfhe::core_crypto::prelude::LweSecretKey; /// ... fn load_lwe_sk(path: &String) -> LweSecretKey> { - let path_sk: &Path = Path::new(path); - let serialized_lwe_key = fs::read(path_sk).unwrap(); - let mut serialized_data = Cursor::new(serialized_lwe_key); - bincode::deserialize_from(&mut serialized_data).unwrap() + let file = fs::File::open(path).unwrap(); + bincode::deserialize_from(file).unwrap() } ``` @@ -53,9 +50,7 @@ To serialize ```rust fn save_lwe_sk(lwe_sk: LweSecretKey>, path: &String) { - let mut serialized_lwe_key = Vec::new(); - bincode::serialize_into(&mut serialized_lwe_key, &lwe_sk).unwrap(); - let path_sk: &Path = Path::new(path); - fs::write(path_sk, serialized_lwe_key).unwrap(); + let file = fs::File::create(path).unwrap(); + bincode::serialize_into(file, lwe_sk).unwrap() } ``` diff --git a/docs/guides/tfhers/shared-key.md b/docs/guides/tfhers/shared-key.md index 065050f504..1951c1dc10 100644 --- a/docs/guides/tfhers/shared-key.md +++ b/docs/guides/tfhers/shared-key.md @@ -30,24 +30,15 @@ In short, we first determine a suitable set of parameters from TFHE-rs and then from functools import partial from concrete.fhe import tfhers -tfhers_params = tfhers.CryptoParams( - lwe_dimension=909, - glwe_dimension=1, - polynomial_size=4096, - pbs_base_log=15, - pbs_level=2, - lwe_noise_distribution=9.743962418842052e-07, - glwe_noise_distribution=2.168404344971009e-19, - encryption_key_choice=tfhers.EncryptionKeyChoice.BIG, -) -# creating a TFHE-rs ciphertext type with crypto and encoding params -tfhers_type = tfhers.TFHERSIntegerType( +# This will create a TFHE-rs unsigned integer of 8 bits +# using the parameters from the json file +tfhers_type = tfhers.get_type_from_params( + # The json file is a serialization of ClassicPBSParameters in TFHE-rs + "tfhers_params.json", is_signed=False, - bit_width=8, - carry_width=3, - msg_width=2, - params=tfhers_params, + precision=8, ) + # this partial will help us create TFHERSInteger with the given type instead of calling # tfhers.TFHERSInteger(tfhers_type, value) every time tfhers_int = partial(tfhers.TFHERSInteger, tfhers_type) @@ -146,7 +137,7 @@ let shortint_key = // Concrete uses this parameters to define the TFHE-rs ciphertext type tfhe::shortint::prelude::PARAM_MESSAGE_2_CARRY_3_KS_PBS ).unwrap(); -let client_key = ClientKey::from_raw_parts(shortint_key.into(), None, None); +let client_key = ClientKey::from_raw_parts(shortint_key.into(), None, None, tfhe::Tag::default()); let server_key = client_key.generate_server_key(); ``` @@ -167,7 +158,7 @@ let config = ConfigBuilder::with_custom_parameters( .build(); let (client_key, server_key) = generate_keys(config); -let (integer_ck, _, _) = client_key.clone().into_raw_parts(); +let (integer_ck, _, _, _) = client_key.clone().into_raw_parts(); let shortint_ck = integer_ck.into_raw_parts(); let (glwe_secret_key, _, _) = shortint_ck.into_raw_parts(); let lwe_secret_key = glwe_secret_key.into_lwe_secret_key(); diff --git a/frontends/concrete-python/examples/tfhers/example.py b/frontends/concrete-python/examples/tfhers/example.py index 942b7340cf..953037fa1c 100644 --- a/frontends/concrete-python/examples/tfhers/example.py +++ b/frontends/concrete-python/examples/tfhers/example.py @@ -16,7 +16,9 @@ ####################################### tfhers_type = tfhers.get_type_from_params( - TFHERS_PARAMS_FILE, IS_SIGNED, FHEUINT_PRECISION + TFHERS_PARAMS_FILE, + is_signed=IS_SIGNED, + precision=FHEUINT_PRECISION, ) tfhers_int = partial(tfhers.TFHERSInteger, tfhers_type)