use crate::shortint::atomic_pattern::AtomicPattern;
use crate::shortint::ciphertext::Degree;
use crate::shortint::server_key::GenericServerKey;
use crate::shortint::Ciphertext;
impl<AP: AtomicPattern> GenericServerKey<AP> {
pub fn scalar_bitand(&self, lhs: &Ciphertext, rhs: u8) -> Ciphertext {
let mut ct_res = lhs.clone();
self.scalar_bitand_assign(&mut ct_res, rhs);
ct_res
}
pub fn scalar_bitand_assign(&self, lhs: &mut Ciphertext, rhs: u8) {
if !lhs.carry_is_empty() {
self.message_extract_assign(lhs);
}
self.unchecked_scalar_bitand_assign(lhs, rhs);
}
pub fn unchecked_scalar_bitand(&self, lhs: &Ciphertext, rhs: u8) -> Ciphertext {
let mut result = lhs.clone();
self.unchecked_scalar_bitand_assign(&mut result, rhs);
result
}
pub fn unchecked_scalar_bitand_assign(&self, lhs: &mut Ciphertext, rhs: u8) {
let new_degree = lhs.degree.after_bitand(Degree::new(u64::from(rhs)));
self.evaluate_msg_univariate_function_assign(lhs, |x| x & rhs as u64);
lhs.degree = new_degree;
}
#[allow(clippy::needless_pass_by_ref_mut)]
pub fn smart_scalar_bitand(&self, lhs: &mut Ciphertext, rhs: u8) -> Ciphertext {
let mut result = lhs.clone();
self.smart_scalar_bitand_assign(&mut result, rhs);
result
}
pub fn smart_scalar_bitand_assign(&self, lhs: &mut Ciphertext, rhs: u8) {
self.unchecked_scalar_bitand_assign(lhs, rhs);
}
pub fn scalar_bitxor(&self, lhs: &Ciphertext, rhs: u8) -> Ciphertext {
let mut ct_res = lhs.clone();
self.scalar_bitxor_assign(&mut ct_res, rhs);
ct_res
}
pub fn scalar_bitxor_assign(&self, lhs: &mut Ciphertext, rhs: u8) {
if !lhs.carry_is_empty() {
self.message_extract_assign(lhs);
}
self.unchecked_scalar_bitxor_assign(lhs, rhs);
}
pub fn unchecked_scalar_bitxor(&self, lhs: &Ciphertext, rhs: u8) -> Ciphertext {
let mut result = lhs.clone();
self.unchecked_scalar_bitxor_assign(&mut result, rhs);
result
}
pub fn unchecked_scalar_bitxor_assign(&self, lhs: &mut Ciphertext, rhs: u8) {
let new_degree = lhs.degree.after_bitxor(Degree::new(u64::from(rhs)));
self.evaluate_msg_univariate_function_assign(lhs, |x| x ^ rhs as u64);
lhs.degree = new_degree;
}
#[allow(clippy::needless_pass_by_ref_mut)]
pub fn smart_scalar_bitxor(&self, lhs: &mut Ciphertext, rhs: u8) -> Ciphertext {
let mut result = lhs.clone();
self.smart_scalar_bitxor_assign(&mut result, rhs);
result
}
pub fn smart_scalar_bitxor_assign(&self, lhs: &mut Ciphertext, rhs: u8) {
self.unchecked_scalar_bitxor_assign(lhs, rhs);
}
pub fn scalar_bitor(&self, lhs: &Ciphertext, rhs: u8) -> Ciphertext {
let mut ct_res = lhs.clone();
self.scalar_bitor_assign(&mut ct_res, rhs);
ct_res
}
pub fn scalar_bitor_assign(&self, lhs: &mut Ciphertext, rhs: u8) {
if !lhs.carry_is_empty() {
self.message_extract_assign(lhs);
}
self.unchecked_scalar_bitor_assign(lhs, rhs);
}
pub fn unchecked_scalar_bitor(&self, lhs: &Ciphertext, rhs: u8) -> Ciphertext {
let mut result = lhs.clone();
self.unchecked_scalar_bitor_assign(&mut result, rhs);
result
}
pub fn unchecked_scalar_bitor_assign(&self, lhs: &mut Ciphertext, rhs: u8) {
let new_degree = lhs.degree.after_bitor(Degree::new(u64::from(rhs)));
self.evaluate_msg_univariate_function_assign(lhs, |x| x | rhs as u64);
lhs.degree = new_degree;
}
#[allow(clippy::needless_pass_by_ref_mut)]
pub fn smart_scalar_bitor(&self, lhs: &mut Ciphertext, rhs: u8) -> Ciphertext {
let mut result = lhs.clone();
self.smart_scalar_bitor_assign(&mut result, rhs);
result
}
pub fn smart_scalar_bitor_assign(&self, lhs: &mut Ciphertext, rhs: u8) {
self.unchecked_scalar_bitor_assign(lhs, rhs);
}
}