Skip to content

Commit

Permalink
Merge pull request #197 from openfheorg/dev
Browse files Browse the repository at this point in the history
Updates main to v0.9.4
  • Loading branch information
yspolyakov authored Oct 6, 2022
2 parents f4def82 + 09859e4 commit a82c4d9
Show file tree
Hide file tree
Showing 57 changed files with 1,298 additions and 1,072 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ project (OpenFHE C CXX)

set(OPENFHE_VERSION_MAJOR 0)
set(OPENFHE_VERSION_MINOR 9)
set(OPENFHE_VERSION_PATCH 3)
set(OPENFHE_VERSION_PATCH 4)
set(OPENFHE_VERSION ${OPENFHE_VERSION_MAJOR}.${OPENFHE_VERSION_MINOR}.${OPENFHE_VERSION_PATCH})

set(CMAKE_CXX_STANDARD 17)
Expand Down
5 changes: 5 additions & 0 deletions docs/static_docs/Release_Notes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
10/05/2022: OpenFHE 0.9.4 (development) is released

* Fixes build errors for NATIVE_SIZE=32
* Includes other small bug fixes

09/16/2022: OpenFHE 0.9.3 (development) is released

* Fixes build errors in MinGW
Expand Down
2 changes: 2 additions & 0 deletions src/binfhe/unittest/UnitTestFunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ using namespace lbcrypto;
// --------------- TESTING METHODS OF FHEW ---------------

// Checks the arbitrary function evaluation
#if NATIVEINT != 32
TEST(UnitTestFHEWGINX, EvalArbFunc) {
auto cc = BinFHEContext();
cc.GenerateBinFHEContext(TOY, true, 12);
Expand Down Expand Up @@ -203,3 +204,4 @@ TEST(UnitTestFHEWGINX, EvalDigitDecompSpace) {
EXPECT_EQ(usint(ceil(log(factor) / log(p_basic)) + 1), decomp.size()) << failed;
}
}
#endif
6 changes: 5 additions & 1 deletion src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ set (CORELIBS ${CORELIBS} PUBLIC OPENFHEcore_static ${THIRDPARTYSTATICLIBS} ${Op
endif()

if( BUILD_UNITTESTS )
file (GLOB CORE_TEST_SRC_FILES CONFIGURE_DEPENDS unittest/*.cpp)
if( "${NATIVE_SIZE}" EQUAL 32 )
message("**** core_tests are not linked for NATIVE_SIZE=32")
else()
file (GLOB CORE_TEST_SRC_FILES CONFIGURE_DEPENDS unittest/*.cpp)
endif()
set (CORE_TEST_SRC_FILES ${CORE_TEST_SRC_FILES})
add_executable( core_tests ${CORE_TEST_SRC_FILES} ${UNITTESTMAIN} )
set_property(TARGET core_tests PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/unittest)
Expand Down
23 changes: 14 additions & 9 deletions src/core/include/lattice/hal/dcrtpoly-interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,15 @@ class DCRTPolyInterface : public ILElement<DerivedType, BigVecType> {
*/
virtual DerivedType Times(const std::vector<NativeInteger>& element) const = 0;

/**
* @brief Performs a multiplication operation even when the multiplicands
* have a different number of towers.
*
* @param &element is the element to multiply with.
* @return is the result of the multiplication.
*/
virtual DerivedType TimesNoCheck(const std::vector<NativeInteger>& element) const = 0;

/**
* @brief Scalar modular multiplication by an integer represented in CRT
* Basis.
Expand Down Expand Up @@ -881,12 +890,9 @@ class DCRTPolyInterface : public ILElement<DerivedType, BigVecType> {
*/
virtual std::shared_ptr<Params> GetExtendedCRTBasis(std::shared_ptr<Params> paramsP) const = 0;

virtual void TimesQovert(
const std::shared_ptr<Params> paramsQ,
const std::vector<NativeInteger> &tInvModq,
const NativeInteger &t,
const NativeInteger &NegQModt,
const NativeInteger &NegQModtPrecon) = 0;
virtual void TimesQovert(const std::shared_ptr<Params> paramsQ, const std::vector<NativeInteger>& tInvModq,
const NativeInteger& t, const NativeInteger& NegQModt,
const NativeInteger& NegQModtPrecon) = 0;

/**
* @brief Performs approximate CRT basis switching:
Expand Down Expand Up @@ -1180,9 +1186,8 @@ class DCRTPolyInterface : public ILElement<DerivedType, BigVecType> {
* @param &pInvModq p^{-1}_{q_i}
* @return
*/
virtual void ScaleAndRoundPOverQ(
const std::shared_ptr<Params> paramsQ,
const std::vector<NativeInteger> &pInvModq) = 0;
virtual void ScaleAndRoundPOverQ(const std::shared_ptr<Params> paramsQ,
const std::vector<NativeInteger>& pInvModq) = 0;

/**
* @brief Expands basis:
Expand Down
23 changes: 14 additions & 9 deletions src/core/include/lattice/hal/default/dcrtpoly.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,15 @@ class DCRTPolyImpl : public DCRTPolyInterface<DCRTPolyImpl<VecType>, VecType, Na
*/
DCRTPolyType Times(const std::vector<NativeInteger>& element) const override;

/**
* @brief Performs a multiplication operation even when the multiplicands
* have a different number of towers.
*
* @param &element is the element to multiply with.
* @return is the result of the multiplication.
*/
DCRTPolyType TimesNoCheck(const std::vector<NativeInteger>& element) const override;

/**
* @brief Scalar modular multiplication by an integer represented in CRT
* Basis.
Expand Down Expand Up @@ -810,12 +819,9 @@ class DCRTPolyImpl : public DCRTPolyInterface<DCRTPolyImpl<VecType>, VecType, Na
*/
std::shared_ptr<Params> GetExtendedCRTBasis(std::shared_ptr<Params> paramsP) const override;

void TimesQovert(
const std::shared_ptr<Params> paramsQ,
const std::vector<NativeInteger> &tInvModq,
const NativeInteger &t,
const NativeInteger &NegQModt,
const NativeInteger &NegQModtPrecon) override;
void TimesQovert(const std::shared_ptr<Params> paramsQ, const std::vector<NativeInteger>& tInvModq,
const NativeInteger& t, const NativeInteger& NegQModt,
const NativeInteger& NegQModtPrecon) override;

/**
* @brief Performs approximate CRT basis switching:
Expand Down Expand Up @@ -1158,9 +1164,8 @@ class DCRTPolyImpl : public DCRTPolyInterface<DCRTPolyImpl<VecType>, VecType, Na
* @param &pInvModq p^{-1}_{q_i}
* @return
*/
void ScaleAndRoundPOverQ(
const std::shared_ptr<DCRTPolyImpl::Params> paramsQ,
const std::vector<NativeInteger> &pInvModq) override;
void ScaleAndRoundPOverQ(const std::shared_ptr<DCRTPolyImpl::Params> paramsQ,
const std::vector<NativeInteger>& pInvModq) override;

/**
* @brief Expands basis:
Expand Down
151 changes: 106 additions & 45 deletions src/core/lib/lattice/hal/default/dcrtpoly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -907,12 +907,11 @@ DCRTPolyImpl<VecType> DCRTPolyImpl<VecType>::Times(const std::vector<Integer>& c
}
return tmp;
}

template <typename VecType>
DCRTPolyImpl<VecType> DCRTPolyImpl<VecType>::Times(const std::vector<NativeInteger>& element) const {
// if (m_vectors.size() != element.size()) {
// OPENFHE_THROW(math_error, "tower size mismatch; cannot multiply");
// }
if (m_vectors.size() != element.size()) {
OPENFHE_THROW(math_error, "tower size mismatch; cannot multiply");
}
DCRTPolyImpl<VecType> tmp(*this);

#pragma omp parallel for
Expand All @@ -922,6 +921,18 @@ DCRTPolyImpl<VecType> DCRTPolyImpl<VecType>::Times(const std::vector<NativeInteg
return tmp;
}

template <typename VecType>
DCRTPolyImpl<VecType> DCRTPolyImpl<VecType>::TimesNoCheck(const std::vector<NativeInteger>& element) const {
size_t vecSize = m_vectors.size() < element.size() ? m_vectors.size() : element.size();
DCRTPolyImpl<VecType> tmp(*this);

#pragma omp parallel for
for (usint i = 0; i < vecSize; i++) {
tmp.m_vectors[i] *= element[i];
}
return tmp;
}

template <typename VecType>
const DCRTPolyImpl<VecType>& DCRTPolyImpl<VecType>::operator*=(const Integer& element) {
for (usint i = 0; i < this->m_vectors.size(); i++) {
Expand Down Expand Up @@ -1380,25 +1391,22 @@ std::shared_ptr<typename DCRTPolyImpl<VecType>::Params> DCRTPolyImpl<VecType>::G
}

template <typename VecType>
void DCRTPolyImpl<VecType>::TimesQovert(
const std::shared_ptr<DCRTPolyImpl::Params> paramsQ,
const std::vector<NativeInteger> &tInvModq,
const NativeInteger &t,
const NativeInteger &NegQModt,
const NativeInteger &NegQModtPrecon) {
usint sizeQ = m_vectors.size();
if (tInvModq.size() < sizeQ) {
OPENFHE_THROW(math_error, "Sizes of vectors do not match.");
}
usint ringDim = this->GetRingDimension();
void DCRTPolyImpl<VecType>::TimesQovert(const std::shared_ptr<DCRTPolyImpl::Params> paramsQ,
const std::vector<NativeInteger>& tInvModq, const NativeInteger& t,
const NativeInteger& NegQModt, const NativeInteger& NegQModtPrecon) {
usint sizeQ = m_vectors.size();
if (tInvModq.size() < sizeQ) {
OPENFHE_THROW(math_error, "Sizes of vectors do not match.");
}
usint ringDim = this->GetRingDimension();
#pragma omp parallel for
for (size_t i = 0; i < sizeQ; i++) {
for (usint ri = 0; ri < ringDim; ri++) {
NativeInteger &xi = m_vectors[i][ri];
xi.ModMulFastConstEq(NegQModt, t, NegQModtPrecon);
for (size_t i = 0; i < sizeQ; i++) {
for (usint ri = 0; ri < ringDim; ri++) {
NativeInteger& xi = m_vectors[i][ri];
xi.ModMulFastConstEq(NegQModt, t, NegQModtPrecon);
}
}
}
*this = this->Times(tInvModq);
*this = this->Times(tInvModq);
}

#if defined(HAVE_INT128) && NATIVEINT == 64 && !defined(__EMSCRIPTEN__)
Expand Down Expand Up @@ -1564,7 +1572,7 @@ DCRTPolyImpl<VecType> DCRTPolyImpl<VecType>::ApproxModDown(
return ans;
}

#if defined(HAVE_INT128) && NATIVEINT == 64
#if defined(HAVE_INT128) && NATIVEINT == 64 && !defined(__EMSCRIPTEN__)
template <typename VecType>
DCRTPolyImpl<VecType> DCRTPolyImpl<VecType>::SwitchCRTBasis(const std::shared_ptr<DCRTPolyImpl::Params> paramsP,
const std::vector<NativeInteger>& QHatInvModq,
Expand Down Expand Up @@ -1732,6 +1740,7 @@ void DCRTPolyImpl<VecType>::ExpandCRTBasis(
this->m_params = paramsQP;
}

#if defined(HAVE_INT128) && NATIVEINT == 64 && !defined(__EMSCRIPTEN__)
template <typename VecType>
void DCRTPolyImpl<VecType>::FastExpandCRTBasisPloverQ(const CRTBasisExtensionPrecomputations precomputed) {
usint ringDim = this->GetRingDimension();
Expand All @@ -1742,7 +1751,7 @@ void DCRTPolyImpl<VecType>::FastExpandCRTBasisPloverQ(const CRTBasisExtensionPre
const size_t sizePl = partPl.m_vectors.size();

// (k + kl)n
#pragma omp parallel for
#pragma omp parallel for
for (usint ri = 0; ri < ringDim; ri++) {
std::vector<DoubleNativeInt> sum(sizePl);
for (usint i = 0; i < sizeQ; i++) {
Expand Down Expand Up @@ -1775,19 +1784,72 @@ void DCRTPolyImpl<VecType>::FastExpandCRTBasisPloverQ(const CRTBasisExtensionPre
// Expand with zeros as should be
m_vectors.resize(sizeQlPl);

#pragma omp parallel for
#pragma omp parallel for
for (size_t i = 0; i < sizeQl; i++) {
m_vectors[i] = partQl.m_vectors[i];
}

// We cannot use two indices in one for loop with omp parallel for.
#pragma omp parallel for
// We cannot use two indices in one for loop with omp parallel for.
#pragma omp parallel for
for (size_t j = 0; j < sizePl; j++) {
m_vectors[sizeQl + j] = partPl.m_vectors[j];
}

this->m_params = precomputed.paramsQlPl;
}
#else
template <typename VecType>
void DCRTPolyImpl<VecType>::FastExpandCRTBasisPloverQ(const CRTBasisExtensionPrecomputations precomputed) {
usint ringDim = this->GetRingDimension();

size_t sizeQ = m_vectors.size();

DCRTPolyType partPl(precomputed.paramsPl, this->m_format, true);
const size_t sizePl = partPl.m_vectors.size();

// (k + kl)n
#pragma omp parallel for
for (usint ri = 0; ri < ringDim; ri++) {
std::vector<DoubleNativeInt> sum(sizePl);
for (usint i = 0; i < sizeQ; i++) {
const NativeInteger& xi = m_vectors[i][ri];
const NativeInteger& qi = m_vectors[i].GetModulus();
const std::vector<NativeInteger>& qInvModpi = precomputed.qInvModp[i];
NativeInteger xQHatInvModqi =
xi.ModMulFastConst(precomputed.mPlQHatInvModq[i], qi, precomputed.mPlQHatInvModqPrecon[i]);
for (usint j = 0; j < sizePl; j++) {
const NativeInteger& pj = partPl.m_vectors[j].GetModulus();
const NativeInteger mu_j = pj.ComputeMu();
partPl.m_vectors[j][ri].ModAddFastEq(xQHatInvModqi.ModMulFast(qInvModpi[j], pj, mu_j), pj);
}
}
}

// EMM: (l + ll)n
// EFP: ln
DCRTPolyType partQl = partPl.SwitchCRTBasis(precomputed.paramsQl, precomputed.PlHatInvModp,
precomputed.PlHatInvModpPrecon, precomputed.PlHatModq,
precomputed.alphaPlModq, precomputed.modqBarrettMu, precomputed.pInv);

const size_t sizeQl = sizePl;
const size_t sizeQlPl = sizePl + sizeQl;
// Expand with zeros as should be
m_vectors.resize(sizeQlPl);

#pragma omp parallel for
for (size_t i = 0; i < sizeQl; i++) {
m_vectors[i] = partQl.m_vectors[i];
}

// We cannot use two indices in one for loop with omp parallel for.
#pragma omp parallel for
for (size_t j = 0; j < sizePl; j++) {
m_vectors[sizeQl + j] = partPl.m_vectors[j];
}

this->m_params = precomputed.paramsQlPl;
}
#endif

template <typename VecType>
void DCRTPolyImpl<VecType>::ExpandCRTBasisQlHat(const std::shared_ptr<DCRTPolyImpl::Params> paramsQ,
Expand Down Expand Up @@ -2094,7 +2156,7 @@ PolyImpl<NativeVector> DCRTPolyImpl<VecType>::ScaleAndRound(
return result;
}

#if defined(HAVE_INT128) && NATIVEINT == 64
#if defined(HAVE_INT128) && NATIVEINT == 64 && !defined(__EMSCRIPTEN__)
template <typename VecType>
DCRTPolyImpl<VecType> DCRTPolyImpl<VecType>::ApproxScaleAndRound(
const std::shared_ptr<DCRTPolyImpl::Params> paramsP,
Expand Down Expand Up @@ -2168,7 +2230,7 @@ DCRTPolyImpl<VecType> DCRTPolyImpl<VecType>::ApproxScaleAndRound(
}
#endif

#if defined(HAVE_INT128) && NATIVEINT == 64
#if defined(HAVE_INT128) && NATIVEINT == 64 && !defined(__EMSCRIPTEN__)
template <typename VecType>
DCRTPolyImpl<VecType> DCRTPolyImpl<VecType>::ScaleAndRound(
const std::shared_ptr<DCRTPolyImpl::Params> paramsOutput,
Expand Down Expand Up @@ -2333,24 +2395,23 @@ PolyImpl<NativeVector> DCRTPolyImpl<VecType>::ScaleAndRound(
}

template <typename VecType>
void DCRTPolyImpl<VecType>::ScaleAndRoundPOverQ(
const std::shared_ptr<DCRTPolyImpl::Params> paramsQ,
const std::vector<NativeInteger> &pInvModq) {
usint sizeQ1 = m_vectors.size();
usint sizeQ = sizeQ1 - 1;
usint ringDim = this->GetRingDimension();
for (usint i = 0; i < sizeQ; i++) {
const NativeInteger &qi = paramsQ->GetParams()[i]->GetModulus();
for (usint ri = 0; ri < ringDim; ri++) {
this->m_vectors[i][ri].ModSubEq(m_vectors[sizeQ][ri], qi);
void DCRTPolyImpl<VecType>::ScaleAndRoundPOverQ(const std::shared_ptr<DCRTPolyImpl::Params> paramsQ,
const std::vector<NativeInteger>& pInvModq) {
usint sizeQ1 = m_vectors.size();
usint sizeQ = sizeQ1 - 1;
usint ringDim = this->GetRingDimension();
for (usint i = 0; i < sizeQ; i++) {
const NativeInteger& qi = paramsQ->GetParams()[i]->GetModulus();
for (usint ri = 0; ri < ringDim; ri++) {
this->m_vectors[i][ri].ModSubEq(m_vectors[sizeQ][ri], qi);
}
}
}
this->m_vectors.resize(sizeQ);
*this = this->Times(pInvModq);
this->m_params = paramsQ;
this->m_vectors.resize(sizeQ);
*this = this->Times(pInvModq);
this->m_params = paramsQ;
}

#if defined(HAVE_INT128) && NATIVEINT == 64
#if defined(HAVE_INT128) && NATIVEINT == 64 && !defined(__EMSCRIPTEN__)
template <typename VecType>
void DCRTPolyImpl<VecType>::FastBaseConvqToBskMontgomery(
const std::shared_ptr<DCRTPolyImpl::Params> paramsBsk, const std::vector<NativeInteger>& moduliQ,
Expand Down Expand Up @@ -2608,7 +2669,7 @@ void DCRTPolyImpl<VecType>::FastBaseConvqToBskMontgomery(
ximtildeQHatModqi = nullptr;
}
#endif
#if defined(HAVE_INT128) && NATIVEINT == 64
#if defined(HAVE_INT128) && NATIVEINT == 64 && !defined(__EMSCRIPTEN__)
template <typename VecType>
void DCRTPolyImpl<VecType>::FastRNSFloorq(
const NativeInteger& t, const std::vector<NativeInteger>& moduliQ, const std::vector<NativeInteger>& moduliBsk,
Expand Down Expand Up @@ -2736,7 +2797,7 @@ void DCRTPolyImpl<VecType>::FastRNSFloorq(
}
#endif

#if defined(HAVE_INT128) && NATIVEINT == 64
#if defined(HAVE_INT128) && NATIVEINT == 64 && !defined(__EMSCRIPTEN__)
template <typename VecType>
void DCRTPolyImpl<VecType>::FastBaseConvSK(
const std::shared_ptr<Params> paramsQ, const std::vector<DoubleNativeInt>& modqBarrettMu,
Expand Down
Loading

0 comments on commit a82c4d9

Please sign in to comment.