From fb409485af43159f2aa05b1e684888522321e1cf Mon Sep 17 00:00:00 2001 From: Dmitriy Suponitskiy Date: Thu, 31 Jul 2025 10:57:00 -0400 Subject: [PATCH] Additional bindings for python --- src/lib/bindings.cpp | 55 +++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/src/lib/bindings.cpp b/src/lib/bindings.cpp index f8c1c5d..bb94678 100644 --- a/src/lib/bindings.cpp +++ b/src/lib/bindings.cpp @@ -65,8 +65,7 @@ void bind_DCRTPoly(py::module &m) { } template -void bind_parameters(py::module &m, const std::string name) -{ +void bind_parameters(py::module &m, const std::string name) { py::class_>(m, name.c_str()) .def(py::init<>()) // getters @@ -224,8 +223,7 @@ void bind_crypto_context_templates(py::class_, std:: ; } -void bind_crypto_context(py::module &m) -{ +void bind_crypto_context(py::module &m) { //Parameters Type // TODO (Oliveira): If we expose Poly's and ParmType, this block will go somewhere else using ParmType = typename DCRTPoly::Params; @@ -485,6 +483,16 @@ void bind_crypto_context(py::module &m) py::arg("plaintext"), py::arg("ciphertext"), py::doc("")) // TODO (dsuponit): replace this with an actual docstring + .def("EvalAddInPlace", + py::overload_cast&, double>(&CryptoContextImpl::EvalAddInPlace, py::const_), + py::arg("ciphertext"), + py::arg("scalar"), + py::doc("")) // TODO (dsuponit): replace this with an actual docstring + .def("EvalAddInPlace", + py::overload_cast&>(&CryptoContextImpl::EvalAddInPlace, py::const_), + py::arg("scalar"), + py::arg("ciphertext"), + py::doc("")) // TODO (dsuponit): replace this with an actual docstring .def("EvalAddMutable", py::overload_cast&, Ciphertext&>(&CryptoContextImpl::EvalAddMutable, py::const_), py::arg("ciphertext1"), @@ -543,6 +551,18 @@ void bind_crypto_context(py::module &m) py::arg("scalar"), py::arg("ciphertext"), py::doc("")) // TODO (dsuponit): replace this with an actual docstring + .def("EvalSubInPlace", + py::overload_cast&, ConstPlaintext&>( + &CryptoContextImpl::EvalSubInPlace, py::const_), + py::arg("ciphertext"), + py::arg("plaintext"), + py::doc("")) // TODO (dsuponit): replace this with an actual docstring + .def("EvalSubInPlace", + py::overload_cast&>( + &CryptoContextImpl::EvalSubInPlace, py::const_), + py::arg("plaintext"), + py::arg("ciphertext"), + py::doc("")) // TODO (dsuponit): replace this with an actual docstring .def("EvalSubMutable", py::overload_cast&, Ciphertext&>(&CryptoContextImpl::EvalSubMutable, py::const_), py::arg("ciphertext1"), @@ -1125,7 +1145,7 @@ void bind_crypto_context(py::module &m) m.def("ClearEvalMultKeys", static_cast(&CryptoContextImpl::ClearEvalMultKeys)); } -int get_native_int(){ +int get_native_int() { #if NATIVEINT == 128 && !defined(__EMSCRIPTEN__) return 128; #elif NATIVEINT == 32 @@ -1135,8 +1155,7 @@ int get_native_int(){ #endif } -void bind_enums_and_constants(py::module &m) -{ +void bind_enums_and_constants(py::module &m) { /* ---- PKE enums ---- */ // Scheme Types py::enum_(m, "SCHEME") @@ -1298,8 +1317,7 @@ void bind_enums_and_constants(py::module &m) m.def("get_native_int", &get_native_int); } -void bind_keys(py::module &m) -{ +void bind_keys(py::module &m) { py::class_, std::shared_ptr>>(m, "PublicKey") .def(py::init<>()) .def("GetKeyTag", &PublicKeyImpl::GetKeyTag) @@ -1322,8 +1340,7 @@ void bind_keys(py::module &m) } // PlaintextImpl is an abstract class, so we should use a helper (trampoline) class -class PlaintextImpl_helper : public PlaintextImpl -{ +class PlaintextImpl_helper : public PlaintextImpl { public: using PlaintextImpl::PlaintextImpl; // inherited constructors @@ -1400,8 +1417,7 @@ class PlaintextImpl_helper : public PlaintextImpl } }; -void bind_encodings(py::module &m) -{ +void bind_encodings(py::module &m) { py::class_, PlaintextImpl_helper>(m, "Plaintext") .def("GetScalingFactor", &PlaintextImpl::GetScalingFactor, ptx_GetScalingFactor_docs) .def("SetScalingFactor", &PlaintextImpl::SetScalingFactor, @@ -1497,7 +1513,7 @@ void bind_ciphertext(py::module &m) { }); } -void bind_schemes(py::module &m){ +void bind_schemes(py::module &m) { // Bind schemes specific functionalities like bootstrapping functions and multiparty py::class_(m, "FHECKKSRNS") .def(py::init<>()) @@ -1513,8 +1529,7 @@ void bind_schemes(py::module &m){ ; } -void bind_sch_swch_params(py::module &m) -{ +void bind_sch_swch_params(py::module &m) { py::class_(m, "SchSwchParams") .def(py::init<>()) .def("GetSecurityLevelCKKS", &SchSwchParams::GetSecurityLevelCKKS) @@ -1562,6 +1577,13 @@ void bind_sch_swch_params(py::module &m) }); } +void bind_utils(py::module& m) { + m.def("EnablePrecomputeCRTTablesAfterDeserializaton", &lbcrypto::EnablePrecomputeCRTTablesAfterDeserializaton, + py::doc("Enable CRT precomputation after deserialization")); + m.def("DisablePrecomputeCRTTablesAfterDeserializaton", &lbcrypto::DisablePrecomputeCRTTablesAfterDeserializaton, + py::doc("Disable CRT precomputation after deserialization")); +} + PYBIND11_MODULE(openfhe, m) { // sequence of function calls matters m.doc() = "Open-Source Fully Homomorphic Encryption Library"; @@ -1583,4 +1605,5 @@ PYBIND11_MODULE(openfhe, m) { bind_serialization(m); bind_schemes(m); bind_sch_swch_params(m); + bind_utils(m); }