use std::ffi::c_void;
use std::ptr::null_mut;
use crate::bindgen;
use crate::error::*;
use crate::{Ciphertext, Context, Plaintext, RelinearizationKeys};
pub struct EvaluatorBase {
handle: *mut c_void,
}
unsafe impl Sync for EvaluatorBase {}
unsafe impl Send for EvaluatorBase {}
impl Drop for EvaluatorBase {
fn drop(&mut self) {
convert_seal_error(unsafe { bindgen::Evaluator_Destroy(self.handle) })
.expect("Internal error in Evaluator::drop()");
}
}
impl EvaluatorBase {
pub(crate) fn new(ctx: &Context) -> Result<Self> {
let mut handle = null_mut();
convert_seal_error(unsafe { bindgen::Evaluator_Create(ctx.get_handle(), &mut handle) })?;
Ok(Self { handle })
}
pub fn get_handle(&self) -> *mut c_void {
self.handle
}
pub(crate) fn negate_inplace(&self, a: &mut Ciphertext) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_Negate(self.handle, a.get_handle(), a.get_handle())
})?;
Ok(())
}
pub(crate) fn negate(&self, a: &Ciphertext) -> Result<Ciphertext> {
let out = Ciphertext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_Negate(self.handle, a.get_handle(), out.get_handle())
})?;
Ok(out)
}
pub(crate) fn add_inplace(&self, a: &mut Ciphertext, b: &Ciphertext) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_Add(self.handle, a.get_handle(), b.get_handle(), a.get_handle())
})?;
Ok(())
}
pub(crate) fn add(&self, a: &Ciphertext, b: &Ciphertext) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_Add(self.handle, a.get_handle(), b.get_handle(), c.get_handle())
})?;
Ok(c)
}
pub(crate) fn add_many(&self, a: &[Ciphertext]) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
let mut a = a
.iter()
.map(|x| x.get_handle())
.collect::<Vec<*mut c_void>>();
convert_seal_error(unsafe {
bindgen::Evaluator_AddMany(self.handle, a.len() as u64, a.as_mut_ptr(), c.get_handle())
})?;
Ok(c)
}
pub(crate) fn multiply_many(
&self,
a: &[Ciphertext],
relin_keys: &RelinearizationKeys,
) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
let mut a = a
.iter()
.map(|x| x.get_handle())
.collect::<Vec<*mut c_void>>();
convert_seal_error(unsafe {
bindgen::Evaluator_MultiplyMany(
self.handle,
a.len() as u64,
a.as_mut_ptr(),
relin_keys.get_handle(),
c.get_handle(),
null_mut(),
)
})?;
Ok(c)
}
pub(crate) fn sub_inplace(&self, a: &mut Ciphertext, b: &Ciphertext) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_Sub(self.handle, a.get_handle(), b.get_handle(), a.get_handle())
})?;
Ok(())
}
pub(crate) fn sub(&self, a: &Ciphertext, b: &Ciphertext) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_Sub(self.handle, a.get_handle(), b.get_handle(), c.get_handle())
})?;
Ok(c)
}
pub(crate) fn multiply_inplace(&self, a: &mut Ciphertext, b: &Ciphertext) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_Multiply(
self.handle,
a.get_handle(),
b.get_handle(),
a.get_handle(),
null_mut(),
)
})?;
Ok(())
}
pub(crate) fn multiply(&self, a: &Ciphertext, b: &Ciphertext) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_Multiply(
self.handle,
a.get_handle(),
b.get_handle(),
c.get_handle(),
null_mut(),
)
})?;
Ok(c)
}
pub(crate) fn square_inplace(&self, a: &mut Ciphertext) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_Square(self.handle, a.get_handle(), a.get_handle(), null_mut())
})?;
Ok(())
}
pub(crate) fn square(&self, a: &Ciphertext) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_Square(self.handle, a.get_handle(), c.get_handle(), null_mut())
})?;
Ok(c)
}
pub(crate) fn mod_switch_to_next(&self, a: &Ciphertext) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_ModSwitchToNext1(
self.get_handle(),
a.get_handle(),
c.get_handle(),
null_mut(),
)
})?;
Ok(c)
}
pub(crate) fn mod_switch_to_next_inplace(&self, a: &Ciphertext) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_ModSwitchToNext1(
self.get_handle(),
a.get_handle(),
a.get_handle(),
null_mut(),
)
})?;
Ok(())
}
pub(crate) fn mod_switch_to_next_plaintext(&self, a: &Plaintext) -> Result<Plaintext> {
let p = Plaintext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_ModSwitchToNext2(self.get_handle(), a.get_handle(), p.get_handle())
})?;
Ok(p)
}
pub(crate) fn mod_switch_to_next_inplace_plaintext(&self, a: &Plaintext) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_ModSwitchToNext2(self.get_handle(), a.get_handle(), a.get_handle())
})?;
Ok(())
}
pub(crate) fn exponentiate(
&self,
a: &Ciphertext,
exponent: u64,
relin_keys: &RelinearizationKeys,
) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_Exponentiate(
self.get_handle(),
a.get_handle(),
exponent,
relin_keys.get_handle(),
c.get_handle(),
null_mut(),
)
})?;
Ok(c)
}
pub(crate) fn exponentiate_inplace(
&self,
a: &Ciphertext,
exponent: u64,
relin_keys: &RelinearizationKeys,
) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_Exponentiate(
self.get_handle(),
a.get_handle(),
exponent,
relin_keys.get_handle(),
a.get_handle(),
null_mut(),
)
})?;
Ok(())
}
pub(crate) fn add_plain(&self, a: &Ciphertext, b: &Plaintext) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_AddPlain(
self.get_handle(),
a.get_handle(),
b.get_handle(),
c.get_handle(),
)
})?;
Ok(c)
}
pub(crate) fn add_plain_inplace(&self, a: &mut Ciphertext, b: &Plaintext) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_AddPlain(
self.get_handle(),
a.get_handle(),
b.get_handle(),
a.get_handle(),
)
})?;
Ok(())
}
pub(crate) fn sub_plain(&self, a: &Ciphertext, b: &Plaintext) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_SubPlain(
self.get_handle(),
a.get_handle(),
b.get_handle(),
c.get_handle(),
)
})?;
Ok(c)
}
pub(crate) fn sub_plain_inplace(&self, a: &mut Ciphertext, b: &Plaintext) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_SubPlain(
self.get_handle(),
a.get_handle(),
b.get_handle(),
a.get_handle(),
)
})?;
Ok(())
}
pub(crate) fn multiply_plain(&self, a: &Ciphertext, b: &Plaintext) -> Result<Ciphertext> {
let c = Ciphertext::new()?;
convert_seal_error(unsafe {
bindgen::Evaluator_MultiplyPlain(
self.get_handle(),
a.get_handle(),
b.get_handle(),
c.get_handle(),
null_mut(),
)
})?;
Ok(c)
}
pub(crate) fn multiply_plain_inplace(&self, a: &mut Ciphertext, b: &Plaintext) -> Result<()> {
convert_seal_error(unsafe {
bindgen::Evaluator_MultiplyPlain(
self.get_handle(),
a.get_handle(),
b.get_handle(),
a.get_handle(),
null_mut(),
)
})?;
Ok(())
}
}