Thank you so much!
I am also wondering if I can do it at the Boolean level. I could get to the engine\mod.rs
file that contains the implementation of the Boolean gates operation. For example, the or
function is implemented as follows:
fn or(
&mut self,
ct_left: &Ciphertext,
ct_right: &Ciphertext,
server_key: &ServerKey,
) -> Ciphertext {
match (ct_left, ct_right) {
(Ciphertext::Trivial(message_left), Ciphertext::Trivial(message_right)) => {
Ciphertext::Trivial(*message_left || *message_right)
}
(Ciphertext::Encrypted(_), Ciphertext::Trivial(message_right)) => {
self.or(ct_left, *message_right, server_key)
}
(Ciphertext::Trivial(message_left), Ciphertext::Encrypted(_)) => {
self.or(*message_left, ct_right, server_key)
}
(Ciphertext::Encrypted(ct_left_ct), Ciphertext::Encrypted(ct_right_ct)) => {
let mut buffer_lwe_before_pbs = LweCiphertext::new(
0u32,
ct_left_ct.lwe_size(),
ct_left_ct.ciphertext_modulus(),
);
let bootstrapper = &mut self.bootstrapper;
// Compute the linear combination for OR: ct_left + ct_right + (0,...,0,+1/8)
// ct_left + ct_right
lwe_ciphertext_add(&mut buffer_lwe_before_pbs, ct_left_ct, ct_right_ct);
let cst = Plaintext(PLAINTEXT_TRUE);
// + 1/8
lwe_ciphertext_plaintext_add_assign(&mut buffer_lwe_before_pbs, cst);
// compute the bootstrap and the key switch
bootstrapper.apply_bootstrapping_pattern(buffer_lwe_before_pbs, server_key)
}
}
}
I am trying to separate the Bootstrapping from the Boolean gate operation itself like the following:
fn or(
&mut self,
ct_left: &Ciphertext,
ct_right: &Ciphertext,
server_key: &ServerKey,
) -> Ciphertext {
match (ct_left, ct_right) {
(Ciphertext::Trivial(message_left), Ciphertext::Trivial(message_right)) => {
Ciphertext::Trivial(*message_left || *message_right)
}
(Ciphertext::Encrypted(_), Ciphertext::Trivial(message_right)) => {
self.or(ct_left, *message_right, server_key)
}
(Ciphertext::Trivial(message_left), Ciphertext::Encrypted(_)) => {
self.or(*message_left, ct_right, server_key)
}
(Ciphertext::Encrypted(ct_left_ct), Ciphertext::Encrypted(ct_right_ct)) => {
let mut buffer_lwe_before_pbs = LweCiphertext::new(
0u32,
ct_left_ct.lwe_size(),
ct_left_ct.ciphertext_modulus(),
);
// Compute the linear combination for OR: ct_left + ct_right + (0,...,0,+1/8)
// ct_left + ct_right
lwe_ciphertext_add(&mut buffer_lwe_before_pbs, ct_left_ct, ct_right_ct);
let cst = Plaintext(PLAINTEXT_TRUE);
// + 1/8
lwe_ciphertext_plaintext_add_assign(&mut buffer_lwe_before_pbs, cst);
// Removed bootstrapping //
Ciphertext::Encrypted(buffer_lwe_before_pbs)
}
}
}
Then I have another bootstrapping function contains the bootstrapping operation:
fn bootstrape_ctxt(buffer_lwe_before_pbfs: Ciphertext, server_key: ServerKey){
let bootstrapper = &mut self.bootstrapper;
// compute the bootstrap and the key switch
bootstrapper.apply_bootstrapping_pattern(buffer_lwe_before_pbs, server_key)
}
The problem I face is that the functions and structs are well-baked together so that modifying the mod.rs
will causes errors.
So, any ideas for implementing this?