Browse Source

Merge pull request #9 from openfheorg/Oliveira_serial

Oliveira serial
Rener Oliveira 2 years ago
parent
commit
31c9c5dc56

+ 5 - 2
CMakeLists.txt

@@ -25,13 +25,16 @@ find_package(pybind11 REQUIRED)
 
 set( CMAKE_CXX_FLAGS ${OpenFHE_CXX_FLAGS} )
 set( OpenFHE_Py_SOURCES src)
+set( OpenFHE_Py_INCLUDES include)
 
 include_directories( ${OPENMP_INCLUDES} )
 include_directories( ${OpenFHE_INCLUDE} )
 include_directories( ${OpenFHE_INCLUDE}/third-party/include )
 include_directories( ${OpenFHE_INCLUDE}/core )
 include_directories( ${OpenFHE_INCLUDE}/pke )
-include_directories( ${OpenFHE_Py_SOURCES} )
+# include_directories( ${OpenFHE_Py_SOURCES} )
+include_directories( ${OpenFHE_Py_INCLUDES}/pke )
+include_directories( ${OpenFHE_Py_INCLUDES} )
 ### add directories for other OpenFHE modules as needed for your project
 
 link_directories( ${OpenFHE_LIBDIR} )
@@ -51,7 +54,7 @@ endif()
 ### add_executable( test demo-simple-example.cpp )
 
 ### Pybind Modules
-pybind11_add_module(openfhe src/bindings.cpp src/pke/decryption.cpp)
+pybind11_add_module(openfhe src/bindings.cpp src/pke/decryption.cpp src/pke/serialization.cpp)
 ### Python installation 
 find_package(Python REQUIRED COMPONENTS Interpreter Development)
 

+ 2 - 1
src/bindings.h → include/bindings.h

@@ -5,9 +5,10 @@
 
 void bind_parameters(pybind11::module &m);
 void bind_crypto_context(pybind11::module &m);
-void bind_enums(pybind11::module &m);
+void bind_enums_and_constants(pybind11::module &m);
 void bind_keys(pybind11::module &m);
 void bind_encodings(pybind11::module &m);
 void bind_ciphertext(pybind11::module &m);
 void bind_decryption(pybind11::module &m);
+void bind_serialization(pybind11::module &m);
 #endif // OPENFHE_BINDINGS_H

+ 10 - 0
include/pke/serialization.h

@@ -0,0 +1,10 @@
+#ifndef OPENFHE_SERIALIZATION_BINDINGS_H
+#define OPENFHE_SERIALIZATION_BINDINGS_H
+
+#include <pybind11/pybind11.h>
+using namespace lbcrypto;
+
+template <typename ST>
+bool SerializeEvalMultKeyWrapper(const std::string& filename, const ST& sertype, std::string id);
+
+#endif // OPENFHE_SERIALIZATION_BINDINGS_H

+ 59 - 27
src/bindings.cpp

@@ -1,6 +1,9 @@
 #include <pybind11/pybind11.h>
 #include <pybind11/stl.h>
+#include <pybind11/iostream.h>
+#include <iostream>
 #include <openfhe/pke/openfhe.h>
+#include <openfhe/pke/key/key-ser.h>
 #include "bindings.h"
 
 using namespace lbcrypto;
@@ -16,36 +19,59 @@ void bind_parameters(py::module &m){
             // getters
             .def("GetPlaintextModulus", &CCParams<CryptoContextBFVRNS>::GetPlaintextModulus)
             .def("GetMultiplicativeDepth", &CCParams<CryptoContextBFVRNS>::GetMultiplicativeDepth);
+    
            
 }
 
-void bind_crypto_context(py::module &m){
-    py::class_<CryptoContextImpl<DCRTPoly>,std::shared_ptr<CryptoContextImpl<DCRTPoly>>>(m,"CryptoContextDCRTPoly")
-            .def("GetKeyGenLevel",&CryptoContextImpl<DCRTPoly>::GetKeyGenLevel)
-            .def("SetKeyGenLevel",&CryptoContextImpl<DCRTPoly>::SetKeyGenLevel)
-            .def("Enable",static_cast<void (CryptoContextImpl<DCRTPoly>::*)(PKESchemeFeature)>(&CryptoContextImpl<DCRTPoly>::Enable), "Enable a feature for the CryptoContext")
-            .def("KeyGen",&CryptoContextImpl<DCRTPoly>::KeyGen,"Generate a key pair with public and private keys") 
-            .def("EvalMultKeyGen",&CryptoContextImpl<DCRTPoly>::EvalMultKeyGen,"Generate the evaluation key for multiplication")
-            .def("EvalRotateKeyGen",&CryptoContextImpl<DCRTPoly>::EvalRotateKeyGen,"Generate the evaluation key for rotation",
-            py::arg("privateKey"),py::arg("indexList"),py::arg("publicKey")=nullptr)
-            .def("MakePackedPlaintext",&CryptoContextImpl<DCRTPoly>::MakePackedPlaintext,"Make a plaintext from a vector of integers",
-            py::arg("value"),py::arg("depth")=1,py::arg("level")=0)
-            .def("EvalRotate",&CryptoContextImpl<DCRTPoly>::EvalRotate,"Rotate a ciphertext")
-            .def("Encrypt",static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(const PublicKey<DCRTPoly>, Plaintext) const>(&CryptoContextImpl<DCRTPoly>::Encrypt),"Encrypt a plaintext using public key")
-            .def("EvalAdd", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalAdd),"Add two ciphertexts")
-            .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalMult),"Multiply two ciphertexts");
-
-    // Generator Functions    
+void bind_crypto_context(py::module &m)
+{
+    py::class_<CryptoContextImpl<DCRTPoly>, std::shared_ptr<CryptoContextImpl<DCRTPoly>>>(m, "CryptoContext")
+        .def(py::init<>())
+        .def("GetKeyGenLevel", &CryptoContextImpl<DCRTPoly>::GetKeyGenLevel)
+        .def("SetKeyGenLevel", &CryptoContextImpl<DCRTPoly>::SetKeyGenLevel)
+        .def("Enable", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(PKESchemeFeature)>(&CryptoContextImpl<DCRTPoly>::Enable), "Enable a feature for the CryptoContext")
+        .def("KeyGen", &CryptoContextImpl<DCRTPoly>::KeyGen, "Generate a key pair with public and private keys")
+        .def("EvalMultKeyGen", &CryptoContextImpl<DCRTPoly>::EvalMultKeyGen, "Generate the evaluation key for multiplication")
+        .def("EvalRotateKeyGen", &CryptoContextImpl<DCRTPoly>::EvalRotateKeyGen, "Generate the evaluation key for rotation",
+             py::arg("privateKey"), py::arg("indexList"), py::arg("publicKey") = nullptr)
+        .def("MakePackedPlaintext", &CryptoContextImpl<DCRTPoly>::MakePackedPlaintext, "Make a plaintext from a vector of integers",
+             py::arg("value"), py::arg("depth") = 1, py::arg("level") = 0)
+        .def("EvalRotate", &CryptoContextImpl<DCRTPoly>::EvalRotate, "Rotate a ciphertext")
+        .def("Encrypt", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(const PublicKey<DCRTPoly>, Plaintext) const>(&CryptoContextImpl<DCRTPoly>::Encrypt),
+             "Encrypt a plaintext using public key")
+        .def("EvalAdd", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalAdd), "Add two ciphertexts")
+        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalMult), "Multiply two ciphertexts")
+        .def_static("ClearEvalMultKeys", [](){
+                CryptoContextImpl<DCRTPoly>::ClearEvalMultKeys();
+            }, "Clear the evaluation keys for multiplication")
+        .def_static("ClearEvalAutomorphismKeys", [](){
+                CryptoContextImpl<DCRTPoly>::ClearEvalAutomorphismKeys();
+            }, "Clear the evaluation keys for rotation")
+        .def_static(
+            "SerializeEvalMultKey", [](const std::string &filename, const SerType::SERBINARY &sertype, std::string id = "")
+            {
+                std::ofstream outfile(filename,std::ios::out | std::ios::binary);
+                bool res;
+                res = CryptoContextImpl<DCRTPoly>::SerializeEvalMultKey<SerType::SERBINARY>(outfile, sertype, id);
+                outfile.close();
+                return res; },
+            py::arg("filename"), py::arg("sertype"), py::arg("id") = "",
+            "Serialize an evaluation key for multiplication")
+            .def_static("SerializeEvalAutomorphismKey", [](const std::string &filename, const SerType::SERBINARY &sertype, std::string id = "")
+            {
+                std::ofstream outfile(filename,std::ios::out | std::ios::binary);
+                bool res;
+                res = CryptoContextImpl<DCRTPoly>::SerializeEvalAutomorphismKey<SerType::SERBINARY>(outfile, sertype, id);
+                outfile.close();
+                return res; },py::arg("filename"), py::arg("sertype"), py::arg("id") = "",  "Serialize evaluation keys for rotation");
+
+    // Generator Functions
     m.def("GenCryptoContext", &GenCryptoContext<CryptoContextBFVRNS>);
     m.def("GenCryptoContext", &GenCryptoContext<CryptoContextBGVRNS>);
-    
-
+    m.def("ReleaseAllContexts",&CryptoContextFactory<DCRTPoly>::ReleaseAllContexts);
 }
 
-
-
-
-void bind_enums(py::module &m){
+void bind_enums_and_constants(py::module &m){
     // Scheme Types
     py::enum_<SCHEME>(m, "SCHEME")
             .value("INVALID_SCHEME", SCHEME::INVALID_SCHEME)
@@ -61,10 +87,16 @@ void bind_enums(py::module &m){
             .value("ADVANCEDSHE", PKESchemeFeature::ADVANCEDSHE)
             .value("MULTIPARTY", PKESchemeFeature::MULTIPARTY)
             .value("FHE", PKESchemeFeature::FHE);
+    // Serialization Types
+    py::class_<SerType::SERJSON >(m, "SERJSON");
+    py::class_<SerType::SERBINARY>(m, "SERBINARY");
+    m.attr("JSON") = py::cast(SerType::JSON);
+    m.attr("BINARY") = py::cast(SerType::BINARY);
 }
 
 void bind_keys(py::module &m){
-    py::class_<PublicKeyImpl<DCRTPoly>,std::shared_ptr<PublicKeyImpl<DCRTPoly>>>(m,"PublicKey");
+    py::class_<PublicKeyImpl<DCRTPoly>,std::shared_ptr<PublicKeyImpl<DCRTPoly>>>(m,"PublicKey")
+    .def(py::init<>());
     py::class_<PrivateKeyImpl<DCRTPoly>,std::shared_ptr<PrivateKeyImpl<DCRTPoly>>>(m,"PrivateKey");
     py::class_<KeyPair<DCRTPoly>>(m,"KeyPair")
             .def_readwrite("publicKey", &KeyPair<DCRTPoly>::publicKey)
@@ -117,10 +149,10 @@ PYBIND11_MODULE(openfhe, m) {
     m.doc() = "Open-Source Fully Homomorphic Encryption Library";
     bind_parameters(m);
     bind_crypto_context(m);
-    bind_enums(m);
+    bind_enums_and_constants(m);
     bind_keys(m);
     bind_encodings(m);
     bind_ciphertext(m);
     bind_decryption(m);
-
-}
+    bind_serialization(m);
+}

+ 2 - 2
src/pke/decryption.cpp

@@ -7,12 +7,12 @@ using namespace lbcrypto;
 namespace py = pybind11;
 
 template<typename Element>
-Plaintext DecryptInterface(Ciphertext<Element> ciphertext,const PrivateKey<Element> privateKey){
+Plaintext DecryptWrapper(Ciphertext<Element> ciphertext,const PrivateKey<Element> privateKey){
     Plaintext plaintextDecResult;
     auto cc = ciphertext->GetCryptoContext();
     cc->Decrypt(privateKey, ciphertext,&plaintextDecResult);
     return plaintextDecResult;
 }
 void bind_decryption(py::module &m){
-    m.def("Decrypt",&DecryptInterface<DCRTPoly>,"Decrypt a ciphertext using private key");
+    m.def("Decrypt",&DecryptWrapper<DCRTPoly>,"Decrypt a ciphertext using private key");
 }

+ 119 - 0
src/pke/examples/simple-integers-serial.py

@@ -0,0 +1,119 @@
+# Initial Settings
+from openfhe import *
+# import openfhe.PKESchemeFeature as Feature
+
+datafolder = 'demoData'
+
+print("This program requres the subdirectory `" + datafolder + "' to exist, otherwise you will get an error writing serializations.")
+
+# Sample Program: Step 1: Set CryptoContext
+parameters = CCParamsBFVRNS()
+parameters.SetPlaintextModulus(65537)
+parameters.SetMultiplicativeDepth(2)
+
+cryptoContext = GenCryptoContext(parameters)
+# Enable features that you wish to use
+cryptoContext.Enable(PKESchemeFeature.PKE)
+cryptoContext.Enable(PKESchemeFeature.KEYSWITCH)
+cryptoContext.Enable(PKESchemeFeature.LEVELEDSHE)
+
+# Serialize cryptocontext
+if not SerializeToFile(datafolder + "/cryptocontext.txt", cryptoContext, BINARY):
+   raise Exception("Error writing serialization of the crypto context to cryptocontext.txt")
+print("The cryptocontext has been serialized.")
+
+# Sample Program: Step 2: Key Generation
+
+# Generate a public/private key pair
+keypair = cryptoContext.KeyGen()
+print("The keypair has been generated.")
+
+# Serialize the public key
+if not SerializeToFile(datafolder + "/key-public.txt", keypair.publicKey, BINARY):
+   raise Exception("Error writing serialization of the public key to key-public.txt")
+print("The public key has been serialized.")
+
+# Serialize the secret key
+if not SerializeToFile(datafolder + "/key-secret.txt", keypair.secretKey, BINARY):
+   raise Exception("Error writing serialization of the secret key to key-secret.txt")
+print("The secret key has been serialized.")
+
+# Generate the relinearization key
+cryptoContext.EvalMultKeyGen(keypair.secretKey)
+print("The relinearization key has been generated.")
+
+# Serialize the relinearization key
+if not cryptoContext.SerializeEvalMultKey(datafolder + "/key-relin.txt",BINARY):
+   raise Exception("Error writing serialization of the eval mult keys to \"key-eval-mult.txt\"")
+print("The relinearization key has been serialized.")
+
+# Generate the rotation evaluation keys
+cryptoContext.EvalRotateKeyGen(keypair.secretKey, [1, 2, -1, -2])
+print("The rotation evaluation keys have been generated.")
+
+# Serialize the rotation evaluation keys
+if not cryptoContext.SerializeEvalAutomorphismKey(datafolder + "/key-eval-rot.txt",BINARY):
+   raise Exception("Error writing serialization of the eval rotate keys to \"key-eval-rot.txt\"")
+print("The rotation evaluation keys have been serialized.")
+
+# Sample Program: Step 3: Encryption
+
+# First plaintext vector is encoded
+vectorOfInts1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+plaintext1 = cryptoContext.MakePackedPlaintext(vectorOfInts1)
+
+# Second plaintext vector is encoded
+vectorOfInts2 = [3, 2, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+plaintext2 = cryptoContext.MakePackedPlaintext(vectorOfInts2)
+
+# Third plaintext vector is encoded
+vectorOfInts3 = [1, 2, 5, 2, 5, 6, 7, 8, 9, 10, 11, 12]
+plaintext3 = cryptoContext.MakePackedPlaintext(vectorOfInts3)
+
+
+# The encoded vectors are encrypted
+ciphertext1 = cryptoContext.Encrypt(keypair.publicKey, plaintext1)
+ciphertext2 = cryptoContext.Encrypt(keypair.publicKey, plaintext2)
+ciphertext3 = cryptoContext.Encrypt(keypair.publicKey, plaintext3)
+print("The plaintexts have been encrypted.")
+
+if not SerializeToFile(datafolder + "/ciphertext1.txt", ciphertext1, BINARY):
+   raise Exception("Error writing serialization of ciphertext 1 to ciphertext1.txt")
+print("The first ciphertext has been serialized.")
+
+if not SerializeToFile(datafolder + "/ciphertext2.txt", ciphertext2, BINARY):
+   raise Exception("Error writing serialization of ciphertext2 to ciphertext2.txt")
+print("The second ciphertext has been serialized.")
+
+if not SerializeToFile(datafolder + "/ciphertext3.txt", ciphertext3, BINARY):   
+   raise Exception("Error writing serialization of ciphertext3 to ciphertext3.txt")
+print("The third ciphertext has been serialized.")
+
+# Sample Program: Step 4: Evaluation
+
+# OpenFHE maintains an internal map of CryptoContext objects which are
+# indexed by a tag and the tag is applied to both the CryptoContext and some
+# of the keys. When deserializing a context, OpenFHE checks for the tag and
+# if it finds it in the CryptoContext map, it will return the stored version.
+# Hence, we need to clear the context and clear the keys.
+cryptoContext.ClearEvalMultKeys()
+cryptoContext.ClearEvalAutomorphismKeys()
+ReleaseAllContexts()
+
+# Deserialize the crypto context
+cc = CryptoContext()
+
+if not DeserializeFromFile(datafolder + "/cryptocontext.txt", cc, BINARY):
+   raise Exception("Error reading serialization of the crypto context from cryptocontext.txt")
+print("The cryptocontext has been deserialized.")
+
+# Deserialize the public key
+pk = PublicKey()
+
+if not DeserializeFromFile(datafolder + "/key-public.txt", pk, BINARY):
+   raise Exception("Error reading serialization of the public key from key-public.txt")
+
+
+
+
+

+ 29 - 23
src/pke/examples/simple-integers.py

@@ -1,49 +1,51 @@
-# Initial Setting
+# Initial Settings
 from openfhe import *
 # import openfhe.PKESchemeFeature as Feature
-# Creating the parameters object
-parameters = CCParamsBFVRNS()
 
-# Printing Default Multip. Depth and Plaintext Modulus
-print("Default BFV Plaintext Modulus = " + str(parameters.GetPlaintextModulus()))
-print("Default BFV Multiplicative Depth = " + str(parameters.GetMultiplicativeDepth()))
 
-# Setting different values
+# Sample Program: Step 1: Set CryptoContext
+parameters = CCParamsBFVRNS()
 parameters.SetPlaintextModulus(65537)
 parameters.SetMultiplicativeDepth(2)
 
-# Getting new values
-print("New BFV Plaintext Modulus = " + str(parameters.GetPlaintextModulus()))
-print("New BFV Multiplicative Depth = " + str(parameters.GetMultiplicativeDepth()))
-
 cryptoContext = GenCryptoContext(parameters)
-
-# cryptoContext.SetKeyGenLevel(2)
-# print(cryptoContext.GetKeyGenLevel())
-print(PKESchemeFeature.__members__)
+# Enable features that you wish to use
 cryptoContext.Enable(PKESchemeFeature.PKE)
 cryptoContext.Enable(PKESchemeFeature.KEYSWITCH)
 cryptoContext.Enable(PKESchemeFeature.LEVELEDSHE)
 
+# Sample Program: Step 2: Key Generation
+
+# Generate a public/private key pair
 keypair = cryptoContext.KeyGen()
-print("Public Key: " + str(keypair.publicKey))
 
+# Generate the relinearization key
 cryptoContext.EvalMultKeyGen(keypair.secretKey)
-cryptoContext.EvalRotateKeyGen(keypair.secretKey, [1, 2, -1, -2]);
 
+# Generate the rotation evaluation keys
+cryptoContext.EvalRotateKeyGen(keypair.secretKey, [1, 2, -1, -2])
+
+# Sample Program: Step 3: Encryption
+
+# First plaintext vector is encoded
 vectorOfInts1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
-vectorOfInts2 = [3, 2, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12]
-vectorOfInts3 = [1, 2, 5, 2, 5, 6, 7, 8, 9, 10, 11, 12]
 plaintext1 = cryptoContext.MakePackedPlaintext(vectorOfInts1)
-plaintext2 = cryptoContext.MakePackedPlaintext(vectorOfInts2)
-plaintext3 = cryptoContext.MakePackedPlaintext(vectorOfInts3)
 
+# Second plaintext vector is encoded
+vectorOfInts2 = [3, 2, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+plaintext2 = cryptoContext.MakePackedPlaintext(vectorOfInts2)
 
+# Third plaintext vector is encoded
+vectorOfInts3 = [1, 2, 5, 2, 5, 6, 7, 8, 9, 10, 11, 12]
+plaintext3 = cryptoContext.MakePackedPlaintext(vectorOfInts3)
 
+# The encoded vectors are encrypted
 ciphertext1 = cryptoContext.Encrypt(keypair.publicKey, plaintext1)
 ciphertext2 = cryptoContext.Encrypt(keypair.publicKey, plaintext2)
 ciphertext3 = cryptoContext.Encrypt(keypair.publicKey, plaintext3)
 
+#  Sample Program: Step 4: Evaluation
+
 # Homomorphic additions
 ciphertextAdd12 = cryptoContext.EvalAdd(ciphertext1, ciphertext2)
 ciphertextAddResult = cryptoContext.EvalAdd(ciphertextAdd12, ciphertext3)
@@ -58,16 +60,20 @@ ciphertextRot2 = cryptoContext.EvalRotate(ciphertext1, 2)
 ciphertextRot3 = cryptoContext.EvalRotate(ciphertext1, -1)
 ciphertextRot4 = cryptoContext.EvalRotate(ciphertext1, -2)
 
-# Decrypting
+# Sample Program: Step 5: Decryption
 
+# Decrypt the result of additions
 plaintextAddResult = Decrypt(ciphertextAddResult,keypair.secretKey)
+
+# Decrypt the result of multiplications
 plaintextMultResult = Decrypt(ciphertextMultResult,keypair.secretKey)
+
+# Decrypt the result of rotations
 plaintextRot1 = Decrypt(ciphertextRot1,keypair.secretKey)
 plaintextRot2 = Decrypt(ciphertextRot2,keypair.secretKey)
 plaintextRot3 = Decrypt(ciphertextRot3,keypair.secretKey)
 plaintextRot4 = Decrypt(ciphertextRot4,keypair.secretKey)
 
-plaintextRot1 = Decrypt(ciphertextRot1,keypair.secretKey)
 
 plaintextRot1.SetLength(len(vectorOfInts1))
 plaintextRot2.SetLength(len(vectorOfInts1))

+ 41 - 0
src/pke/serialization.cpp

@@ -0,0 +1,41 @@
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+#include <openfhe/pke/openfhe.h>
+#include <openfhe/pke/scheme/bfvrns/bfvrns-ser.h>
+#include <openfhe/pke/cryptocontext-ser.h>
+#include "bindings.h"
+#include "serialization.h"
+
+using namespace lbcrypto;
+namespace py = pybind11;
+
+template <typename ST>
+bool SerializeEvalMultKeyWrapper(const std::string& filename, const ST& sertype, std::string id)
+{
+    std::ofstream outfile(filename, std::ios::out | std::ios::binary);
+    bool res;
+    res = CryptoContextImpl<DCRTPoly>::SerializeEvalMultKey<ST>(outfile, sertype, id);
+    outfile.close();
+    return res;
+}
+
+void bind_serialization(pybind11::module &m) {
+    // Json Serialization
+    m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const CryptoContext<DCRTPoly>&, const SerType::SERJSON&)>(&Serial::SerializeToFile<DCRTPoly>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    m.def("DeserializeFromFile", static_cast<bool (*)(const std::string&, CryptoContext<DCRTPoly>& ,const SerType::SERJSON&)>(&Serial::DeserializeFromFile<DCRTPoly>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const PublicKey<DCRTPoly>&, const SerType::SERJSON&)>(&Serial::SerializeToFile<PublicKey<DCRTPoly>>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    m.def("DeserializeFromFile", static_cast<bool (*)(const std::string&, PublicKey<DCRTPoly>& ,const SerType::SERJSON&)>(&Serial::DeserializeFromFile<PublicKey<DCRTPoly>>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const PrivateKey<DCRTPoly>&, const SerType::SERJSON&)>(&Serial::SerializeToFile<PrivateKey<DCRTPoly>>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const Ciphertext<DCRTPoly>&, const SerType::SERJSON&)>(&Serial::SerializeToFile<Ciphertext<DCRTPoly>>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    // Binary Serialization
+    m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const CryptoContext<DCRTPoly>&, const SerType::SERBINARY&)>(&Serial::SerializeToFile<DCRTPoly>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    m.def("DeserializeFromFile", static_cast<bool (*)(const std::string&, CryptoContext<DCRTPoly>& ,const SerType::SERBINARY&)>(&Serial::DeserializeFromFile<DCRTPoly>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const PublicKey<DCRTPoly>&, const SerType::SERBINARY&)>(&Serial::SerializeToFile<PublicKey<DCRTPoly>>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    m.def("DeserializeFromFile", static_cast<bool (*)(const std::string&, PublicKey<DCRTPoly>& ,const SerType::SERBINARY&)>(&Serial::DeserializeFromFile<PublicKey<DCRTPoly>>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const PrivateKey<DCRTPoly>&, const SerType::SERBINARY&)>(&Serial::SerializeToFile<PrivateKey<DCRTPoly>>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    m.def("SerializeToFile", static_cast<bool (*)(const std::string&, const Ciphertext<DCRTPoly>&, const SerType::SERBINARY&)>(&Serial::SerializeToFile<Ciphertext<DCRTPoly>>), py::arg("filename"), py::arg("obj"), py::arg("sertype"));
+    
+    
+}
+
+