Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions measurements/single/results-1.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"Timing": {
"Input generation": "0.1273s",
"Input preprocessing": "0.0008s",
"Key Generation": "0.7905s",
"Input encryption": "0.0122s",
"Encrypted computation": "1.4031s",
"Result decryption": "0.0026s",
"Result postprocessing": "0.0006s",
"Total": "2.3371s"
"Input generation": "0.0922s",
"Input preprocessing": "0.0012s",
"Key Generation": "1.0345s",
"Input encryption": "0.0114s",
"Encrypted computation": "3.798s",
"Result decryption": "0.0027s",
"Result postprocessing": "0.0008s",
"Total": "4.9409s"
},
"Bandwidth": {
"Public and evaluation keys": "125.0M",
"Encrypted input": "1.0M",
"Encrypted results": "514.4K"
"Public and evaluation keys": "28.8M",
"Encrypted input": "6.0K",
"Encrypted results": "514.5K"
}
}
2 changes: 1 addition & 1 deletion submission/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
bincode = "1.3"
serde = "1"
tfhe = { version = "~1.1.3", features = ["integer"] }
tfhe = { version = "1.5.4", features = ["integer"] }
rand = { version = "0.9.1" }

[[bin]]
Expand Down
6 changes: 6 additions & 0 deletions submission/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

This is a reference implementation for the 64-bits multiplication workload, written in [Rust](https://rust-lang.org/) and using the [TFHE-rs](https://docs.zama.org/tfhe-rs) library.

## Security and Parameters

The reference implementation uses the default parameter set of TFHE-rs, version 1.5.4. According to the [TFHE-rs documentation](https://docs.zama.org/tfhe-rs/1.5/get-started/security-and-cryptography#security), these parameters provide 128 bits of security in the IND-CPA-D model:
* The lowest attack cost as estimated by the [Lattice Estimator](https://github.com/malb/lattice-estimator) is above $2^{128}$.
* The probability of decryption failure after a programmable bootstrap using the [drift reduction technique](https://eprint.iacr.org/2024/1718.pdf) is below $2^{-128}$.

## Build and run

Building the workflow requires the [Rust toolchain](https://rust-lang.org/tools/install/).
Expand Down
6 changes: 3 additions & 3 deletions submission/src/bin/client_encode_encrypt_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::env;
use std::path::Path;
use std::fs;

use tfhe::{ClientKey, FheUint64};
use tfhe::{ClientKey, CompressedFheUint64};
use tfhe::prelude::*;

use zn_multiplication::utils::*;
Expand All @@ -32,7 +32,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
let rhs_cleartext: Vec<u64> = read_numbers_from_file(Path::new(&("datasets/".to_owned() + &size + "/rhs.txt")))?;

// Encode and encrypt the LHS
let lhs_ciphers = lhs_cleartext.into_iter().map(|m| FheUint64::encrypt(m, &lwe_sk));
let lhs_ciphers = lhs_cleartext.into_iter().map(|m| CompressedFheUint64::encrypt(m, &lwe_sk));

// Write the LHS
let ciphertexts_dir = io_dir.clone() + "/ciphertexts_upload";
Expand All @@ -44,7 +44,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
}

// Encode and encrypt the RHS
let rhs_ciphers = rhs_cleartext.into_iter().map(|m| FheUint64::encrypt(m, &lwe_sk));
let rhs_ciphers = rhs_cleartext.into_iter().map(|m| CompressedFheUint64::encrypt(m, &lwe_sk));

// Write the RHS
for (i, cipher) in rhs_ciphers.enumerate() {
Expand Down
7 changes: 4 additions & 3 deletions submission/src/bin/client_key_generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use std::env;
use std::fs;
use tfhe::{ConfigBuilder, generate_keys};
use tfhe::{CompressedServerKey, ConfigBuilder, generate_keys};

pub fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = env::args().collect();
Expand All @@ -19,15 +19,16 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {

// Generate the keys
let config = ConfigBuilder::default().build();
let (client_key, server_key) = generate_keys(config);
let (client_key, _) = generate_keys(config);

// Serialize and save the secret key
let serialised_data = bincode::serialize(&client_key)?;
fs::create_dir(io_dir.clone() + "/private_keys")?;
fs::write(io_dir.clone() + "/private_keys/sk.bin", &serialised_data)?;

// Serialize and save the public key
let serialised_data = bincode::serialize(&server_key)?;
let compressed_server_key = CompressedServerKey::new(&client_key);
let serialised_data = bincode::serialize(&compressed_server_key)?;
fs::create_dir(io_dir.clone() + "/public_keys")?;
fs::write(io_dir.clone() + "/public_keys/pk.bin", &serialised_data)?;

Expand Down
15 changes: 8 additions & 7 deletions submission/src/bin/server_encrypted_compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::env;
use std::path::Path;
use std::fs;

use tfhe::{ FheUint64, set_server_key, ServerKey };
use tfhe::{ CompressedFheUint64, CompressedServerKey, FheUint64, set_server_key };

use zn_multiplication::half_cipher_cipher_mul_64;

Expand All @@ -25,23 +25,24 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {

// Load the server key
let serialised_data = fs::read(io_dir.clone() + "/public_keys/pk.bin")?;
let server_key: ServerKey = bincode::deserialize(&serialised_data)?;
let compressed_server_key: CompressedServerKey = bincode::deserialize(&serialised_data)?;
let server_key = compressed_server_key.decompress();
set_server_key(server_key);

// Load the LHS input ciphers
let ciphertexts_in_dir = io_dir.clone() + "/ciphertexts_upload";
let ciphers_lhs = (0 .. data_size).map(|i|
bincode::deserialize::<FheUint64>(&fs::read(ciphertexts_in_dir.clone() + "/cipher_lhs_" + &i.to_string() + ".bin")?)
).collect::<Result<Vec<FheUint64>, Box<bincode::ErrorKind>>>()?;
bincode::deserialize::<CompressedFheUint64>(&fs::read(ciphertexts_in_dir.clone() + "/cipher_lhs_" + &i.to_string() + ".bin")?)
).collect::<Result<Vec<CompressedFheUint64>, Box<bincode::ErrorKind>>>()?;

// Load the RHS input ciphers
let ciphers_rhs = (0 .. data_size).map(|i|
bincode::deserialize::<FheUint64>(&fs::read(ciphertexts_in_dir.clone() + "/cipher_rhs_" + &i.to_string() + ".bin")?)
).collect::<Result<Vec<FheUint64>, Box<bincode::ErrorKind>>>()?;
bincode::deserialize::<CompressedFheUint64>(&fs::read(ciphertexts_in_dir.clone() + "/cipher_rhs_" + &i.to_string() + ".bin")?)
).collect::<Result<Vec<CompressedFheUint64>, Box<bincode::ErrorKind>>>()?;

// Run the homomorphic multiplications
let ciphers_out = ciphers_lhs.iter().zip(ciphers_rhs.iter())
.map(|(lhs, rhs)| half_cipher_cipher_mul_64(lhs, rhs))
.map(|(lhs, rhs)| half_cipher_cipher_mul_64(&lhs.decompress(), &rhs.decompress()))
.collect::<Vec<FheUint64>>();

// Write the results
Expand Down