Key upgrade
use tfhe::shortint::parameters::{
COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
};
use tfhe::prelude::*;
use tfhe::{ConfigBuilder, set_server_key, ServerKey, ClientKey, FheUint32, KeySwitchingKey, Device};
use tfhe::upgrade::UpgradeKeyChain;
fn main() {
let compute_params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let compression_parameters = COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let config = ConfigBuilder::with_custom_parameters(compute_params)
.enable_compression(compression_parameters)
.build();
let (cks_1, sks_1) = {
let mut ck = ClientKey::generate(config);
ck.tag_mut().set_u64(1);
let sk = ServerKey::new(&ck);
(ck, sk)
};
let (cks_2, sks_2) = {
let mut ck = ClientKey::generate(config);
ck.tag_mut().set_u64(2);
let sk = ServerKey::new(&ck);
(ck, sk)
};
// Create a ksk that upgrades from the first key, to the second key
let ksk = KeySwitchingKey::with_parameters(
(&cks_1, &sks_1),
(&cks_2, &sks_2),
PARAM_KEYSWITCH_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
);
let mut upgrader = UpgradeKeyChain::default();
// First, add the server keys
// to register the different possible parameters
upgrader.add_key_set(&sks_1);
upgrader.add_key_set(&sks_2);
// Add our upgrade key
upgrader.add_upgrade_key(ksk).unwrap();
let clear_a = rand::random::<u32>();
let clear_b = rand::random::<u32>();
let a = FheUint32::encrypt(clear_a, &cks_1);
let b = FheUint32::encrypt(clear_b, &cks_1);
let upgraded_a = upgrader
.upgrade(&a, sks_2.tag(), Device::Cpu)
.unwrap();
let upgraded_b = upgrader
.upgrade(&b, sks_2.tag(), Device::Cpu)
.unwrap();
set_server_key(sks_2.clone());
let c = upgraded_a + upgraded_b;
let dc: u32 = c.decrypt(&cks_2);
assert_eq!(dc, clear_a.wrapping_add(clear_b));
}Last updated
Was this helpful?