use std::ops::{Add, AddAssign, Mul, MulAssign, Sub};
use tfhe::shortint::prelude::*;
pub struct CipherTextType{
pub CipherTxt: Option<Ciphertext>,
pub ServerKey: Option<ServerKey>,
pub Modulus: Option<u64>
}
impl CipherTextType{
fn new(_CipherTxt: Ciphertext, _ServerKey: ServerKey, _Modulus: u64) -> CipherTextType{
CipherTextType{
CipherTxt: Some(_CipherTxt),
ServerKey: Some(_ServerKey),
Modulus: Some(_Modulus)
}
}
fn is_def(&self) -> bool {
if self.CipherTxt.is_none() || self.ServerKey.is_none() || self.Modulus.is_none() {
return true;
}
false
}
}
impl Clone for CipherTextType{
fn clone(&self) -> Self {
if self.is_def() {
CipherTextType::new(self.CipherTxt.clone().unwrap(), self.ServerKey.clone().unwrap(), self.Modulus.clone().unwrap())
}
else{
CipherTextType::default()
}
}
}
impl Default for CipherTextType{
fn default() -> Self {
CipherTextType{
CipherTxt: None,
ServerKey: None,
Modulus: None
}
}
}
impl Add for CipherTextType {
type Output = Option<CipherTextType>;
fn add(self, rhs: Self) -> Self::Output {
if !self.is_def() && !rhs.is_def() {
let _ciphertext = self.ServerKey.clone().unwrap().unchecked_add(&self.CipherTxt.unwrap(), &rhs.CipherTxt.unwrap());
return Some(CipherTextType::new(_ciphertext, self.ServerKey.clone().unwrap(), self.Modulus.clone().unwrap()));
}
else if !self.is_def() && rhs.is_def() {
return Some(self.clone());
}
else if self.is_def() && !rhs.is_def() {
return Some(rhs.clone());
}
None
}
}
impl Mul for CipherTextType {
type Output = Option<CipherTextType>;
fn mul(self, rhs: Self) -> Self::Output {
if !self.is_def() || !rhs.is_def() {
let _ciphertext = self.ServerKey.clone().unwrap().smart_mul_lsb(&mut self.CipherTxt.unwrap(), &mut rhs.CipherTxt.unwrap());
Some(CipherTextType::new(_ciphertext, self.ServerKey.clone().unwrap(), self.Modulus.clone().unwrap()));
}
None
}
}
impl Sub for CipherTextType {
type Output = Option<CipherTextType>;
fn sub(self, rhs: Self) -> Self::Output {
if !self.is_def() || !rhs.is_def() {
let _ciphertext = self.ServerKey.clone().unwrap().unchecked_sub(&self.CipherTxt.unwrap(), &rhs.CipherTxt.unwrap());
Some(CipherTextType::new(_ciphertext, self.ServerKey.clone().unwrap(), self.Modulus.clone().unwrap()));
}
None
}
}
impl AddAssign for CipherTextType {
fn add_assign(&mut self, rhs: Self) {
if !self.is_def() || !rhs.is_def() {
let _ciphertext = self.ServerKey.clone().unwrap().unchecked_add(&self.CipherTxt.clone().unwrap(), &rhs.CipherTxt.clone().unwrap());
self.CipherTxt = Some(_ciphertext);
}
}
}
impl MulAssign for CipherTextType {
fn mul_assign(&mut self, rhs: Self) {
if !self.is_def() || !rhs.is_def() {
let _ciphertext = self.ServerKey.clone().unwrap().smart_mul_lsb(&mut self.CipherTxt.clone().unwrap(), &mut rhs.CipherTxt.clone().unwrap());
self.CipherTxt = Some(_ciphertext);
}
}
}