Ciphertexts Rerandomization
Example: Re-randomization of two FheUint64 values before addition
FheUint64 values before additionuse tfhe::prelude::*;
use tfhe::shortint::parameters::v1_4::meta::cpu::V1_4_META_PARAM_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128;
use tfhe::{
generate_keys, set_server_key, CompactPublicKey, CompressedCiphertextListBuilder, FheUint64,
ReRandomizationContext,
};
pub fn main() {
// The chosen parameters have re-rand enabled
let (cks, sks) = generate_keys(V1_4_META_PARAM_CPU_2_2_KS_PBS_PKE_TO_SMALL_ZKV2_TUNIFORM_2M128);
let cpk = CompactPublicKey::new(&cks);
let compact_public_encryption_domain_separator = *b"TFHE_Enc";
let rerand_domain_separator = *b"TFHE_Rrd";
set_server_key(sks);
// We want to compute FheUint64 + FheUint64, prepare inputs
let clear_a = rand::random::<u64>();
let clear_b = rand::random::<u64>();
let a = FheUint64::encrypt(clear_a, &cks);
let b = FheUint64::encrypt(clear_b, &cks);
// Simulate the data being stored on disk
let mut builder = CompressedCiphertextListBuilder::new();
builder.push(a);
builder.push(b);
let list = builder.build().unwrap();
// Actual Re-Randomization context
let c = {
// Inputs are fetched from storage
let mut a: FheUint64 = list.get(0).unwrap().unwrap();
let mut b: FheUint64 = list.get(1).unwrap().unwrap();
// Simulate a 256 bits nonce to make the execution unique
let nonce: [u8; 256 / 8] = core::array::from_fn(|_| rand::random());
let mut re_rand_context = ReRandomizationContext::new(
rerand_domain_separator,
// First is the function description, second is a nonce
[b"FheUint64+FheUint64".as_slice(), nonce.as_slice()],
compact_public_encryption_domain_separator,
);
// Add ciphertexts to the context
re_rand_context.add_ciphertext(&a);
re_rand_context.add_ciphertext(&b);
// Get the seeds for the rerandomization
let mut seed_gen = re_rand_context.finalize();
// Re-Randomize a and b
a.re_randomize(&cpk, seed_gen.next_seed().unwrap()).unwrap();
b.re_randomize(&cpk, seed_gen.next_seed().unwrap()).unwrap();
// Compute our function F
a + b
};
// Check everything went well
let dec: u64 = c.decrypt(&cks);
assert_eq!(clear_a.wrapping_add(clear_b), dec);
}Last updated
Was this helpful?