Skip to content

Commit 8686a7e

Browse files
Added bindings for new APIs and constants defined in OpenFHE v1.3.0 (#221)
Co-authored-by: Dmitriy Suponitskiy <[email protected]>
1 parent 978d4d6 commit 8686a7e

File tree

3 files changed

+120
-1
lines changed

3 files changed

+120
-1
lines changed

src/include/docstrings/cryptocontext_docs.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,47 @@ const char* cc_MultiAddEvalMultKeys_docs = R"pbdoc(
10711071
:rtype: EvalKey
10721072
)pbdoc";
10731073

1074+
const char* cc_IntBootDecrypt_docs = R"pbdoc(
1075+
Performs masked decryption for interactive bootstrapping (2-party protocol).
1076+
1077+
:param privateKey: Secret key share
1078+
:type privateKey: PrivateKey
1079+
:param ciphertext: Input Ciphertext
1080+
:type ciphertext: Ciphertext
1081+
:return: Resulting ciphertext
1082+
:rtype: Ciphertext
1083+
)pbdoc";
1084+
1085+
const char* cc_IntBootEncrypt_docs = R"pbdoc(
1086+
Encrypts Client's masked decryption for interactive bootstrapping. Increases ciphertext modulus to allow further computation. Done by Client.
1087+
1088+
:param publicKey: Joined public key (Threshold FHE)
1089+
:type publicKey: PublicKey
1090+
:param ciphertext: Input Ciphertext
1091+
:type ciphertext: Ciphertext
1092+
:return: Resulting ciphertext
1093+
:rtype: Ciphertext
1094+
)pbdoc";
1095+
1096+
const char* cc_IntBootAdd_docs = R"pbdoc(
1097+
Combines encrypted and unencrypted masked decryptions in 2-party interactive bootstrapping. It is the last step in the boostrapping.
1098+
1099+
:param ciphertext1: Encrypted masked decryption
1100+
:type ciphertext1: Ciphertext
1101+
:param ciphertext2: Unencrypted masked decryption
1102+
:type ciphertext2: Ciphertext
1103+
:return: Refreshed ciphertext
1104+
:rtype: Ciphertext
1105+
)pbdoc";
1106+
1107+
const char* cc_IntBootAdjustScale_docs = R"pbdoc(
1108+
Prepares a ciphertext for interactive bootstrapping.
1109+
1110+
:param ciphertext: Input ciphertext
1111+
:type ciphertext: Ciphertext
1112+
:return: Adjusted ciphertext
1113+
:rtype: Ciphertext
1114+
)pbdoc";
10741115

10751116
const char* cc_IntMPBootAdjustScale_docs = R"pbdoc(
10761117
Threshold FHE: Prepare a ciphertext for Multi-Party Interactive Bootstrapping.

src/include/docstrings/cryptoparameters_docs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ const char* ccparams_doc = R"doc(
6363
:ivar int multiHopModSize: size of moduli used for PRE in the provable HRA setting
6464
:ivar EncryptionTechnique encryptionTechnique: STANDARD or EXTENDED mode for BFV encryption
6565
:ivar MultiplicationTechnique multiplicationTechnique: multiplication method in BFV: BEHZ, HPS, etc.
66+
:ivar CKKSDataType ckksDataType: CKKS data type: real or complex. Noise flooding is only enabled for real values.
67+
:ivar uint32_t compositeDegree: parameter to support high-precision CKKS RNS with small word sizes
68+
:ivar uint32_t registerWordSize: parameter to support high-precision CKKS RNS with small word sizes
6669
)doc";
6770

6871
const char* cc_GetScalingFactorReal_docs = R"pbdoc(

src/lib/bindings.cpp

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ namespace py = pybind11;
5454
// disable the PYBIND11 template-based conversion for this type
5555
PYBIND11_MAKE_OPAQUE(std::map<uint32_t, EvalKey<DCRTPoly>>);
5656

57+
inline std::shared_ptr<CryptoParametersRNS> GetParamsRNSChecked(const CryptoContext<DCRTPoly>& self, const std::string& func) {
58+
auto ptr = std::dynamic_pointer_cast<CryptoParametersRNS>(self->GetCryptoParameters());
59+
if (!ptr)
60+
OPENFHE_THROW("Failed to cast to CryptoParametersRNS in " + func + "()");
61+
return ptr;
62+
}
63+
5764
template <typename T>
5865
void bind_parameters(py::module &m,const std::string name)
5966
{
@@ -90,6 +97,9 @@ void bind_parameters(py::module &m,const std::string name)
9097
.def("GetMultiplicationTechnique", &CCParams<T>::GetMultiplicationTechnique)
9198
.def("GetPRENumHops", &CCParams<T>::GetPRENumHops)
9299
.def("GetInteractiveBootCompressionLevel", &CCParams<T>::GetInteractiveBootCompressionLevel)
100+
.def("GetCompositeDegree", &CCParams<T>::GetCompositeDegree)
101+
.def("GetRegisterWordSize", &CCParams<T>::GetRegisterWordSize)
102+
.def("GetCKKSDataType", &CCParams<T>::GetCKKSDataType)
93103
// setters
94104
.def("SetPlaintextModulus", &CCParams<T>::SetPlaintextModulus)
95105
.def("SetDigitSize", &CCParams<T>::SetDigitSize)
@@ -120,6 +130,9 @@ void bind_parameters(py::module &m,const std::string name)
120130
.def("SetMultiplicationTechnique", &CCParams<T>::SetMultiplicationTechnique)
121131
.def("SetPRENumHops", &CCParams<T>::SetPRENumHops)
122132
.def("SetInteractiveBootCompressionLevel", &CCParams<T>::SetInteractiveBootCompressionLevel)
133+
.def("SetCompositeDegree", &CCParams<T>::SetCompositeDegree)
134+
.def("SetRegisterWordSize", &CCParams<T>::SetRegisterWordSize)
135+
.def("SetCKKSDataType", &CCParams<T>::SetCKKSDataType)
123136
.def("__str__",[](const CCParams<T> &params) {
124137
std::stringstream stream;
125138
stream << params;
@@ -155,6 +168,43 @@ void bind_crypto_context(py::module &m)
155168
.def("GetScalingTechnique",&GetScalingTechniqueWrapper)
156169
.def("GetDigitSize", &GetDigitSizeWrapper)
157170
.def("GetCyclotomicOrder", &CryptoContextImpl<DCRTPoly>::GetCyclotomicOrder, cc_GetCyclotomicOrder_docs)
171+
.def("GetCKKSDataType", &CryptoContextImpl<DCRTPoly>::GetCKKSDataType)
172+
.def("GetNoiseEstimate", [](CryptoContext<DCRTPoly>& self) {
173+
return GetParamsRNSChecked(self, "GetNoiseEstimate")->GetNoiseEstimate();
174+
})
175+
.def("SetNoiseEstimate", [](CryptoContext<DCRTPoly>& self, double noiseEstimate) {
176+
GetParamsRNSChecked(self, "SetNoiseEstimate")->SetNoiseEstimate(noiseEstimate);
177+
}, py::arg("noiseEstimate"))
178+
.def("GetMultiplicativeDepth", [](CryptoContext<DCRTPoly>& self) {
179+
return GetParamsRNSChecked(self, "GetMultiplicativeDepth")->GetMultiplicativeDepth();
180+
})
181+
.def("SetMultiplicativeDepth", [](CryptoContext<DCRTPoly>& self, uint32_t multiplicativeDepth) {
182+
GetParamsRNSChecked(self, "SetMultiplicativeDepth")->SetMultiplicativeDepth(multiplicativeDepth);
183+
}, py::arg("multiplicativeDepth"))
184+
.def("GetEvalAddCount", [](CryptoContext<DCRTPoly>& self) {
185+
return GetParamsRNSChecked(self, "GetEvalAddCount")->GetEvalAddCount();
186+
})
187+
.def("SetEvalAddCount", [](CryptoContext<DCRTPoly>& self, uint32_t evalAddCount) {
188+
GetParamsRNSChecked(self, "SetEvalAddCount")->SetEvalAddCount(evalAddCount);
189+
}, py::arg("evalAddCount"))
190+
.def("GetKeySwitchCount", [](CryptoContext<DCRTPoly>& self) {
191+
return GetParamsRNSChecked(self, "GetKeySwitchCount")->GetKeySwitchCount();
192+
})
193+
.def("SetKeySwitchCount", [](CryptoContext<DCRTPoly>& self, uint32_t keySwitchCount) {
194+
GetParamsRNSChecked(self, "SetKeySwitchCount")->SetKeySwitchCount(keySwitchCount);
195+
}, py::arg("keySwitchCount"))
196+
.def("GetPRENumHops", [](CryptoContext<DCRTPoly>& self) {
197+
return GetParamsRNSChecked(self, "GetPRENumHops")->GetPRENumHops();
198+
})
199+
.def("SetPRENumHops", [](CryptoContext<DCRTPoly>& self, uint32_t PRENumHops) {
200+
GetParamsRNSChecked(self, "SetPRENumHops")->SetPRENumHops(PRENumHops);
201+
}, py::arg("PRENumHops"))
202+
.def("GetRegisterWordSize", [](CryptoContext<DCRTPoly>& self) {
203+
return GetParamsRNSChecked(self, "GetRegisterWordSize")->GetRegisterWordSize();
204+
})
205+
.def("GetCompositeDegree", [](CryptoContext<DCRTPoly>& self) {
206+
return GetParamsRNSChecked(self, "GetCompositeDegree")->GetCompositeDegree();
207+
})
158208
.def("Enable", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(PKESchemeFeature)>(&CryptoContextImpl<DCRTPoly>::Enable), cc_Enable_docs,
159209
py::arg("feature"))
160210
.def("KeyGen", &CryptoContextImpl<DCRTPoly>::KeyGen, cc_KeyGen_docs)
@@ -572,6 +622,21 @@ void bind_crypto_context(py::module &m)
572622
py::arg("evalKey1"),
573623
py::arg("evalKey2"),
574624
py::arg("keyTag") = "")
625+
.def("IntBootDecrypt",&CryptoContextImpl<DCRTPoly>::IntBootDecrypt,
626+
cc_IntBootDecrypt_docs,
627+
py::arg("privateKey"),
628+
py::arg("ciphertext"))
629+
.def("IntBootEncrypt",&CryptoContextImpl<DCRTPoly>::IntBootEncrypt,
630+
cc_IntBootEncrypt_docs,
631+
py::arg("publicKey"),
632+
py::arg("ciphertext"))
633+
.def("IntBootAdd",&CryptoContextImpl<DCRTPoly>::IntBootAdd,
634+
cc_IntBootAdd_docs,
635+
py::arg("ciphertext1"),
636+
py::arg("ciphertext2"))
637+
.def("IntBootAdjustScale",&CryptoContextImpl<DCRTPoly>::IntBootAdjustScale,
638+
cc_IntBootAdjustScale_docs,
639+
py::arg("ciphertext"))
575640
.def("IntMPBootAdjustScale",&CryptoContextImpl<DCRTPoly>::IntMPBootAdjustScale,
576641
cc_IntMPBootAdjustScale_docs,
577642
py::arg("ciphertext"))
@@ -971,12 +1036,16 @@ void bind_enums_and_constants(py::module &m)
9711036
.value("FLEXIBLEAUTO", ScalingTechnique::FLEXIBLEAUTO)
9721037
.value("FLEXIBLEAUTOEXT", ScalingTechnique::FLEXIBLEAUTOEXT)
9731038
.value("NORESCALE", ScalingTechnique::NORESCALE)
1039+
.value("COMPOSITESCALINGAUTO", ScalingTechnique::COMPOSITESCALINGAUTO)
1040+
.value("COMPOSITESCALINGMANUAL", ScalingTechnique::COMPOSITESCALINGMANUAL)
9741041
.value("INVALID_RS_TECHNIQUE", ScalingTechnique::INVALID_RS_TECHNIQUE);
9751042
m.attr("FIXEDMANUAL") = py::cast(ScalingTechnique::FIXEDMANUAL);
9761043
m.attr("FIXEDAUTO") = py::cast(ScalingTechnique::FIXEDAUTO);
9771044
m.attr("FLEXIBLEAUTO") = py::cast(ScalingTechnique::FLEXIBLEAUTO);
9781045
m.attr("FLEXIBLEAUTOEXT") = py::cast(ScalingTechnique::FLEXIBLEAUTOEXT);
9791046
m.attr("NORESCALE") = py::cast(ScalingTechnique::NORESCALE);
1047+
m.attr("COMPOSITESCALINGAUTO") = py::cast(ScalingTechnique::COMPOSITESCALINGAUTO);
1048+
m.attr("COMPOSITESCALINGMANUAL") = py::cast(ScalingTechnique::COMPOSITESCALINGMANUAL);
9801049
m.attr("INVALID_RS_TECHNIQUE") = py::cast(ScalingTechnique::INVALID_RS_TECHNIQUE);
9811050

9821051
// Key Switching Techniques
@@ -1055,7 +1124,13 @@ void bind_enums_and_constants(py::module &m)
10551124
.value("SLACK", COMPRESSION_LEVEL::SLACK);
10561125
m.attr("COMPACT") = py::cast(COMPRESSION_LEVEL::COMPACT);
10571126
m.attr("SLACK") = py::cast(COMPRESSION_LEVEL::SLACK);
1058-
1127+
1128+
py::enum_<CKKSDataType>(m,"CKKSDataType")
1129+
.value("REAL", CKKSDataType::REAL)
1130+
.value("COMPLEX", CKKSDataType::COMPLEX);
1131+
m.attr("REAL") = py::cast(CKKSDataType::REAL);
1132+
m.attr("COMPLEX") = py::cast(CKKSDataType::COMPLEX);
1133+
10591134
/* ---- CORE enums ---- */
10601135
// Security Level
10611136
py::enum_<SecurityLevel>(m,"SecurityLevel")

0 commit comments

Comments
 (0)