Bläddra i källkod

Adding new functions part 2

Hovsep Papoyan 11 månader sedan
förälder
incheckning
77b7270f41
5 ändrade filer med 265 tillägg och 163 borttagningar
  1. 5 5
      examples/polynomial_evaluation.rs
  2. 15 15
      examples/simple_real_numbers.rs
  3. 119 60
      src/bindings.cc
  4. 51 24
      src/bindings.hpp
  5. 75 59
      src/lib.rs

+ 5 - 5
examples/polynomial_evaluation.rs

@@ -81,21 +81,21 @@ fn main()
     print!("Generating evaluation key for homomorphic multiplication...");
     _cc.EvalMultKeyGen(_key_pair.GetPrivateKey());
     println!("Completed.\n");
-    let mut _cipher_text_1 = _cc.Encrypt(_key_pair.GetPublicKey(), _plain_text_1.GetPlainText());
+    let mut _cipher_text_1 = _cc.Encrypt(_key_pair.GetPublicKey(), &_plain_text_1);
 
     let mut _start = Instant::now();
-    let mut _result = _cc.EvalPoly(_cipher_text_1.GetCipherText(), &_coefficients_1);
+    let mut _result = _cc.EvalPoly(&_cipher_text_1, &_coefficients_1);
     let _time_eval_poly_1 = _start.elapsed();
 
     _start = Instant::now();
-    let mut _result_2 = _cc.EvalPoly(_cipher_text_1.GetCipherText(), &_coefficients_2);
+    let mut _result_2 = _cc.EvalPoly(&_cipher_text_1, &_coefficients_2);
     let _time_eval_poly_2 = _start.elapsed();
 
     let mut _plain_text_dec = ffi::GenEmptyPlainText();
-    _cc.Decrypt(_key_pair.GetPrivateKey(), _result.GetCipherText(), _plain_text_dec.pin_mut());
+    _cc.Decrypt(_key_pair.GetPrivateKey(), &_result, _plain_text_dec.pin_mut());
     _plain_text_dec.SetLength(_encoded_length);
     let mut _plain_text_dec_2 = ffi::GenEmptyPlainText();
-    _cc.Decrypt(_key_pair.GetPrivateKey(), _result_2.GetCipherText(), _plain_text_dec_2.pin_mut());
+    _cc.Decrypt(_key_pair.GetPrivateKey(), &_result_2, _plain_text_dec_2.pin_mut());
     _plain_text_dec_2.SetLength(_encoded_length);
 
     println!("\n Original Plaintext #1:");

+ 15 - 15
examples/simple_real_numbers.rs

@@ -52,45 +52,45 @@ fn main()
     println!("Input x1: {}", _p_txt_1.GetString());
     println!("Input x2: {}", _p_txt_2.GetString());
 
-    let mut _c1 = _cc.Encrypt(_key_pair.GetPublicKey(), _p_txt_1.GetPlainText());
-    let mut _c2 = _cc.Encrypt(_key_pair.GetPublicKey(), _p_txt_2.GetPlainText());
+    let mut _c1 = _cc.Encrypt(_key_pair.GetPublicKey(), &_p_txt_1);
+    let mut _c2 = _cc.Encrypt(_key_pair.GetPublicKey(), &_p_txt_2);
 
-    let mut _c_add = _cc.EvalAdd(_c1.GetCipherText(), _c2.GetCipherText());
-    let mut _c_sub = _cc.EvalSub(_c1.GetCipherText(), _c2.GetCipherText());
-    let mut _c_scalar = _cc.EvalMultByConst(_c1.GetCipherText(), 4.0);
-    let mut _c_mul = _cc.EvalMult(_c1.GetCipherText(), _c2.GetCipherText());
-    let mut _c_rot_1 = _cc.EvalRotate(_c1.GetCipherText(), 1);
-    let mut _c_rot_2 = _cc.EvalRotate(_c1.GetCipherText(), -2);
+    let mut _c_add = _cc.EvalAdd(&_c1, &_c2);
+    let mut _c_sub = _cc.EvalSub(&_c1, &_c2);
+    let mut _c_scalar = _cc.EvalMultByConst(&_c1, 4.0);
+    let mut _c_mul = _cc.EvalMult(&_c1, &_c2);
+    let mut _c_rot_1 = _cc.EvalRotate(&_c1, 1);
+    let mut _c_rot_2 = _cc.EvalRotate(&_c1, -2);
 
     let mut _result = ffi::GenEmptyPlainText();
     println!("\nResults of homomorphic computations:");
 
-    _cc.Decrypt(_key_pair.GetPrivateKey(), _c1.GetCipherText(), _result.pin_mut());
+    _cc.Decrypt(_key_pair.GetPrivateKey(), &_c1, _result.pin_mut());
     _result.SetLength(_batch_size.try_into().unwrap());
     println!("x1 = {}Estimated precision in bits: {}", _result.GetString(), _result.GetLogPrecision());
 
-    _cc.Decrypt(_key_pair.GetPrivateKey(), _c_add.GetCipherText(), _result.pin_mut());
+    _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_add, _result.pin_mut());
     _result.SetLength(_batch_size.try_into().unwrap());
     println!("x1 + x2 = {}Estimated precision in bits: {}",_result.GetString(), _result.GetLogPrecision());
 
-    _cc.Decrypt(_key_pair.GetPrivateKey(), _c_sub.GetCipherText(), _result.pin_mut());
+    _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_sub, _result.pin_mut());
     _result.SetLength(_batch_size.try_into().unwrap());
     println!("x1 - x2 = {}", _result.GetString());
 
-    _cc.Decrypt(_key_pair.GetPrivateKey(), _c_scalar.GetCipherText(), _result.pin_mut());
+    _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_scalar, _result.pin_mut());
     _result.SetLength(_batch_size.try_into().unwrap());
     println!("4 * x1 = {}", _result.GetString());
 
-    _cc.Decrypt(_key_pair.GetPrivateKey(), _c_mul.GetCipherText(), _result.pin_mut());
+    _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_mul, _result.pin_mut());
     _result.SetLength(_batch_size.try_into().unwrap());
     println!("x1 * x2 = {}", _result.GetString());
 
-    _cc.Decrypt(_key_pair.GetPrivateKey(), _c_rot_1.GetCipherText(), _result.pin_mut());
+    _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_rot_1, _result.pin_mut());
     _result.SetLength(_batch_size.try_into().unwrap());
     println!("\nIn rotations, very small outputs (~10^-10 here) correspond to 0's:");
     println!("x1 rotate by 1 = {}", _result.GetString());
 
-    _cc.Decrypt(_key_pair.GetPrivateKey(), _c_rot_2.GetCipherText(), _result.pin_mut());
+    _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_rot_2, _result.pin_mut());
     _result.SetLength(_batch_size.try_into().unwrap());
     println!("x1 rotate by -2 = {}", _result.GetString());
 }

+ 119 - 60
src/bindings.cc

@@ -12,6 +12,10 @@ namespace openfhe
 PublicKeyDCRTPoly::PublicKeyDCRTPoly()
     : m_publicKey(std::make_shared<PublicKeyImpl>())
 { }
+std::shared_ptr<PublicKeyImpl> PublicKeyDCRTPoly::GetInternal() const
+{
+    return m_publicKey;
+}
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -38,7 +42,7 @@ Plaintext& Plaintext::operator=(std::shared_ptr<PlaintextImpl> plaintext)
     m_plaintext = plaintext;
     return *this;
 }
-std::shared_ptr<PlaintextImpl> Plaintext::GetPlainText() const
+std::shared_ptr<PlaintextImpl> Plaintext::GetInternal() const
 {
     return m_plaintext;
 }
@@ -65,7 +69,7 @@ CiphertextDCRTPoly::CiphertextDCRTPoly()
 CiphertextDCRTPoly::CiphertextDCRTPoly(std::shared_ptr<CiphertextImpl> ciphertext)
     : m_ciphertext(ciphertext)
 { }
-std::shared_ptr<CiphertextImpl> CiphertextDCRTPoly::GetCipherText() const
+std::shared_ptr<CiphertextImpl> CiphertextDCRTPoly::GetInternal() const
 {
     return m_ciphertext;
 }
@@ -116,6 +120,10 @@ void CryptoContextDCRTPoly::EvalRotateKeyGen(
 {
     m_cryptoContextImplSharedPtr->EvalRotateKeyGen(privateKey, indexList, publicKey);
 }
+void CryptoContextDCRTPoly::EvalCKKStoFHEWPrecompute(const double scale) const
+{
+    m_cryptoContextImplSharedPtr->EvalCKKStoFHEWPrecompute(scale);
+}
 std::unique_ptr<Plaintext> CryptoContextDCRTPoly::MakePackedPlaintext(
     const std::vector<int64_t>& value, const size_t noiseScaleDeg,
     const uint32_t level) const
@@ -125,67 +133,117 @@ std::unique_ptr<Plaintext> CryptoContextDCRTPoly::MakePackedPlaintext(
 }
 std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::Encrypt(
     const std::shared_ptr<lbcrypto::PublicKeyImpl<lbcrypto::DCRTPoly>> publicKey,
-    std::shared_ptr<PlaintextImpl> plaintext) const
+    const Plaintext& plaintext) const
 {
     return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->Encrypt(
-        publicKey, plaintext));
+        publicKey, plaintext.GetInternal()));
 }
 std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalAdd(
-    std::shared_ptr<CiphertextImpl> ciphertext1, std::shared_ptr<CiphertextImpl> ciphertext2) const
+    const CiphertextDCRTPoly& ciphertext1, const CiphertextDCRTPoly& ciphertext2) const
 {
     return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->EvalAdd(
-        ciphertext1, ciphertext2));
+        ciphertext1.GetInternal(), ciphertext2.GetInternal()));
 }
 std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalSub(
-    std::shared_ptr<CiphertextImpl> ciphertext1, std::shared_ptr<CiphertextImpl> ciphertext2) const
+    const CiphertextDCRTPoly& ciphertext1, const CiphertextDCRTPoly& ciphertext2) const
 {
     return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->EvalSub(
-        ciphertext1, ciphertext2));
+        ciphertext1.GetInternal(), ciphertext2.GetInternal()));
 }
 std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalMult(
-    std::shared_ptr<CiphertextImpl> ciphertext1, std::shared_ptr<CiphertextImpl> ciphertext2) const
+    const CiphertextDCRTPoly& ciphertext1, const CiphertextDCRTPoly& ciphertext2) const
 {
     return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->EvalMult(
-        ciphertext1, ciphertext2));
+        ciphertext1.GetInternal(), ciphertext2.GetInternal()));
 }
 std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalMultNoRelin(
-    std::shared_ptr<CiphertextImpl> ciphertext1, std::shared_ptr<CiphertextImpl> ciphertext2) const
+    const CiphertextDCRTPoly& ciphertext1, const CiphertextDCRTPoly& ciphertext2) const
 {
     return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->EvalMultNoRelin(
-        ciphertext1, ciphertext2));
+        ciphertext1.GetInternal(), ciphertext2.GetInternal()));
 }
 std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalMultAndRelinearize(
-    std::shared_ptr<CiphertextImpl> ciphertext1, std::shared_ptr<CiphertextImpl> ciphertext2) const
+    const CiphertextDCRTPoly& ciphertext1, const CiphertextDCRTPoly& ciphertext2) const
 {
     return std::make_unique<CiphertextDCRTPoly>(
-        m_cryptoContextImplSharedPtr->EvalMultAndRelinearize(ciphertext1, ciphertext2));
+        m_cryptoContextImplSharedPtr->EvalMultAndRelinearize(ciphertext1.GetInternal(),
+        ciphertext2.GetInternal()));
 }
 std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalMultByConst(
-    std::shared_ptr<CiphertextImpl> ciphertext, const double constant) const
+    const CiphertextDCRTPoly& ciphertext, const double constant) const
 {
     return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->EvalMult(
-        ciphertext, constant));
+        ciphertext.GetInternal(), constant));
 }
 std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalRotate(
-    std::shared_ptr<CiphertextImpl> ciphertext, const int32_t index) const
+    const CiphertextDCRTPoly& ciphertext, const int32_t index) const
 {
     return std::make_unique<CiphertextDCRTPoly>(
-        m_cryptoContextImplSharedPtr->EvalRotate(ciphertext, index));
+        m_cryptoContextImplSharedPtr->EvalRotate(ciphertext.GetInternal(), index));
 }
 std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalChebyshevSeries(
-    std::shared_ptr<CiphertextImpl> ciphertext, const std::vector<double>& coefficients,
+    const CiphertextDCRTPoly& ciphertext, const std::vector<double>& coefficients,
     const double a, const double b) const
 {
     return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->EvalChebyshevSeries(
-        ciphertext, coefficients, a, b));
+        ciphertext.GetInternal(), coefficients, a, b));
+}
+std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalBootstrap(
+    const CiphertextDCRTPoly& ciphertext, const uint32_t numIterations,
+    const uint32_t precision) const
+{
+    return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->EvalBootstrap(
+        ciphertext.GetInternal(), numIterations, precision));
+}
+std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::Rescale(
+    const CiphertextDCRTPoly& ciphertext) const
+{
+    return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->Rescale(
+        ciphertext.GetInternal()));
+}
+std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::ModReduce(
+    const CiphertextDCRTPoly& ciphertext) const
+{
+    return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->ModReduce(
+        ciphertext.GetInternal()));
+}
+std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalSum(
+    const CiphertextDCRTPoly& ciphertext, const uint32_t batchSize) const
+{
+    return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->EvalSum(
+        ciphertext.GetInternal(), batchSize));
+}
+std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::IntMPBootAdjustScale(
+    const CiphertextDCRTPoly& ciphertext) const
+{
+    return std::make_unique<CiphertextDCRTPoly>(m_cryptoContextImplSharedPtr->IntMPBootAdjustScale(
+        ciphertext.GetInternal()));
+}
+std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::IntMPBootRandomElementGen(
+    const PublicKeyDCRTPoly& publicKey) const
+{
+    return std::make_unique<CiphertextDCRTPoly>(
+        m_cryptoContextImplSharedPtr->IntMPBootRandomElementGen(publicKey.GetInternal()));
+}
+void CryptoContextDCRTPoly::EvalBootstrapSetup(
+    const std::vector<uint32_t>& levelBudget, const std::vector<uint32_t>& dim1,
+    const uint32_t slots, const uint32_t correctionFactor, const bool precompute) const
+{
+    m_cryptoContextImplSharedPtr->EvalBootstrapSetup(levelBudget, dim1, slots, correctionFactor,
+        precompute);
+}
+void CryptoContextDCRTPoly::EvalBootstrapKeyGen(const std::shared_ptr<PrivateKeyImpl> privateKey,
+    const uint32_t slots) const
+{
+    m_cryptoContextImplSharedPtr->EvalBootstrapKeyGen(privateKey, slots);
 }
 std::unique_ptr<DecryptResult> CryptoContextDCRTPoly::Decrypt(
     const std::shared_ptr<PrivateKeyImpl> privateKey,
-    std::shared_ptr<CiphertextImpl> ciphertext, Plaintext& plaintext) const
+    const CiphertextDCRTPoly& ciphertext, Plaintext& plaintext) const
 {
     std::shared_ptr<PlaintextImpl> res;
     std::unique_ptr<DecryptResult> result = std::make_unique<DecryptResult>(
-        m_cryptoContextImplSharedPtr->Decrypt(privateKey, ciphertext, &res));
+        m_cryptoContextImplSharedPtr->Decrypt(privateKey, ciphertext.GetInternal(), &res));
     plaintext = res;
     return result;
 }
@@ -193,6 +251,10 @@ uint32_t CryptoContextDCRTPoly::GetRingDimension() const
 {
     return m_cryptoContextImplSharedPtr->GetRingDimension();
 }
+uint32_t CryptoContextDCRTPoly::GetCyclotomicOrder() const
+{
+    return m_cryptoContextImplSharedPtr->GetCyclotomicOrder();
+}
 std::unique_ptr<Plaintext> CryptoContextDCRTPoly::MakeCKKSPackedPlaintext(
     const std::vector<double>& value, const size_t scaleDeg, const uint32_t level,
     const std::shared_ptr<DCRTPolyParams> params, const uint32_t slots) const
@@ -201,10 +263,10 @@ std::unique_ptr<Plaintext> CryptoContextDCRTPoly::MakeCKKSPackedPlaintext(
         value, scaleDeg, level, params, slots));
 }
 std::unique_ptr<CiphertextDCRTPoly> CryptoContextDCRTPoly::EvalPoly(
-    std::shared_ptr<CiphertextImpl> ciphertext, const std::vector<double>& coefficients) const
+    const CiphertextDCRTPoly& ciphertext, const std::vector<double>& coefficients) const
 {
     return std::make_unique<CiphertextDCRTPoly>(
-        m_cryptoContextImplSharedPtr->EvalPoly(ciphertext, coefficients));
+        m_cryptoContextImplSharedPtr->EvalPoly(ciphertext.GetInternal(), coefficients));
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -282,6 +344,9 @@ std::unique_ptr<CiphertextDCRTPoly> GenDefaultConstructedCiphertext()
 {
     return std::make_unique<CiphertextDCRTPoly>();
 }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 bool SerializeCryptoContextToFile(const std::string& ccLocation,
     const CryptoContextDCRTPoly& cryptoContext, const SerialMode serialMode)
 {
@@ -323,13 +388,13 @@ bool SerializeEvalMultKeyToFile(const std::string& multKeyLocation,
     {
         if (serialMode == SerialMode::BINARY)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalMultKey(
-                *ofs, lbcrypto::SerType::BINARY, cryptoContext.m_cryptoContextImplSharedPtr);
+            return CryptoContextImpl::SerializeEvalMultKey(*ofs,
+                lbcrypto::SerType::BINARY, cryptoContext.m_cryptoContextImplSharedPtr);
         }
         if (serialMode == SerialMode::JSON)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalMultKey(
-                *ofs, lbcrypto::SerType::JSON, cryptoContext.m_cryptoContextImplSharedPtr);
+            return CryptoContextImpl::SerializeEvalMultKey(*ofs,
+                lbcrypto::SerType::JSON, cryptoContext.m_cryptoContextImplSharedPtr);
         }
     }
     return false;
@@ -345,13 +410,11 @@ bool SerializeEvalMultKeyByIdToFile(const std::string& multKeyLocation,
     {
         if (serialMode == SerialMode::BINARY)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalMultKey(
-                *ofs, lbcrypto::SerType::BINARY, id);
+            return CryptoContextImpl::SerializeEvalMultKey(*ofs, lbcrypto::SerType::BINARY, id);
         }
         if (serialMode == SerialMode::JSON)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalMultKey(
-                *ofs, lbcrypto::SerType::JSON, id);
+            return CryptoContextImpl::SerializeEvalMultKey(*ofs, lbcrypto::SerType::JSON, id);
         }
     }
     return false;
@@ -367,13 +430,11 @@ bool DeserializeEvalMultKeyFromFile(const std::string& multKeyLocation,
     {
         if (serialMode == SerialMode::BINARY)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::DeserializeEvalMultKey(
-                *ifs, lbcrypto::SerType::BINARY);
+            return CryptoContextImpl::DeserializeEvalMultKey(*ifs, lbcrypto::SerType::BINARY);
         }
         if (serialMode == SerialMode::JSON)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::DeserializeEvalMultKey(
-                *ifs, lbcrypto::SerType::JSON);
+            return CryptoContextImpl::DeserializeEvalMultKey(*ifs, lbcrypto::SerType::JSON);
         }
     }
     return false;
@@ -389,13 +450,13 @@ bool SerializeEvalSumKeyToFile(const std::string& sumKeyLocation,
     {
         if (serialMode == SerialMode::BINARY)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalAutomorphismKey(
-                *ofs, lbcrypto::SerType::BINARY, cryptoContext.m_cryptoContextImplSharedPtr);
+            return CryptoContextImpl::SerializeEvalAutomorphismKey(*ofs, lbcrypto::SerType::BINARY,
+                cryptoContext.m_cryptoContextImplSharedPtr);
         }
         if (serialMode == SerialMode::JSON)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalAutomorphismKey(
-                *ofs, lbcrypto::SerType::JSON, cryptoContext.m_cryptoContextImplSharedPtr);
+            return CryptoContextImpl::SerializeEvalAutomorphismKey(*ofs, lbcrypto::SerType::JSON,
+                cryptoContext.m_cryptoContextImplSharedPtr);
         }
     }
     return false;
@@ -411,13 +472,11 @@ bool SerializeEvalSumKeyByIdToFile(const std::string& sumKeyLocation,
     {
         if (serialMode == SerialMode::BINARY)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalSumKey(
-                *ofs, lbcrypto::SerType::BINARY, id);
+            return CryptoContextImpl::SerializeEvalSumKey(*ofs, lbcrypto::SerType::BINARY, id);
         }
         if (serialMode == SerialMode::JSON)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalSumKey(
-                *ofs, lbcrypto::SerType::JSON, id);
+            return CryptoContextImpl::SerializeEvalSumKey(*ofs, lbcrypto::SerType::JSON, id);
         }
     }
     return false;
@@ -432,13 +491,13 @@ bool DeserializeEvalSumKeyFromFile(const std::string& sumKeyLocation, const Seri
     {
         if (serialMode == SerialMode::BINARY)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::DeserializeEvalAutomorphismKey(
-                *ifs, lbcrypto::SerType::BINARY);
+            return CryptoContextImpl::DeserializeEvalAutomorphismKey(*ifs,
+                lbcrypto::SerType::BINARY);
         }
         if (serialMode == SerialMode::JSON)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::DeserializeEvalAutomorphismKey(
-                *ifs, lbcrypto::SerType::JSON);
+            return CryptoContextImpl::DeserializeEvalAutomorphismKey(*ifs,
+                lbcrypto::SerType::JSON);
         }
     }
     return false;
@@ -454,13 +513,13 @@ bool SerializeEvalAutomorphismKeyToFile(const std::string& automorphismKeyLocati
     {
         if (serialMode == SerialMode::BINARY)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalAutomorphismKey(
-                *ofs, lbcrypto::SerType::BINARY, cryptoContext.m_cryptoContextImplSharedPtr);
+            return CryptoContextImpl::SerializeEvalAutomorphismKey(*ofs, lbcrypto::SerType::BINARY,
+                cryptoContext.m_cryptoContextImplSharedPtr);
         }
         if (serialMode == SerialMode::JSON)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalAutomorphismKey(
-                *ofs, lbcrypto::SerType::JSON, cryptoContext.m_cryptoContextImplSharedPtr);
+            return CryptoContextImpl::SerializeEvalAutomorphismKey(*ofs, lbcrypto::SerType::JSON,
+                cryptoContext.m_cryptoContextImplSharedPtr);
         }
     }
     return false;
@@ -476,13 +535,13 @@ bool SerializeEvalAutomorphismKeyByIdToFile(const std::string& automorphismKeyLo
     {
         if (serialMode == SerialMode::BINARY)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalAutomorphismKey(
-                *ofs, lbcrypto::SerType::BINARY, id);
+            return CryptoContextImpl::SerializeEvalAutomorphismKey(*ofs, lbcrypto::SerType::BINARY,
+                id);
         }
         if (serialMode == SerialMode::JSON)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::SerializeEvalAutomorphismKey(
-                *ofs, lbcrypto::SerType::JSON, id);
+            return CryptoContextImpl::SerializeEvalAutomorphismKey(*ofs, lbcrypto::SerType::JSON,
+                id);
         }
     }
     return false;
@@ -498,13 +557,13 @@ bool DeserializeEvalAutomorphismKeyFromFile(const std::string& automorphismKeyLo
     {
         if (serialMode == SerialMode::BINARY)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::DeserializeEvalAutomorphismKey(
-                *ifs, lbcrypto::SerType::BINARY);
+            return CryptoContextImpl::DeserializeEvalAutomorphismKey(*ifs,
+                lbcrypto::SerType::BINARY);
         }
         if (serialMode == SerialMode::JSON)
         {
-            return lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>::DeserializeEvalAutomorphismKey(
-                *ifs, lbcrypto::SerType::JSON);
+            return CryptoContextImpl::DeserializeEvalAutomorphismKey(*ifs,
+                lbcrypto::SerType::JSON);
         }
     }
     return false;

+ 51 - 24
src/bindings.hpp

@@ -33,8 +33,6 @@ using COMPRESSION_LEVEL = lbcrypto::COMPRESSION_LEVEL;
 using PKESchemeFeature = lbcrypto::PKESchemeFeature;
 using PublicKeyImpl = lbcrypto::PublicKeyImpl<lbcrypto::DCRTPoly>;
 using PrivateKeyImpl = lbcrypto::PrivateKeyImpl<lbcrypto::DCRTPoly>;
-using PlaintextImpl = lbcrypto::PlaintextImpl;
-using CiphertextImpl = lbcrypto::CiphertextImpl<lbcrypto::DCRTPoly>;
 using DecryptResult = lbcrypto::DecryptResult;
 using DCRTPolyParams = lbcrypto::DCRTPoly::Params;
 using ::SerialMode;
@@ -42,6 +40,15 @@ struct ComplexPair;
 using Complex = std::complex<double>;
 struct SharedComplex;
 
+// not used in the Rust side
+using PlaintextImpl = lbcrypto::PlaintextImpl;
+// not used in the Rust side
+using CiphertextImpl = lbcrypto::CiphertextImpl<lbcrypto::DCRTPoly>;
+// not used in the Rust side
+using CryptoContextImpl = lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>;
+// not used in the Rust side
+using KeyPair = lbcrypto::KeyPair<lbcrypto::DCRTPoly>;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 class PublicKeyDCRTPoly final
@@ -58,6 +65,8 @@ public:
     PublicKeyDCRTPoly(PublicKeyDCRTPoly&&) = delete;
     PublicKeyDCRTPoly& operator=(const PublicKeyDCRTPoly&) = delete;
     PublicKeyDCRTPoly& operator=(PublicKeyDCRTPoly&&) = delete;
+
+    [[nodiscard]] std::shared_ptr<PublicKeyImpl> GetInternal() const;
 };
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -67,7 +76,7 @@ class KeyPairDCRTPoly final
     std::shared_ptr<PublicKeyImpl> m_publicKey;
     std::shared_ptr<PrivateKeyImpl> m_privateKey;
 public:
-    explicit KeyPairDCRTPoly(lbcrypto::KeyPair<lbcrypto::DCRTPoly> keyPair);
+    explicit KeyPairDCRTPoly(KeyPair keyPair);
     KeyPairDCRTPoly(const KeyPairDCRTPoly&) = delete;
     KeyPairDCRTPoly(KeyPairDCRTPoly&&) = delete;
     KeyPairDCRTPoly& operator=(const KeyPairDCRTPoly&) = delete;
@@ -91,7 +100,7 @@ public:
     Plaintext& operator=(Plaintext&&) = delete;
     Plaintext& operator=(std::shared_ptr<PlaintextImpl> plaintext);
 
-    [[nodiscard]] std::shared_ptr<PlaintextImpl> GetPlainText() const;
+    [[nodiscard]] std::shared_ptr<PlaintextImpl> GetInternal() const;
     void SetLength(const size_t newSize) const;
     [[nodiscard]] double GetLogPrecision() const;
     [[nodiscard]] rust::String GetString() const;
@@ -115,14 +124,14 @@ public:
     CiphertextDCRTPoly& operator=(const CiphertextDCRTPoly&) = delete;
     CiphertextDCRTPoly& operator=(CiphertextDCRTPoly&&) = delete;
 
-    [[nodiscard]] std::shared_ptr<CiphertextImpl> GetCipherText() const;
+    [[nodiscard]] std::shared_ptr<CiphertextImpl> GetInternal() const;
 };
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 class CryptoContextDCRTPoly final
 {
-    std::shared_ptr<lbcrypto::CryptoContextImpl<lbcrypto::DCRTPoly>> m_cryptoContextImplSharedPtr;
+    std::shared_ptr<CryptoContextImpl> m_cryptoContextImplSharedPtr;
 public:
     friend bool SerializeCryptoContextToFile(const std::string& ccLocation,
         const CryptoContextDCRTPoly& cryptoContext, const SerialMode serialMode);
@@ -151,37 +160,51 @@ public:
     void EvalRotateKeyGen(
         const std::shared_ptr<PrivateKeyImpl> privateKey, const std::vector<int32_t>& indexList,
         const std::shared_ptr<PublicKeyImpl> publicKey /* nullptr */) const;
+    void EvalCKKStoFHEWPrecompute(const double scale /* 1.0 */) const;
     [[nodiscard]] uint32_t GetRingDimension() const;
+    [[nodiscard]] uint32_t GetCyclotomicOrder() const;
     [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> Encrypt(
-        const std::shared_ptr<PublicKeyImpl> publicKey,
-        std::shared_ptr<lbcrypto::PlaintextImpl> plaintext) const;
+        const std::shared_ptr<PublicKeyImpl> publicKey, const Plaintext& plaintext) const;
     [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalAdd(
-        std::shared_ptr<CiphertextImpl> ciphertext1,
-        std::shared_ptr<CiphertextImpl> ciphertext2) const;
+        const CiphertextDCRTPoly& ciphertext1, const CiphertextDCRTPoly& ciphertext2) const;
     [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalSub(
-        std::shared_ptr<CiphertextImpl> ciphertext1,
-        std::shared_ptr<CiphertextImpl> ciphertext2) const;
+        const CiphertextDCRTPoly& ciphertext1, const CiphertextDCRTPoly& ciphertext2) const;
     [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalMult(
-        std::shared_ptr<CiphertextImpl> ciphertext1,
-        std::shared_ptr<CiphertextImpl> ciphertext2) const;
+        const CiphertextDCRTPoly& ciphertext1, const CiphertextDCRTPoly& ciphertext2) const;
     [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalMultNoRelin(
-        std::shared_ptr<CiphertextImpl> ciphertext1,
-        std::shared_ptr<CiphertextImpl> ciphertext2) const;
+        const CiphertextDCRTPoly& ciphertext1, const CiphertextDCRTPoly& ciphertext2) const;
     [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalMultAndRelinearize(
-        std::shared_ptr<CiphertextImpl> ciphertext1,
-        std::shared_ptr<CiphertextImpl> ciphertext2) const;
+        const CiphertextDCRTPoly& ciphertext1, const CiphertextDCRTPoly& ciphertext2) const;
     [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalMultByConst(
-        std::shared_ptr<CiphertextImpl> ciphertext, const double constant) const;
+        const CiphertextDCRTPoly& ciphertext, const double constant) const;
     [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalRotate(
-        std::shared_ptr<CiphertextImpl> ciphertext, const int32_t index) const;
+        const CiphertextDCRTPoly& ciphertext, const int32_t index) const;
     [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalPoly(
-        std::shared_ptr<CiphertextImpl> ciphertext, const std::vector<double>& coefficients) const;
+        const CiphertextDCRTPoly& ciphertext, const std::vector<double>& coefficients) const;
     [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalChebyshevSeries(
-        std::shared_ptr<CiphertextImpl> ciphertext, const std::vector<double>& coefficients,
+   	    const CiphertextDCRTPoly& ciphertext, const std::vector<double>& coefficients,
         const double a, const double b) const;
+    [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalBootstrap(
+        const CiphertextDCRTPoly& ciphertext, const uint32_t numIterations /* 1 */,
+        const uint32_t precision /* 0 */) const;
+    [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> Rescale(
+   	    const CiphertextDCRTPoly& ciphertext) const;
+    [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> ModReduce(
+        const CiphertextDCRTPoly& ciphertext) const;
+    [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> EvalSum(const CiphertextDCRTPoly& ciphertext,
+        const uint32_t batchSize) const;
+    [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> IntMPBootAdjustScale(
+   	    const CiphertextDCRTPoly& ciphertext) const;
+    [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> IntMPBootRandomElementGen(
+        const PublicKeyDCRTPoly& publicKey) const;
+    void EvalBootstrapSetup(const std::vector<uint32_t>& levelBudget /* {5, 4} */,
+        const std::vector<uint32_t>& dim1 /* {0, 0} */, const uint32_t slots /* 0 */,
+        const uint32_t correctionFactor /* 0 */, const bool precompute /* true */) const;
+    void EvalBootstrapKeyGen(const std::shared_ptr<PrivateKeyImpl> privateKey,
+        const uint32_t slots) const;
     [[nodiscard]] std::unique_ptr<DecryptResult> Decrypt(
-        const std::shared_ptr<PrivateKeyImpl> privateKey,
-        std::shared_ptr<CiphertextImpl> ciphertext, Plaintext& plaintext) const;
+        const std::shared_ptr<PrivateKeyImpl> privateKey, const CiphertextDCRTPoly& ciphertext,
+        Plaintext& plaintext) const;
     [[nodiscard]] std::unique_ptr<Plaintext> MakePackedPlaintext(
         const std::vector<int64_t>& value, const size_t noiseScaleDeg /* 1 */,
         const uint32_t level /* 0 */) const;
@@ -195,6 +218,8 @@ public:
         const uint32_t slots /* 0 */) const;
 };
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 [[nodiscard]] std::unique_ptr<std::vector<SharedComplex>> GenVectorOfComplex(
     const std::vector<ComplexPair>& vals);
 [[nodiscard]] std::unique_ptr<Params> GetParamsByScheme(const SCHEME scheme);
@@ -220,6 +245,8 @@ public:
 [[nodiscard]] std::unique_ptr<PublicKeyDCRTPoly> GenDefaultConstructedPublicKey();
 [[nodiscard]] std::unique_ptr<CiphertextDCRTPoly> GenDefaultConstructedCiphertext();
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 bool SerializeCryptoContextToFile(const std::string& ccLocation,
     const CryptoContextDCRTPoly& cryptoContext, const SerialMode serialMode);
 bool DeserializeCryptoContextFromFile(const std::string& ccLocation,

+ 75 - 59
src/lib.rs

@@ -142,9 +142,7 @@ pub mod ffi
         type KeyPairDCRTPoly;
         type PrivateKeyImpl;
         type PublicKeyImpl;
-        type PlaintextImpl;
         type Plaintext;
-        type CiphertextImpl;
         type CiphertextDCRTPoly;
         type DecryptResult;
         type DCRTPolyParams;
@@ -460,7 +458,6 @@ pub mod ffi
     unsafe extern "C++"
     {
         fn GenEmptyPlainText() -> UniquePtr<Plaintext>;
-        fn GetPlainText(self: &Plaintext) -> SharedPtr<PlaintextImpl>;
         fn SetLength(self: &Plaintext, newSize: usize);
         fn GetString(self: &Plaintext) -> String;
         fn GetLogPrecision(self: &Plaintext) -> f64;
@@ -469,7 +466,6 @@ pub mod ffi
     // CiphertextDCRTPoly
     unsafe extern "C++"
     {
-        fn GetCipherText(self: &CiphertextDCRTPoly) -> SharedPtr<CiphertextImpl>;
         fn GenDefaultConstructedCiphertext() -> UniquePtr<CiphertextDCRTPoly>;
     }
 
@@ -508,35 +504,55 @@ pub mod ffi
         fn EvalMultKeysGen(self: &CryptoContextDCRTPoly, key: SharedPtr<PrivateKeyImpl>);
         fn EvalRotateKeyGen(self: &CryptoContextDCRTPoly, privateKey: SharedPtr<PrivateKeyImpl>,
                             indexList: &CxxVector<i32>, publicKey: SharedPtr<PublicKeyImpl>);
+        fn EvalCKKStoFHEWPrecompute(self: &CryptoContextDCRTPoly, scale: /* 1.0 */ f64);
         fn MakePackedPlaintext(self: &CryptoContextDCRTPoly, value: &CxxVector<i64>,
                                noiseScaleDeg: /* 1 */ usize, level: /* 0 */ u32)
                                -> UniquePtr<Plaintext>;
         fn Encrypt(self: &CryptoContextDCRTPoly, publicKey: SharedPtr<PublicKeyImpl>,
-                   plaintext: SharedPtr<PlaintextImpl>) -> UniquePtr<CiphertextDCRTPoly>;
-        fn EvalAdd(self: &CryptoContextDCRTPoly, ciphertext1: SharedPtr<CiphertextImpl>,
-                   ciphertext2: SharedPtr<CiphertextImpl>) -> UniquePtr<CiphertextDCRTPoly>;
-        fn EvalSub(self: &CryptoContextDCRTPoly, ciphertext1: SharedPtr<CiphertextImpl>,
-                   ciphertext2: SharedPtr<CiphertextImpl>) -> UniquePtr<CiphertextDCRTPoly>;
-        fn EvalMult(self: &CryptoContextDCRTPoly, ciphertext1: SharedPtr<CiphertextImpl>,
-                    ciphertext2: SharedPtr<CiphertextImpl>) -> UniquePtr<CiphertextDCRTPoly>;
-        fn EvalMultNoRelin(self: &CryptoContextDCRTPoly, ciphertext1: SharedPtr<CiphertextImpl>,
-                           ciphertext2: SharedPtr<CiphertextImpl>)
-                           -> UniquePtr<CiphertextDCRTPoly>;
+                   plaintext: &Plaintext) -> UniquePtr<CiphertextDCRTPoly>;
+        fn EvalAdd(self: &CryptoContextDCRTPoly, ciphertext1: &CiphertextDCRTPoly,
+                   ciphertext2: &CiphertextDCRTPoly) -> UniquePtr<CiphertextDCRTPoly>;
+        fn EvalSub(self: &CryptoContextDCRTPoly, ciphertext1: &CiphertextDCRTPoly,
+                   ciphertext2: &CiphertextDCRTPoly) -> UniquePtr<CiphertextDCRTPoly>;
+        fn EvalMult(self: &CryptoContextDCRTPoly, ciphertext1: &CiphertextDCRTPoly,
+                    ciphertext2: &CiphertextDCRTPoly) -> UniquePtr<CiphertextDCRTPoly>;
+        fn EvalMultNoRelin(self: &CryptoContextDCRTPoly, ciphertext1: &CiphertextDCRTPoly,
+                           ciphertext2: &CiphertextDCRTPoly) -> UniquePtr<CiphertextDCRTPoly>;
         fn EvalMultAndRelinearize(self: &CryptoContextDCRTPoly,
-                                  ciphertext1: SharedPtr<CiphertextImpl>,
-                                  ciphertext2: SharedPtr<CiphertextImpl>)
+                                  ciphertext1: &CiphertextDCRTPoly,
+                                  ciphertext2: &CiphertextDCRTPoly)
                                   -> UniquePtr<CiphertextDCRTPoly>;
-        fn EvalMultByConst(self: &CryptoContextDCRTPoly, ciphertext: SharedPtr<CiphertextImpl>,
+        fn EvalMultByConst(self: &CryptoContextDCRTPoly, ciphertext: &CiphertextDCRTPoly,
                            constant: f64) -> UniquePtr<CiphertextDCRTPoly>;
-        fn EvalRotate(self: &CryptoContextDCRTPoly, ciphertext: SharedPtr<CiphertextImpl>,
-                      index: i32) -> UniquePtr<CiphertextDCRTPoly>;
-        fn EvalChebyshevSeries(self: &CryptoContextDCRTPoly, ciphertext: SharedPtr<CiphertextImpl>,
+        fn EvalRotate(self: &CryptoContextDCRTPoly, ciphertext: &CiphertextDCRTPoly, index: i32)
+                      -> UniquePtr<CiphertextDCRTPoly>;
+        fn EvalChebyshevSeries(self: &CryptoContextDCRTPoly, ciphertext: &CiphertextDCRTPoly,
                                coefficients: &CxxVector<f64>, a: f64, b: f64)
                                -> UniquePtr<CiphertextDCRTPoly>;
+        fn EvalBootstrap(self: &CryptoContextDCRTPoly, ciphertext: &CiphertextDCRTPoly,
+                         numIterations: /* 1 */ u32, precision: /* 0 */ u32)
+                         -> UniquePtr<CiphertextDCRTPoly>;
+        fn Rescale(self: &CryptoContextDCRTPoly, ciphertext: &CiphertextDCRTPoly)
+                   -> UniquePtr<CiphertextDCRTPoly>;
+        fn ModReduce(self: &CryptoContextDCRTPoly, ciphertext: &CiphertextDCRTPoly)
+                     -> UniquePtr<CiphertextDCRTPoly>;
+        fn EvalSum(self: &CryptoContextDCRTPoly, ciphertext: &CiphertextDCRTPoly, batchSize: u32)
+                   -> UniquePtr<CiphertextDCRTPoly>;
+        fn IntMPBootAdjustScale(self: &CryptoContextDCRTPoly, ciphertext: &CiphertextDCRTPoly)
+                                -> UniquePtr<CiphertextDCRTPoly>;
+        fn IntMPBootRandomElementGen(self: &CryptoContextDCRTPoly, publicKey: &PublicKeyDCRTPoly)
+                                     -> UniquePtr<CiphertextDCRTPoly>;
+        fn EvalBootstrapSetup(self: &CryptoContextDCRTPoly,
+                              levelBudget: /* {5, 4} */ &CxxVector<u32>,
+                              dim1: /* {0, 0} */ &CxxVector<u32>, slots: /* 0 */ u32,
+                              correctionFactor: /* 0 */ u32, precompute: /* true */ bool);
+        fn EvalBootstrapKeyGen(self: &CryptoContextDCRTPoly, privateKey: SharedPtr<PrivateKeyImpl>,
+                               slots: u32);
         fn Decrypt(self: &CryptoContextDCRTPoly, privateKey: SharedPtr<PrivateKeyImpl>,
-                   ciphertext: SharedPtr<CiphertextImpl>, plaintext: Pin<&mut Plaintext>)
+                   ciphertext: &CiphertextDCRTPoly, plaintext: Pin<&mut Plaintext>)
                    -> UniquePtr<DecryptResult>;
         fn GetRingDimension(self: &CryptoContextDCRTPoly) -> u32;
+        fn GetCyclotomicOrder(self: &CryptoContextDCRTPoly) -> u32;
         fn MakeCKKSPackedPlaintext(self: &CryptoContextDCRTPoly, value: &CxxVector<f64>,
                                    scaleDeg: /* 1 */ usize, level: /* 0 */ u32,
                                    params: /* null() */ SharedPtr<DCRTPolyParams>,
@@ -546,7 +562,7 @@ pub mod ffi
                                                     scaleDeg: /* 1 */ usize, level: /* 0 */ u32,
                                                     params: /* null() */ SharedPtr<DCRTPolyParams>,
                                                     slots: /* 0 */ u32) -> UniquePtr<Plaintext>;
-        fn EvalPoly(self: &CryptoContextDCRTPoly, ciphertext: SharedPtr<CiphertextImpl>,
+        fn EvalPoly(self: &CryptoContextDCRTPoly, ciphertext: &CiphertextDCRTPoly,
                     coefficients: &CxxVector<f64>) -> UniquePtr<CiphertextDCRTPoly>;
     }
 
@@ -667,33 +683,33 @@ mod tests
         _vector_of_ints_3.pin_mut().push(12);
         let mut _plain_text_3 = _cc.MakePackedPlaintext(&_vector_of_ints_3, 1, 0);
 
-        let mut _cipher_text_1 = _cc.Encrypt(_key_pair.GetPublicKey(), _plain_text_1.GetPlainText());
-        let mut _cipher_text_2 = _cc.Encrypt(_key_pair.GetPublicKey(), _plain_text_2.GetPlainText());
-        let mut _cipher_text_3 = _cc.Encrypt(_key_pair.GetPublicKey(), _plain_text_3.GetPlainText());
+        let mut _cipher_text_1 = _cc.Encrypt(_key_pair.GetPublicKey(), &_plain_text_1);
+        let mut _cipher_text_2 = _cc.Encrypt(_key_pair.GetPublicKey(), &_plain_text_2);
+        let mut _cipher_text_3 = _cc.Encrypt(_key_pair.GetPublicKey(), &_plain_text_3);
 
-        let mut _cipher_text_add_1_2 = _cc.EvalAdd(_cipher_text_1.GetCipherText(), _cipher_text_2.GetCipherText());
-        let mut _cipher_text_add_result = _cc.EvalAdd(_cipher_text_add_1_2.GetCipherText(), _cipher_text_3.GetCipherText());
+        let mut _cipher_text_add_1_2 = _cc.EvalAdd(&_cipher_text_1, &_cipher_text_2);
+        let mut _cipher_text_add_result = _cc.EvalAdd(&_cipher_text_add_1_2, &_cipher_text_3);
 
-        let mut _cipher_text_mul_1_2 = _cc.EvalMult(_cipher_text_1.GetCipherText(), _cipher_text_2.GetCipherText());
-        let mut _cipher_text_mult_result = _cc.EvalMult(_cipher_text_mul_1_2.GetCipherText(), _cipher_text_3.GetCipherText());
+        let mut _cipher_text_mul_1_2 = _cc.EvalMult(&_cipher_text_1, &_cipher_text_2);
+        let mut _cipher_text_mult_result = _cc.EvalMult(&_cipher_text_mul_1_2, &_cipher_text_3);
 
-        let mut _cipher_text_rot_1 = _cc.EvalRotate(_cipher_text_1.GetCipherText(), 1);
-        let mut _cipher_text_rot_2 = _cc.EvalRotate(_cipher_text_1.GetCipherText(), 2);
-        let mut _cipher_text_rot_3 = _cc.EvalRotate(_cipher_text_1.GetCipherText(), -1);
-        let mut _cipher_text_rot_4 = _cc.EvalRotate(_cipher_text_1.GetCipherText(), -2);
+        let mut _cipher_text_rot_1 = _cc.EvalRotate(&_cipher_text_1, 1);
+        let mut _cipher_text_rot_2 = _cc.EvalRotate(&_cipher_text_1, 2);
+        let mut _cipher_text_rot_3 = _cc.EvalRotate(&_cipher_text_1, -1);
+        let mut _cipher_text_rot_4 = _cc.EvalRotate(&_cipher_text_1, -2);
 
         let mut _plain_text_add_result = ffi::GenEmptyPlainText();
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _cipher_text_add_result.GetCipherText(), _plain_text_add_result.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_cipher_text_add_result, _plain_text_add_result.pin_mut());
         let mut _plain_text_mult_result = ffi::GenEmptyPlainText();
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _cipher_text_mult_result.GetCipherText(), _plain_text_mult_result.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_cipher_text_mult_result, _plain_text_mult_result.pin_mut());
         let mut _plain_text_rot_1 = ffi::GenEmptyPlainText();
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _cipher_text_rot_1.GetCipherText(), _plain_text_rot_1.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_cipher_text_rot_1, _plain_text_rot_1.pin_mut());
         let mut _plain_text_rot_2 = ffi::GenEmptyPlainText();
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _cipher_text_rot_2.GetCipherText(), _plain_text_rot_2.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_cipher_text_rot_2, _plain_text_rot_2.pin_mut());
         let mut _plain_text_rot_3 = ffi::GenEmptyPlainText();
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _cipher_text_rot_3.GetCipherText(), _plain_text_rot_3.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_cipher_text_rot_3, _plain_text_rot_3.pin_mut());
         let mut _plain_text_rot_4 = ffi::GenEmptyPlainText();
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _cipher_text_rot_4.GetCipherText(), _plain_text_rot_4.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_cipher_text_rot_4, _plain_text_rot_4.pin_mut());
 
         _plain_text_rot_1.SetLength(_vector_of_ints_1.len());
         _plain_text_rot_2.SetLength(_vector_of_ints_1.len());
@@ -765,45 +781,45 @@ mod tests
         println!("Input x1: {}", _p_txt_1.GetString());
         println!("Input x2: {}", _p_txt_2.GetString());
 
-        let mut _c1 = _cc.Encrypt(_key_pair.GetPublicKey(), _p_txt_1.GetPlainText());
-        let mut _c2 = _cc.Encrypt(_key_pair.GetPublicKey(), _p_txt_2.GetPlainText());
+        let mut _c1 = _cc.Encrypt(_key_pair.GetPublicKey(), &_p_txt_1);
+        let mut _c2 = _cc.Encrypt(_key_pair.GetPublicKey(), &_p_txt_2);
 
-        let mut _c_add = _cc.EvalAdd(_c1.GetCipherText(), _c2.GetCipherText());
-        let mut _c_sub = _cc.EvalSub(_c1.GetCipherText(), _c2.GetCipherText());
-        let mut _c_scalar = _cc.EvalMultByConst(_c1.GetCipherText(), 4.0);
-        let mut _c_mul = _cc.EvalMult(_c1.GetCipherText(), _c2.GetCipherText());
-        let mut _c_rot_1 = _cc.EvalRotate(_c1.GetCipherText(), 1);
-        let mut _c_rot_2 = _cc.EvalRotate(_c1.GetCipherText(), -2);
+        let mut _c_add = _cc.EvalAdd(&_c1, &_c2);
+        let mut _c_sub = _cc.EvalSub(&_c1, &_c2);
+        let mut _c_scalar = _cc.EvalMultByConst(&_c1, 4.0);
+        let mut _c_mul = _cc.EvalMult(&_c1, &_c2);
+        let mut _c_rot_1 = _cc.EvalRotate(&_c1, 1);
+        let mut _c_rot_2 = _cc.EvalRotate(&_c1, -2);
 
         let mut _result = ffi::GenEmptyPlainText();
         println!("\nResults of homomorphic computations:");
 
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _c1.GetCipherText(), _result.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_c1, _result.pin_mut());
         _result.SetLength(_batch_size.try_into().unwrap());
         println!("x1 = {}Estimated precision in bits: {}", _result.GetString(), _result.GetLogPrecision());
 
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _c_add.GetCipherText(), _result.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_add, _result.pin_mut());
         _result.SetLength(_batch_size.try_into().unwrap());
         println!("x1 + x2 = {}Estimated precision in bits: {}",_result.GetString(), _result.GetLogPrecision());
 
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _c_sub.GetCipherText(), _result.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_sub, _result.pin_mut());
         _result.SetLength(_batch_size.try_into().unwrap());
         println!("x1 - x2 = {}", _result.GetString());
 
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _c_scalar.GetCipherText(), _result.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_scalar, _result.pin_mut());
         _result.SetLength(_batch_size.try_into().unwrap());
         println!("4 * x1 = {}", _result.GetString());
 
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _c_mul.GetCipherText(), _result.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_mul, _result.pin_mut());
         _result.SetLength(_batch_size.try_into().unwrap());
         println!("x1 * x2 = {}", _result.GetString());
 
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _c_rot_1.GetCipherText(), _result.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_rot_1, _result.pin_mut());
         _result.SetLength(_batch_size.try_into().unwrap());
         println!("\nIn rotations, very small outputs (~10^-10 here) correspond to 0's:");
         println!("x1 rotate by 1 = {}", _result.GetString());
 
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _c_rot_2.GetCipherText(), _result.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_c_rot_2, _result.pin_mut());
         _result.SetLength(_batch_size.try_into().unwrap());
         println!("x1 rotate by -2 = {}", _result.GetString());
     }
@@ -889,21 +905,21 @@ mod tests
         print!("Generating evaluation key for homomorphic multiplication...");
         _cc.EvalMultKeyGen(_key_pair.GetPrivateKey());
         println!("Completed.\n");
-        let mut _cipher_text_1 = _cc.Encrypt(_key_pair.GetPublicKey(), _plain_text_1.GetPlainText());
+        let mut _cipher_text_1 = _cc.Encrypt(_key_pair.GetPublicKey(), &_plain_text_1);
 
         let mut _start = Instant::now();
-        let mut _result = _cc.EvalPoly(_cipher_text_1.GetCipherText(), &_coefficients_1);
+        let mut _result = _cc.EvalPoly(&_cipher_text_1, &_coefficients_1);
         let _time_eval_poly_1 = _start.elapsed();
 
         _start = Instant::now();
-        let mut _result_2 = _cc.EvalPoly(_cipher_text_1.GetCipherText(), &_coefficients_2);
+        let mut _result_2 = _cc.EvalPoly(&_cipher_text_1, &_coefficients_2);
         let _time_eval_poly_2 = _start.elapsed();
 
         let mut _plain_text_dec = ffi::GenEmptyPlainText();
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _result.GetCipherText(), _plain_text_dec.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_result, _plain_text_dec.pin_mut());
         _plain_text_dec.SetLength(_encoded_length);
         let mut _plain_text_dec_2 = ffi::GenEmptyPlainText();
-        _cc.Decrypt(_key_pair.GetPrivateKey(), _result_2.GetCipherText(), _plain_text_dec_2.pin_mut());
+        _cc.Decrypt(_key_pair.GetPrivateKey(), &_result_2, _plain_text_dec_2.pin_mut());
         _plain_text_dec_2.SetLength(_encoded_length);
 
         println!("\n Original Plaintext #1:");