diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a3d5e4d3..b3dae0cc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,8 +32,8 @@ set(OPENFHE_VERSION_MINOR 5) set(OPENFHE_VERSION_PATCH 1) set(OPENFHE_VERSION ${OPENFHE_VERSION_MAJOR}.${OPENFHE_VERSION_MINOR}.${OPENFHE_VERSION_PATCH}) -set(CMAKE_CXX_STANDARD 17) -set(CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) #-------------------------------------------------------------------- # Build options @@ -128,12 +128,12 @@ message(STATUS "USE_MACPORTS: ${USE_MACPORTS}") # Compiler logic #-------------------------------------------------------------------- if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) - message(WARNING "GCC version should be at least 9.0.") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0) + message(WARNING "GCC version should be at least 13.0 for reliable C++23 support.") endif() elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10) - message(WARNING "Clang version should be at least 10.0.") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0) + message(WARNING "Clang version should be at least 17.0 for reliable C++23 support.") endif() else() message(WARNING "You are using ${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION}, which is unsupported.") @@ -169,13 +169,16 @@ endif() set(IGNORE_WARNINGS "") # initialize IGNORE_WARNINGS if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # Add -Wno-parentheses for compatibility with g++ - set (IGNORE_WARNINGS "-Wno-parentheses") + # Add -Wno-volatile to suppress C++20 deprecated-volatile warnings for intentional + # security-related volatile uses (e.g., secure_memset, blake2 memset_v) + set (IGNORE_WARNINGS "-Wno-parentheses -Wno-volatile") # We can use GNU built-in functions provided by GCC for debugging. ex: __builtin_LINE (), __builtin_FUNCTION (), __builtin_FILE () add_definitions(-DBUILTIN_INFO_AVAILABLE) message(STATUS "BUILTIN_INFO_AVAILABLE is defined") elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set (IGNORE_WARNINGS "-Wno-parentheses") if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(IGNORE_WARNINGS "-Wno-unused-private-field -Wno-shift-op-parentheses") + string(APPEND IGNORE_WARNINGS " -Wno-unused-private-field -Wno-shift-op-parentheses") endif() endif() if(IGNORE_WARNINGS) diff --git a/src/core/include/lattice/field2n.h b/src/core/include/lattice/field2n.h index 5a90277d2..14f663e71 100644 --- a/src/core/include/lattice/field2n.h +++ b/src/core/include/lattice/field2n.h @@ -348,7 +348,7 @@ class Field2n : public std::vector>, public Serializable { std::string SerializedObjectName() const override { return "Field2n"; } - static uint32_t SerializedVersion() { + static constexpr uint32_t SerializedVersion() { return 1; } }; diff --git a/src/core/include/lattice/hal/default/dcrtpoly.h b/src/core/include/lattice/hal/default/dcrtpoly.h index ca8138a16..3da996574 100644 --- a/src/core/include/lattice/hal/default/dcrtpoly.h +++ b/src/core/include/lattice/hal/default/dcrtpoly.h @@ -359,11 +359,11 @@ class DCRTPolyImpl final : public DCRTPolyInterface, VecTy return "DCRTPoly"; } - static uint32_t SerializedVersion() { + static constexpr uint32_t SerializedVersion() { return 1; } - inline Format GetFormat() const final { + constexpr Format GetFormat() const final { return m_format; } diff --git a/src/core/include/lattice/hal/default/ildcrtparams.h b/src/core/include/lattice/hal/default/ildcrtparams.h index cc15bc084..3e841b9c8 100644 --- a/src/core/include/lattice/hal/default/ildcrtparams.h +++ b/src/core/include/lattice/hal/default/ildcrtparams.h @@ -348,7 +348,7 @@ class ILDCRTParams final : public ElemParams { std::string SerializedObjectName() const override { return "DCRTParams"; } - static uint32_t SerializedVersion() { + static constexpr uint32_t SerializedVersion() { return 1; } diff --git a/src/core/include/lattice/hal/default/ilparams.h b/src/core/include/lattice/hal/default/ilparams.h index b3ad215cd..f80e56168 100644 --- a/src/core/include/lattice/hal/default/ilparams.h +++ b/src/core/include/lattice/hal/default/ilparams.h @@ -152,7 +152,7 @@ class ILParamsImpl final : public ElemParams { return "ILParms"; } - static uint32_t SerializedVersion() { + static constexpr uint32_t SerializedVersion() { return 1; } diff --git a/src/core/include/lattice/hal/default/poly.h b/src/core/include/lattice/hal/default/poly.h index 629481b29..468887448 100644 --- a/src/core/include/lattice/hal/default/poly.h +++ b/src/core/include/lattice/hal/default/poly.h @@ -358,7 +358,7 @@ class PolyImpl final : public PolyInterface, VecType, PolyImpl return "Poly"; } - static uint32_t SerializedVersion() { + static constexpr uint32_t SerializedVersion() { return 1; } diff --git a/src/core/include/lattice/hal/elemparams.h b/src/core/include/lattice/hal/elemparams.h index 7521b3428..7dd685f01 100644 --- a/src/core/include/lattice/hal/elemparams.h +++ b/src/core/include/lattice/hal/elemparams.h @@ -147,7 +147,7 @@ class ElemParams : public Serializable { * @brief Simple getter method for cyclotomic order. * @return The cyclotomic order. */ - uint32_t GetCyclotomicOrder() const { + constexpr uint32_t GetCyclotomicOrder() const { return m_cyclotomicOrder; } @@ -156,7 +156,7 @@ class ElemParams : public Serializable { * evaluation of the totient function of the cyclotomic order. * @return the ring dimension. */ - uint32_t GetRingDimension() const { + constexpr uint32_t GetRingDimension() const { return m_ringDimension; } @@ -165,7 +165,7 @@ class ElemParams : public Serializable { * ciphertext modulus. * @return The ciphertext modulus, not the big ciphertext modulus. */ - const IntegerType& GetModulus() const { + constexpr const IntegerType& GetModulus() const { return m_ciphertextModulus; } @@ -174,7 +174,7 @@ class ElemParams : public Serializable { * This is not relevant for all applications. * @return The big ciphertext modulus. */ - const IntegerType& GetBigModulus() const { + constexpr const IntegerType& GetBigModulus() const { return m_bigCiphertextModulus; } @@ -183,7 +183,7 @@ class ElemParams : public Serializable { * unity. * @return The root of unity, not the big root of unity. */ - const IntegerType& GetRootOfUnity() const { + constexpr const IntegerType& GetRootOfUnity() const { return m_rootOfUnity; } @@ -191,7 +191,7 @@ class ElemParams : public Serializable { * @brief Simple getter method for the big root of unity. * @return The the big root of unity. */ - const IntegerType& GetBigRootOfUnity() const { + constexpr const IntegerType& GetBigRootOfUnity() const { return m_bigRootOfUnity; } @@ -251,7 +251,7 @@ class ElemParams : public Serializable { std::string SerializedObjectName() const override { return "ElemParams"; } - static uint32_t SerializedVersion() { + static constexpr uint32_t SerializedVersion() { return 1; } diff --git a/src/core/include/lattice/stdlatticeparms.h b/src/core/include/lattice/stdlatticeparms.h index b5b1af50b..efd373f2f 100644 --- a/src/core/include/lattice/stdlatticeparms.h +++ b/src/core/include/lattice/stdlatticeparms.h @@ -40,6 +40,7 @@ #include "utils/inttypes.h" +#include #include #include #include @@ -96,25 +97,18 @@ class StdLatticeParm { // will suffer MAKE SURE that the number of entries in the DistributionType // enum is == the first index, and MAKE SURE that the number of entries in the // SecurityLevel enum is == the second index - static std::map byRing[3][6]; - static std::map byLogQ[3][6]; + static std::map byRing[3][6]; + static std::map byLogQ[3][6]; - static std::vector StandardLatticeParmSets; static bool initialized; + // defined out-of-class below, after the anonymous namespace that holds the constexpr data + static void initializeLookups(); + public: - StdLatticeParm(DistributionType distType, uint32_t ringDim, SecurityLevel minSecLev, uint32_t maxLogQ) + constexpr StdLatticeParm(DistributionType distType, uint32_t ringDim, SecurityLevel minSecLev, uint32_t maxLogQ) : distType(distType), ringDim(ringDim), minSecLev(minSecLev), maxLogQ(maxLogQ) {} - static void initializeLookups() { - for (size_t i = 0; i < StandardLatticeParmSets.size(); i++) { - StdLatticeParm& s = StandardLatticeParmSets[i]; - byRing[static_cast(s.distType)][static_cast(s.minSecLev)][s.ringDim] = &s; - byLogQ[static_cast(s.distType)][static_cast(s.minSecLev)][s.maxLogQ] = &s; - } - initialized = true; - } - static uint32_t FindMaxQ(DistributionType distType, SecurityLevel minSecLev, uint32_t ringDim) { int distTypeIdx = static_cast(distType); int minSecLevIdx = static_cast(minSecLev); @@ -133,30 +127,183 @@ class StdLatticeParm { int distTypeIdx = static_cast(distType); int minSecLevIdx = static_cast(minSecLev); - uint32_t n = 0; - for (std::pair& it : byLogQ[distTypeIdx][minSecLevIdx]) { - if ((curLogQ <= it.second->getMaxLogQ()) && (curLogQ > prev)) - return it.second->getRingDim(); - prev = it.second->getMaxLogQ(); - n = it.second->getRingDim(); + uint32_t n = 0; + for (const auto& [key, parm] : byLogQ[distTypeIdx][minSecLevIdx]) { + if ((curLogQ <= parm->getMaxLogQ()) && (curLogQ > prev)) + return parm->getRingDim(); + prev = parm->getMaxLogQ(); + n = parm->getRingDim(); } return 2 * n; } - DistributionType getDistType() const { + constexpr DistributionType getDistType() const { return distType; } - uint32_t getRingDim() const { + constexpr uint32_t getRingDim() const { return ringDim; } - SecurityLevel getMinSecLev() const { + constexpr SecurityLevel getMinSecLev() const { return minSecLev; } - uint32_t getMaxLogQ() const { + constexpr uint32_t getMaxLogQ() const { return maxLogQ; } }; +// Anonymous namespace gives internal linkage (one copy per TU, like static). +// StdLatticeParm is complete here so std::vector can be initialized. +namespace { +constexpr auto StandardLatticeParmSets = std::to_array({ + StdLatticeParm(HEStd_uniform, 1024, HEStd_128_classic, 29), + StdLatticeParm(HEStd_uniform, 1024, HEStd_192_classic, 21), + StdLatticeParm(HEStd_uniform, 1024, HEStd_256_classic, 16), + StdLatticeParm(HEStd_uniform, 2048, HEStd_128_classic, 56), + StdLatticeParm(HEStd_uniform, 2048, HEStd_192_classic, 39), + StdLatticeParm(HEStd_uniform, 2048, HEStd_256_classic, 31), + StdLatticeParm(HEStd_uniform, 4096, HEStd_128_classic, 111), + StdLatticeParm(HEStd_uniform, 4096, HEStd_192_classic, 77), + StdLatticeParm(HEStd_uniform, 4096, HEStd_256_classic, 60), + StdLatticeParm(HEStd_uniform, 8192, HEStd_128_classic, 220), + StdLatticeParm(HEStd_uniform, 8192, HEStd_192_classic, 154), + StdLatticeParm(HEStd_uniform, 8192, HEStd_256_classic, 120), + StdLatticeParm(HEStd_uniform, 16384, HEStd_128_classic, 440), + StdLatticeParm(HEStd_uniform, 16384, HEStd_192_classic, 307), + StdLatticeParm(HEStd_uniform, 16384, HEStd_256_classic, 239), + StdLatticeParm(HEStd_uniform, 32768, HEStd_128_classic, 880), + StdLatticeParm(HEStd_uniform, 32768, HEStd_192_classic, 612), + StdLatticeParm(HEStd_uniform, 32768, HEStd_256_classic, 478), + + StdLatticeParm(HEStd_error, 1024, HEStd_128_classic, 29), + StdLatticeParm(HEStd_error, 1024, HEStd_192_classic, 21), + StdLatticeParm(HEStd_error, 1024, HEStd_256_classic, 16), + StdLatticeParm(HEStd_error, 2048, HEStd_128_classic, 56), + StdLatticeParm(HEStd_error, 2048, HEStd_192_classic, 39), + StdLatticeParm(HEStd_error, 2048, HEStd_256_classic, 31), + StdLatticeParm(HEStd_error, 4096, HEStd_128_classic, 111), + StdLatticeParm(HEStd_error, 4096, HEStd_192_classic, 77), + StdLatticeParm(HEStd_error, 4096, HEStd_256_classic, 60), + StdLatticeParm(HEStd_error, 8192, HEStd_128_classic, 220), + StdLatticeParm(HEStd_error, 8192, HEStd_192_classic, 154), + StdLatticeParm(HEStd_error, 8192, HEStd_256_classic, 120), + StdLatticeParm(HEStd_error, 16384, HEStd_128_classic, 440), + StdLatticeParm(HEStd_error, 16384, HEStd_192_classic, 307), + StdLatticeParm(HEStd_error, 16384, HEStd_256_classic, 239), + StdLatticeParm(HEStd_error, 32768, HEStd_128_classic, 883), + StdLatticeParm(HEStd_error, 32768, HEStd_192_classic, 613), + StdLatticeParm(HEStd_error, 32768, HEStd_256_classic, 478), + StdLatticeParm(HEStd_error, 65536, HEStd_128_classic, 1749), + StdLatticeParm(HEStd_error, 65536, HEStd_192_classic, 1201), + StdLatticeParm(HEStd_error, 65536, HEStd_256_classic, 931), + StdLatticeParm(HEStd_error, 131072, HEStd_128_classic, 3525), + StdLatticeParm(HEStd_error, 131072, HEStd_192_classic, 2413), + StdLatticeParm(HEStd_error, 131072, HEStd_256_classic, 1868), + + StdLatticeParm(HEStd_ternary, 1024, HEStd_128_classic, 27), + StdLatticeParm(HEStd_ternary, 1024, HEStd_192_classic, 19), + StdLatticeParm(HEStd_ternary, 1024, HEStd_256_classic, 14), + StdLatticeParm(HEStd_ternary, 2048, HEStd_128_classic, 54), + StdLatticeParm(HEStd_ternary, 2048, HEStd_192_classic, 37), + StdLatticeParm(HEStd_ternary, 2048, HEStd_256_classic, 29), + StdLatticeParm(HEStd_ternary, 4096, HEStd_128_classic, 109), + StdLatticeParm(HEStd_ternary, 4096, HEStd_192_classic, 75), + StdLatticeParm(HEStd_ternary, 4096, HEStd_256_classic, 58), + StdLatticeParm(HEStd_ternary, 8192, HEStd_128_classic, 218), + StdLatticeParm(HEStd_ternary, 8192, HEStd_192_classic, 152), + StdLatticeParm(HEStd_ternary, 8192, HEStd_256_classic, 118), + StdLatticeParm(HEStd_ternary, 16384, HEStd_128_classic, 438), + StdLatticeParm(HEStd_ternary, 16384, HEStd_192_classic, 305), + StdLatticeParm(HEStd_ternary, 16384, HEStd_256_classic, 237), + StdLatticeParm(HEStd_ternary, 32768, HEStd_128_classic, 881), + StdLatticeParm(HEStd_ternary, 32768, HEStd_192_classic, 611), + StdLatticeParm(HEStd_ternary, 32768, HEStd_256_classic, 476), + StdLatticeParm(HEStd_ternary, 65536, HEStd_128_classic, 1747), + StdLatticeParm(HEStd_ternary, 65536, HEStd_192_classic, 1199), + StdLatticeParm(HEStd_ternary, 65536, HEStd_256_classic, 929), + StdLatticeParm(HEStd_ternary, 131072, HEStd_128_classic, 3523), + StdLatticeParm(HEStd_ternary, 131072, HEStd_192_classic, 2411), + StdLatticeParm(HEStd_ternary, 131072, HEStd_256_classic, 1866), + + StdLatticeParm(HEStd_uniform, 1024, HEStd_128_quantum, 27), + StdLatticeParm(HEStd_uniform, 1024, HEStd_192_quantum, 19), + StdLatticeParm(HEStd_uniform, 1024, HEStd_256_quantum, 15), + StdLatticeParm(HEStd_uniform, 2048, HEStd_128_quantum, 53), + StdLatticeParm(HEStd_uniform, 2048, HEStd_192_quantum, 37), + StdLatticeParm(HEStd_uniform, 2048, HEStd_256_quantum, 29), + StdLatticeParm(HEStd_uniform, 4096, HEStd_128_quantum, 103), + StdLatticeParm(HEStd_uniform, 4096, HEStd_192_quantum, 72), + StdLatticeParm(HEStd_uniform, 4096, HEStd_256_quantum, 56), + StdLatticeParm(HEStd_uniform, 8192, HEStd_128_quantum, 206), + StdLatticeParm(HEStd_uniform, 8192, HEStd_192_quantum, 143), + StdLatticeParm(HEStd_uniform, 8192, HEStd_256_quantum, 111), + StdLatticeParm(HEStd_uniform, 16384, HEStd_128_quantum, 413), + StdLatticeParm(HEStd_uniform, 16384, HEStd_192_quantum, 286), + StdLatticeParm(HEStd_uniform, 16384, HEStd_256_quantum, 222), + StdLatticeParm(HEStd_uniform, 32768, HEStd_128_quantum, 829), + StdLatticeParm(HEStd_uniform, 32768, HEStd_192_quantum, 573), + StdLatticeParm(HEStd_uniform, 32768, HEStd_256_quantum, 445), + + StdLatticeParm(HEStd_error, 1024, HEStd_128_quantum, 27), + StdLatticeParm(HEStd_error, 1024, HEStd_192_quantum, 19), + StdLatticeParm(HEStd_error, 1024, HEStd_256_quantum, 15), + StdLatticeParm(HEStd_error, 2048, HEStd_128_quantum, 53), + StdLatticeParm(HEStd_error, 2048, HEStd_192_quantum, 37), + StdLatticeParm(HEStd_error, 2048, HEStd_256_quantum, 29), + StdLatticeParm(HEStd_error, 4096, HEStd_128_quantum, 103), + StdLatticeParm(HEStd_error, 4096, HEStd_192_quantum, 72), + StdLatticeParm(HEStd_error, 4096, HEStd_256_quantum, 56), + StdLatticeParm(HEStd_error, 8192, HEStd_128_quantum, 206), + StdLatticeParm(HEStd_error, 8192, HEStd_192_quantum, 143), + StdLatticeParm(HEStd_error, 8192, HEStd_256_quantum, 111), + StdLatticeParm(HEStd_error, 16384, HEStd_128_quantum, 413), + StdLatticeParm(HEStd_error, 16384, HEStd_192_quantum, 286), + StdLatticeParm(HEStd_error, 16384, HEStd_256_quantum, 222), + StdLatticeParm(HEStd_error, 32768, HEStd_128_quantum, 829), + StdLatticeParm(HEStd_error, 32768, HEStd_192_quantum, 573), + StdLatticeParm(HEStd_error, 32768, HEStd_256_quantum, 445), + StdLatticeParm(HEStd_error, 65536, HEStd_128_quantum, 1665), + StdLatticeParm(HEStd_error, 65536, HEStd_192_quantum, 1147), + StdLatticeParm(HEStd_error, 65536, HEStd_256_quantum, 890), + StdLatticeParm(HEStd_error, 131072, HEStd_128_quantum, 3351), + StdLatticeParm(HEStd_error, 131072, HEStd_192_quantum, 2304), + StdLatticeParm(HEStd_error, 131072, HEStd_256_quantum, 1786), + + StdLatticeParm(HEStd_ternary, 1024, HEStd_128_quantum, 25), + StdLatticeParm(HEStd_ternary, 1024, HEStd_192_quantum, 17), + StdLatticeParm(HEStd_ternary, 1024, HEStd_256_quantum, 13), + StdLatticeParm(HEStd_ternary, 2048, HEStd_128_quantum, 51), + StdLatticeParm(HEStd_ternary, 2048, HEStd_192_quantum, 35), + StdLatticeParm(HEStd_ternary, 2048, HEStd_256_quantum, 27), + StdLatticeParm(HEStd_ternary, 4096, HEStd_128_quantum, 101), + StdLatticeParm(HEStd_ternary, 4096, HEStd_192_quantum, 70), + StdLatticeParm(HEStd_ternary, 4096, HEStd_256_quantum, 54), + StdLatticeParm(HEStd_ternary, 8192, HEStd_128_quantum, 202), + StdLatticeParm(HEStd_ternary, 8192, HEStd_192_quantum, 141), + StdLatticeParm(HEStd_ternary, 8192, HEStd_256_quantum, 109), + StdLatticeParm(HEStd_ternary, 16384, HEStd_128_quantum, 411), + StdLatticeParm(HEStd_ternary, 16384, HEStd_192_quantum, 284), + StdLatticeParm(HEStd_ternary, 16384, HEStd_256_quantum, 220), + StdLatticeParm(HEStd_ternary, 32768, HEStd_128_quantum, 827), + StdLatticeParm(HEStd_ternary, 32768, HEStd_192_quantum, 571), + StdLatticeParm(HEStd_ternary, 32768, HEStd_256_quantum, 443), + StdLatticeParm(HEStd_ternary, 65536, HEStd_128_quantum, 1663), + StdLatticeParm(HEStd_ternary, 65536, HEStd_192_quantum, 1145), + StdLatticeParm(HEStd_ternary, 65536, HEStd_256_quantum, 888), + StdLatticeParm(HEStd_ternary, 131072, HEStd_128_quantum, 3348), + StdLatticeParm(HEStd_ternary, 131072, HEStd_192_quantum, 2301), + StdLatticeParm(HEStd_ternary, 131072, HEStd_256_quantum, 1784), +}); +} // anonymous namespace + +// Out-of-class definition placed here so it can see StandardLatticeParmSets above. +inline void StdLatticeParm::initializeLookups() { + for (const StdLatticeParm& s : StandardLatticeParmSets) { + byRing[static_cast(s.distType)][static_cast(s.minSecLev)][s.ringDim] = &s; + byLogQ[static_cast(s.distType)][static_cast(s.minSecLev)][s.maxLogQ] = &s; + } + initialized = true; +} + } /* namespace lbcrypto */ #endif diff --git a/src/core/include/math/hal/bigintdyn/mubintvecdyn.h b/src/core/include/math/hal/bigintdyn/mubintvecdyn.h index ee3a7fbb2..b45a394f9 100644 --- a/src/core/include/math/hal/bigintdyn/mubintvecdyn.h +++ b/src/core/include/math/hal/bigintdyn/mubintvecdyn.h @@ -226,7 +226,7 @@ class mubintvec final : public lbcrypto::BigVectorInterface #include - // clang-format off + // clang-format off // TODO: fix shifting issue when limb_t == Dlimb_t #if (NATIVEINT >= 64 && defined(HAVE_INT128)) using expdtype = uint64_t; @@ -159,7 +159,7 @@ class ubint final : public lbcrypto::BigIntegerInterface> { ubint() = default; - explicit operator bool() noexcept { + constexpr explicit operator bool() const noexcept { return m_MSB != 0; } @@ -167,9 +167,9 @@ class ubint final : public lbcrypto::BigIntegerInterface> { * Copy constructor. * @param &val is the ubint to be copied. */ - ubint(const ubint& val) noexcept : m_MSB{val.m_MSB}, m_value{val.m_value} {} + constexpr ubint(const ubint& val) noexcept : m_MSB{val.m_MSB}, m_value{val.m_value} {} - ubint(const std::vector& v) noexcept : m_value{v} { + constexpr ubint(const std::vector& v) noexcept : m_value{v} { this->ubint::NormalizeLimbs(); } @@ -177,9 +177,9 @@ class ubint final : public lbcrypto::BigIntegerInterface> { * Move constructor. * @param &&val is the ubint to be copied. */ - ubint(ubint&& val) noexcept : m_MSB{std::move(val.m_MSB)}, m_value{std::move(val.m_value)} {} + constexpr ubint(ubint&& val) noexcept : m_MSB{std::move(val.m_MSB)}, m_value{std::move(val.m_value)} {} - ubint(std::vector&& v) noexcept : m_value{std::move(v)} { + constexpr ubint(std::vector&& v) noexcept : m_value{std::move(v)} { this->ubint::NormalizeLimbs(); } @@ -193,14 +193,14 @@ class ubint final : public lbcrypto::BigIntegerInterface> { explicit ubint(const char* strval) { this->ubint::SetValue(std::string(strval)); } - explicit ubint(const char strval) : ubint(limb_t(strval - '0')) {} + constexpr explicit ubint(const char strval) : ubint(limb_t(strval - '0')) {} /** * Constructor from an unsigned integer. * @param val is the initial integer represented as a uint64_t. */ template , bool> = true> - ubint(T val) : m_MSB{lbcrypto::GetMSB(val)}, m_value{limb_t(val)} { + constexpr ubint(T val) : m_MSB{lbcrypto::GetMSB(val)}, m_value{limb_t(val)} { if constexpr (sizeof(T) > sizeof(limb_t)) { if ((val >>= m_limbBitLength) > 0) { m_value.resize(ubint::MSBToLimbs(m_MSB)); @@ -748,7 +748,7 @@ class ubint final : public lbcrypto::BigIntegerInterface> { * Returns the MSB location of the value. * @return the index of the most significant bit. */ - uint32_t GetMSB() const { + constexpr uint32_t GetMSB() const { return m_MSB; } @@ -756,7 +756,7 @@ class ubint final : public lbcrypto::BigIntegerInterface> { * Returns the size of the underlying vector of Limbs * @return the size */ - size_t GetNumberOfLimbs() const { + constexpr size_t GetNumberOfLimbs() const { return m_value.size(); } @@ -790,7 +790,7 @@ class ubint final : public lbcrypto::BigIntegerInterface> { */ // TODO hardcoded for base 2? - uint32_t GetLengthForBase(uint32_t base) const { + constexpr uint32_t GetLengthForBase(uint32_t base) const { return GetMSB(); } @@ -901,7 +901,7 @@ class ubint final : public lbcrypto::BigIntegerInterface> { return "DYNInteger"; } - static uint32_t SerializedVersion() { + static constexpr uint32_t SerializedVersion() { return 1; } @@ -921,7 +921,7 @@ class ubint final : public lbcrypto::BigIntegerInterface> { * * @return resulting bit. */ - void NormalizeLimbs() { + constexpr void NormalizeLimbs() { auto size = m_value.size() - 1; while (size > 0 && m_value[size--] == 0) m_value.pop_back(); diff --git a/src/core/include/math/hal/bigintfxd/mubintvecfxd.h b/src/core/include/math/hal/bigintfxd/mubintvecfxd.h index ab69b7a55..d0f4c0d12 100644 --- a/src/core/include/math/hal/bigintfxd/mubintvecfxd.h +++ b/src/core/include/math/hal/bigintfxd/mubintvecfxd.h @@ -589,7 +589,7 @@ class BigVectorFixedT final : public lbcrypto::BigVectorInterface, return "NTLVector"; } - static uint32_t SerializedVersion() { + static constexpr uint32_t SerializedVersion() { return 1; } diff --git a/src/core/include/math/hal/bigintntl/ubintntl.h b/src/core/include/math/hal/bigintntl/ubintntl.h index b072e08c7..26653985e 100644 --- a/src/core/include/math/hal/bigintntl/ubintntl.h +++ b/src/core/include/math/hal/bigintntl/ubintntl.h @@ -1065,7 +1065,7 @@ class myZZ : public NTL::ZZ, public lbcrypto::BigIntegerInterface { return "NTLInteger"; } - static uint32_t SerializedVersion() { + static constexpr uint32_t SerializedVersion() { return 1; } diff --git a/src/core/include/math/hal/intnat/mubintvecnat.h b/src/core/include/math/hal/intnat/mubintvecnat.h index b7fa84ae8..3ba07b599 100644 --- a/src/core/include/math/hal/intnat/mubintvecnat.h +++ b/src/core/include/math/hal/intnat/mubintvecnat.h @@ -707,7 +707,7 @@ class NativeVectorT final : public lbcrypto::BigVectorInterface -class stl_allocator; -template <> -class stl_allocator { -public: - typedef void* pointer; - typedef const void* const_pointer; - // reference to void members are impossible. - typedef void value_type; +#include +#include +#include +#include - template - struct rebind { - typedef stl_allocator other; - }; -}; +#include "xallocator.h" /// @brief stl_allocator is STL-compatible allocator used to provide fixed /// block allocations. @@ -61,114 +50,96 @@ class stl_allocator { template class stl_allocator { public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; + using value_type = T; + using size_type = size_t; + using difference_type = ptrdiff_t; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; /// Constructor - stl_allocator() {} + stl_allocator() noexcept = default; /// Destructor - ~stl_allocator() {} + ~stl_allocator() = default; /// Copy constructor template - stl_allocator(const stl_allocator&) {} + stl_allocator(const stl_allocator&) noexcept {} template struct rebind { - typedef stl_allocator other; + using other = stl_allocator; }; /// Return reference address. /// @return Pointer to T memory. - pointer address(reference x) const { + pointer address(reference x) const noexcept { return &x; } /// Return reference address. /// @return Const pointer to T memory. - const_pointer address(const_reference x) const { + const_pointer address(const_reference x) const noexcept { return &x; } /// Get the maximum size of memory. /// @return Max memory size in bytes. - size_type max_size() const throw() { - return size_t(-1) / sizeof(value_type); + size_type max_size() const noexcept { + return std::numeric_limits::max() / sizeof(value_type); } /// Allocates a fixed block of memory /// @param[in] n - size of memory to allocate in bytes - /// @param[in] hint /// @return Pointer to the allocated memory. - pointer allocate(size_type n, stl_allocator::const_pointer hint = nullptr) { + pointer allocate(size_type n) { return static_cast(xmalloc(n * sizeof(T))); } + /// Allocates a fixed block of memory. + /// @param[in] n - size of memory to allocate in bytes + /// @param[in] hint - placement hint ignored by this allocator + /// @return Pointer to the allocated memory. + pointer allocate(size_type n, const void* hint) { + (void)hint; + return allocate(n); + } + /// Deallocate a previously allocated fixed memory block. /// @param[in] p - pointer to the memory block /// @param[in] n - size of memory in bytes - void deallocate(pointer p, size_type n) { + void deallocate(pointer p, size_type n) noexcept { + (void)n; xfree(p); } /// Constructs a new instance. /// @param[in] p - pointer to the memory where the instance is constructed /// using placement new. - /// @param[in] val - instance of object to copy construct. - void construct(pointer p, const T& val) { - new (static_cast(p)) T(val); - } - - /// Create a new object instance using placement new. - /// @param[in] p - pointer to the memory where the instance is constructed - /// using placement new. - void construct(pointer p) { - new (static_cast(p)) T(); + template + void construct(U* p, Args&&... args) { + new (static_cast(p)) U(std::forward(args)...); } /// Destroys an instance. Objects created with placement new must /// explicitly call the destructor. /// @param[in] p - pointer to object instance. - void destroy(pointer p) { - p->~T(); + template + void destroy(U* p) noexcept { + p->~U(); } }; template -inline bool operator==(const stl_allocator&, const stl_allocator) { +inline bool operator==(const stl_allocator&, const stl_allocator&) { return true; } template -inline bool operator!=(const stl_allocator&, const stl_allocator) { +inline bool operator!=(const stl_allocator&, const stl_allocator&) { return false; } -// For VC6/STLPort 4-5-3 see /stl/_alloc.h, line 464 -// "If custom allocators are being used without member template classes support -// : user (on purpose) is forced to define rebind/get operations !!!" -#ifdef _WIN32 - #define STD_ALLOC_CDECL __cdecl -#else - #define STD_ALLOC_CDECL -#endif - -namespace std { -template -inline stl_allocator<_Tp2>& STD_ALLOC_CDECL __stl_alloc_rebind(stl_allocator<_Tp1>& __a, const _Tp2*) { - return (stl_allocator<_Tp2>&)(__a); -} - -template -inline stl_allocator<_Tp2> STD_ALLOC_CDECL __stl_alloc_create(const stl_allocator<_Tp1>&, const _Tp2*) { - return stl_allocator<_Tp2>(); -} -} // namespace std - #endif diff --git a/src/core/lib/lattice/stdlatticeparms.cpp b/src/core/lib/lattice/stdlatticeparms.cpp index b20a3400a..bfc849338 100644 --- a/src/core/lib/lattice/stdlatticeparms.cpp +++ b/src/core/lib/lattice/stdlatticeparms.cpp @@ -113,152 +113,9 @@ std::ostream& operator<<(std::ostream& s, SecurityLevel sl) { return s; } -std::map StdLatticeParm::byRing[3][6]; -std::map StdLatticeParm::byLogQ[3][6]; +std::map StdLatticeParm::byRing[3][6]; +std::map StdLatticeParm::byLogQ[3][6]; bool StdLatticeParm::initialized = false; -// this is a collection of all of the parameter sets -// the constructor for each one saves and indexes it so that you can search for -// it with static methods in the StdLatticeParm class -std::vector StdLatticeParm::StandardLatticeParmSets({ - StdLatticeParm(HEStd_uniform, 1024, HEStd_128_classic, 29), - StdLatticeParm(HEStd_uniform, 1024, HEStd_192_classic, 21), - StdLatticeParm(HEStd_uniform, 1024, HEStd_256_classic, 16), - StdLatticeParm(HEStd_uniform, 2048, HEStd_128_classic, 56), - StdLatticeParm(HEStd_uniform, 2048, HEStd_192_classic, 39), - StdLatticeParm(HEStd_uniform, 2048, HEStd_256_classic, 31), - StdLatticeParm(HEStd_uniform, 4096, HEStd_128_classic, 111), - StdLatticeParm(HEStd_uniform, 4096, HEStd_192_classic, 77), - StdLatticeParm(HEStd_uniform, 4096, HEStd_256_classic, 60), - StdLatticeParm(HEStd_uniform, 8192, HEStd_128_classic, 220), - StdLatticeParm(HEStd_uniform, 8192, HEStd_192_classic, 154), - StdLatticeParm(HEStd_uniform, 8192, HEStd_256_classic, 120), - StdLatticeParm(HEStd_uniform, 16384, HEStd_128_classic, 440), - StdLatticeParm(HEStd_uniform, 16384, HEStd_192_classic, 307), - StdLatticeParm(HEStd_uniform, 16384, HEStd_256_classic, 239), - StdLatticeParm(HEStd_uniform, 32768, HEStd_128_classic, 880), - StdLatticeParm(HEStd_uniform, 32768, HEStd_192_classic, 612), - StdLatticeParm(HEStd_uniform, 32768, HEStd_256_classic, 478), - - StdLatticeParm(HEStd_error, 1024, HEStd_128_classic, 29), - StdLatticeParm(HEStd_error, 1024, HEStd_192_classic, 21), - StdLatticeParm(HEStd_error, 1024, HEStd_256_classic, 16), - StdLatticeParm(HEStd_error, 2048, HEStd_128_classic, 56), - StdLatticeParm(HEStd_error, 2048, HEStd_192_classic, 39), - StdLatticeParm(HEStd_error, 2048, HEStd_256_classic, 31), - StdLatticeParm(HEStd_error, 4096, HEStd_128_classic, 111), - StdLatticeParm(HEStd_error, 4096, HEStd_192_classic, 77), - StdLatticeParm(HEStd_error, 4096, HEStd_256_classic, 60), - StdLatticeParm(HEStd_error, 8192, HEStd_128_classic, 220), - StdLatticeParm(HEStd_error, 8192, HEStd_192_classic, 154), - StdLatticeParm(HEStd_error, 8192, HEStd_256_classic, 120), - StdLatticeParm(HEStd_error, 16384, HEStd_128_classic, 440), - StdLatticeParm(HEStd_error, 16384, HEStd_192_classic, 307), - StdLatticeParm(HEStd_error, 16384, HEStd_256_classic, 239), - StdLatticeParm(HEStd_error, 32768, HEStd_128_classic, 883), - StdLatticeParm(HEStd_error, 32768, HEStd_192_classic, 613), - StdLatticeParm(HEStd_error, 32768, HEStd_256_classic, 478), - StdLatticeParm(HEStd_error, 65536, HEStd_128_classic, 1749), - StdLatticeParm(HEStd_error, 65536, HEStd_192_classic, 1201), - StdLatticeParm(HEStd_error, 65536, HEStd_256_classic, 931), - StdLatticeParm(HEStd_error, 131072, HEStd_128_classic, 3525), - StdLatticeParm(HEStd_error, 131072, HEStd_192_classic, 2413), - StdLatticeParm(HEStd_error, 131072, HEStd_256_classic, 1868), - - StdLatticeParm(HEStd_ternary, 1024, HEStd_128_classic, 27), - StdLatticeParm(HEStd_ternary, 1024, HEStd_192_classic, 19), - StdLatticeParm(HEStd_ternary, 1024, HEStd_256_classic, 14), - StdLatticeParm(HEStd_ternary, 2048, HEStd_128_classic, 54), - StdLatticeParm(HEStd_ternary, 2048, HEStd_192_classic, 37), - StdLatticeParm(HEStd_ternary, 2048, HEStd_256_classic, 29), - StdLatticeParm(HEStd_ternary, 4096, HEStd_128_classic, 109), - StdLatticeParm(HEStd_ternary, 4096, HEStd_192_classic, 75), - StdLatticeParm(HEStd_ternary, 4096, HEStd_256_classic, 58), - StdLatticeParm(HEStd_ternary, 8192, HEStd_128_classic, 218), - StdLatticeParm(HEStd_ternary, 8192, HEStd_192_classic, 152), - StdLatticeParm(HEStd_ternary, 8192, HEStd_256_classic, 118), - StdLatticeParm(HEStd_ternary, 16384, HEStd_128_classic, 438), - StdLatticeParm(HEStd_ternary, 16384, HEStd_192_classic, 305), - StdLatticeParm(HEStd_ternary, 16384, HEStd_256_classic, 237), - StdLatticeParm(HEStd_ternary, 32768, HEStd_128_classic, 881), - StdLatticeParm(HEStd_ternary, 32768, HEStd_192_classic, 611), - StdLatticeParm(HEStd_ternary, 32768, HEStd_256_classic, 476), - StdLatticeParm(HEStd_ternary, 65536, HEStd_128_classic, 1747), - StdLatticeParm(HEStd_ternary, 65536, HEStd_192_classic, 1199), - StdLatticeParm(HEStd_ternary, 65536, HEStd_256_classic, 929), - StdLatticeParm(HEStd_ternary, 131072, HEStd_128_classic, 3523), - StdLatticeParm(HEStd_ternary, 131072, HEStd_192_classic, 2411), - StdLatticeParm(HEStd_ternary, 131072, HEStd_256_classic, 1866), - - StdLatticeParm(HEStd_uniform, 1024, HEStd_128_quantum, 27), - StdLatticeParm(HEStd_uniform, 1024, HEStd_192_quantum, 19), - StdLatticeParm(HEStd_uniform, 1024, HEStd_256_quantum, 15), - StdLatticeParm(HEStd_uniform, 2048, HEStd_128_quantum, 53), - StdLatticeParm(HEStd_uniform, 2048, HEStd_192_quantum, 37), - StdLatticeParm(HEStd_uniform, 2048, HEStd_256_quantum, 29), - StdLatticeParm(HEStd_uniform, 4096, HEStd_128_quantum, 103), - StdLatticeParm(HEStd_uniform, 4096, HEStd_192_quantum, 72), - StdLatticeParm(HEStd_uniform, 4096, HEStd_256_quantum, 56), - StdLatticeParm(HEStd_uniform, 8192, HEStd_128_quantum, 206), - StdLatticeParm(HEStd_uniform, 8192, HEStd_192_quantum, 143), - StdLatticeParm(HEStd_uniform, 8192, HEStd_256_quantum, 111), - StdLatticeParm(HEStd_uniform, 16384, HEStd_128_quantum, 413), - StdLatticeParm(HEStd_uniform, 16384, HEStd_192_quantum, 286), - StdLatticeParm(HEStd_uniform, 16384, HEStd_256_quantum, 222), - StdLatticeParm(HEStd_uniform, 32768, HEStd_128_quantum, 829), - StdLatticeParm(HEStd_uniform, 32768, HEStd_192_quantum, 573), - StdLatticeParm(HEStd_uniform, 32768, HEStd_256_quantum, 445), - - StdLatticeParm(HEStd_error, 1024, HEStd_128_quantum, 27), - StdLatticeParm(HEStd_error, 1024, HEStd_192_quantum, 19), - StdLatticeParm(HEStd_error, 1024, HEStd_256_quantum, 15), - StdLatticeParm(HEStd_error, 2048, HEStd_128_quantum, 53), - StdLatticeParm(HEStd_error, 2048, HEStd_192_quantum, 37), - StdLatticeParm(HEStd_error, 2048, HEStd_256_quantum, 29), - StdLatticeParm(HEStd_error, 4096, HEStd_128_quantum, 103), - StdLatticeParm(HEStd_error, 4096, HEStd_192_quantum, 72), - StdLatticeParm(HEStd_error, 4096, HEStd_256_quantum, 56), - StdLatticeParm(HEStd_error, 8192, HEStd_128_quantum, 206), - StdLatticeParm(HEStd_error, 8192, HEStd_192_quantum, 143), - StdLatticeParm(HEStd_error, 8192, HEStd_256_quantum, 111), - StdLatticeParm(HEStd_error, 16384, HEStd_128_quantum, 413), - StdLatticeParm(HEStd_error, 16384, HEStd_192_quantum, 286), - StdLatticeParm(HEStd_error, 16384, HEStd_256_quantum, 222), - StdLatticeParm(HEStd_error, 32768, HEStd_128_quantum, 829), - StdLatticeParm(HEStd_error, 32768, HEStd_192_quantum, 573), - StdLatticeParm(HEStd_error, 32768, HEStd_256_quantum, 445), - StdLatticeParm(HEStd_error, 65536, HEStd_128_quantum, 1665), - StdLatticeParm(HEStd_error, 65536, HEStd_192_quantum, 1147), - StdLatticeParm(HEStd_error, 65536, HEStd_256_quantum, 890), - StdLatticeParm(HEStd_error, 131072, HEStd_128_quantum, 3351), - StdLatticeParm(HEStd_error, 131072, HEStd_192_quantum, 2304), - StdLatticeParm(HEStd_error, 131072, HEStd_256_quantum, 1786), - - StdLatticeParm(HEStd_ternary, 1024, HEStd_128_quantum, 25), - StdLatticeParm(HEStd_ternary, 1024, HEStd_192_quantum, 17), - StdLatticeParm(HEStd_ternary, 1024, HEStd_256_quantum, 13), - StdLatticeParm(HEStd_ternary, 2048, HEStd_128_quantum, 51), - StdLatticeParm(HEStd_ternary, 2048, HEStd_192_quantum, 35), - StdLatticeParm(HEStd_ternary, 2048, HEStd_256_quantum, 27), - StdLatticeParm(HEStd_ternary, 4096, HEStd_128_quantum, 101), - StdLatticeParm(HEStd_ternary, 4096, HEStd_192_quantum, 70), - StdLatticeParm(HEStd_ternary, 4096, HEStd_256_quantum, 54), - StdLatticeParm(HEStd_ternary, 8192, HEStd_128_quantum, 202), - StdLatticeParm(HEStd_ternary, 8192, HEStd_192_quantum, 141), - StdLatticeParm(HEStd_ternary, 8192, HEStd_256_quantum, 109), - StdLatticeParm(HEStd_ternary, 16384, HEStd_128_quantum, 411), - StdLatticeParm(HEStd_ternary, 16384, HEStd_192_quantum, 284), - StdLatticeParm(HEStd_ternary, 16384, HEStd_256_quantum, 220), - StdLatticeParm(HEStd_ternary, 32768, HEStd_128_quantum, 827), - StdLatticeParm(HEStd_ternary, 32768, HEStd_192_quantum, 571), - StdLatticeParm(HEStd_ternary, 32768, HEStd_256_quantum, 443), - StdLatticeParm(HEStd_ternary, 65536, HEStd_128_quantum, 1663), - StdLatticeParm(HEStd_ternary, 65536, HEStd_192_quantum, 1145), - StdLatticeParm(HEStd_ternary, 65536, HEStd_256_quantum, 888), - StdLatticeParm(HEStd_ternary, 131072, HEStd_128_quantum, 3348), - StdLatticeParm(HEStd_ternary, 131072, HEStd_192_quantum, 2301), - StdLatticeParm(HEStd_ternary, 131072, HEStd_256_quantum, 1784), -}); - } /* namespace lbcrypto */ diff --git a/src/pke/unittest/UnitTestMultiparty.cpp b/src/pke/unittest/UnitTestMultiparty.cpp index f6c1dc2e7..868ca38a2 100644 --- a/src/pke/unittest/UnitTestMultiparty.cpp +++ b/src/pke/unittest/UnitTestMultiparty.cpp @@ -609,8 +609,8 @@ class UTGENERAL_MULTIPARTY : public ::testing::TestWithParam(FIXEDMANUAL)) ? 1 : 2; + targetTowers = (testData.params.multipartyMode == static_cast(NOISE_FLOODING_MULTIPARTY)) ? 3 : targetTowers; ciphertextMult = cc->Compress(ciphertextMult, targetTowers); } Plaintext plaintextMultipartyMult; diff --git a/src/pke/unittest/utbgvrns/UnitTestBGVrns.cpp b/src/pke/unittest/utbgvrns/UnitTestBGVrns.cpp index 57802d36f..358fb312c 100644 --- a/src/pke/unittest/utbgvrns/UnitTestBGVrns.cpp +++ b/src/pke/unittest/utbgvrns/UnitTestBGVrns.cpp @@ -893,7 +893,7 @@ class UTBGVRNS : public ::testing::TestWithParam { Plaintext result; Plaintext resultCompressed; auto algo = cc->GetScheme(); - size_t targetTowers = (testData.params.scalTech == FLEXIBLEAUTOEXT) ? 2 : 1; + size_t targetTowers = (testData.params.scalTech == static_cast(FLEXIBLEAUTOEXT)) ? 2 : 1; auto ctCompressed = cc->Compress(ct, targetTowers); size_t towersLeft = ctCompressed->GetElements()[0].GetNumOfElements(); diff --git a/src/pke/unittest/utckksrns/UnitTestNoiseFlooding.cpp b/src/pke/unittest/utckksrns/UnitTestNoiseFlooding.cpp index 3e29fc715..1b388189d 100644 --- a/src/pke/unittest/utckksrns/UnitTestNoiseFlooding.cpp +++ b/src/pke/unittest/utckksrns/UnitTestNoiseFlooding.cpp @@ -224,7 +224,7 @@ class UTCKKSRNS_NOISE_FLOODING : public ::testing::TestWithParamDecrypt(keyPair.secretKey, noiseCiphertext, &noisePlaintext); double noise = noisePlaintext->GetLogError(); double expectedNoise = - testData.params.scalTech == FLEXIBLEAUTOEXT ? NOISE_ESTIMATE_FLEX_AUTO_EXT : NOISE_ESTIMATE; + testData.params.scalTech == static_cast(FLEXIBLEAUTOEXT) ? NOISE_ESTIMATE_FLEX_AUTO_EXT : NOISE_ESTIMATE; EXPECT_TRUE(checkEquality(noise, expectedNoise, buffer)) << failmsg + " CKKS Noise estimation fails"; } catch (std::exception& e) { diff --git a/src/pke/unittest/utils/UnitTestCCParams.h b/src/pke/unittest/utils/UnitTestCCParams.h index adf92d812..b7cea2e9c 100644 --- a/src/pke/unittest/utils/UnitTestCCParams.h +++ b/src/pke/unittest/utils/UnitTestCCParams.h @@ -78,7 +78,7 @@ struct UnitTestCCParams { std::ostream& operator<<(std::ostream& os, const UnitTestCCParams& params); //=========================================================================================================== inline bool isDefaultValue(double val) { - return (DFLT == std::round(val)); + return (static_cast(DFLT) == std::round(val)); } //=========================================================================================================== diff --git a/third-party/cereal b/third-party/cereal index 984e3f194..68a87f167 160000 --- a/third-party/cereal +++ b/third-party/cereal @@ -1 +1 @@ -Subproject commit 984e3f194862b17916536b5fade40cba6e47a6fe +Subproject commit 68a87f167f4d1746b01c9eccdba4781eaaa56a6d