Zero-knowledge proofs
use rand::prelude::*;
use tfhe::prelude::FheDecrypt;
use tfhe::shortint::parameters::DynamicDistribution;
use tfhe::set_server_key;
use tfhe::zk::{CompactPkeCrs, ZkComputeLoad};
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut rng = thread_rng();
let max_num_message = 1;
let mut params =
tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS_TUNIFORM_2M40;
let client_key = tfhe::ClientKey::generate(tfhe::ConfigBuilder::with_custom_parameters(params, None));
// This is done in an offline phase and the CRS is shared to all clients and the server
let crs = CompactPkeCrs::from_shortint_params(params, max_num_message).unwrap();
let public_zk_params = crs.public_params();
let server_key = tfhe::ServerKey::new(&client_key);
let public_key = tfhe::CompactPublicKey::try_new(&client_key).unwrap();
let clear_a = rng.gen::<u64>();
let clear_b = rng.gen::<u64>();
let a = tfhe::ProvenCompactFheUint64::try_encrypt(
clear_a,
public_zk_params,
&public_key,
ZkComputeLoad::Proof,
)?;
let b = tfhe::ProvenCompactFheUint64::try_encrypt(
clear_b,
public_zk_params,
&public_key,
ZkComputeLoad::Proof,
)?;
// Server side
let result = {
set_server_key(server_key);
// Verify the ciphertexts
let a = a.verify_and_expand(&public_zk_params, &public_key)?;
let b = b.verify_and_expand(&public_zk_params, &public_key)?;
a + b
};
// Back on the client side
let a_plus_b: u64 = result.decrypt(&client_key);
assert_eq!(a_plus_b, clear_a.wrapping_add(clear_b));
Ok(())
}Last updated
Was this helpful?