diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f63dcf..ddc8351 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,40 +38,60 @@ option(USE_PERF "Use Google Profiler" OFF) option(ENABLE_SHARED "Build as shared libraries" OFF) -set(TFHEpp_DEFINITIONS "" PARENT_SCOPE) +set(TFHEpp_DEFINITIONS + "" + PARENT_SCOPE) if(USE_RANDEN) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_RANDEN" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_RANDEN" + PARENT_SCOPE) add_compile_definitions(USE_RANDEN) endif() if(USE_80BIT_SECURITY) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_80BIT_SECURITY" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_80BIT_SECURITY" + PARENT_SCOPE) add_compile_definitions(USE_80BIT_SECURITY) elseif(USE_COMPRESS) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_COMPRESS" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_COMPRESS" + PARENT_SCOPE) add_compile_definitions(USE_COMPRESS) elseif(USE_CGGI19) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_CGGI19" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_CGGI19" + PARENT_SCOPE) add_compile_definitions(USE_CGGI19) elseif(USE_CONCRETE) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_CONCRETE" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_CONCRETE" + PARENT_SCOPE) add_compile_definitions(USE_CONCRETE) elseif(USE_TFHE_RS) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_TFHE_RS" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_TFHE_RS" + PARENT_SCOPE) add_compile_definitions(USE_TFHE_RS) elseif(USE_TERNARY_CMUX) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_TERNARY_CMUX;USE_TERNARY" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_TERNARY_CMUX;USE_TERNARY" + PARENT_SCOPE) add_compile_definitions(USE_TERNARY) add_compile_definitions(USE_TERNARY_CMUX) elseif(USE_TERNARY) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_TERNARY" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_TERNARY" + PARENT_SCOPE) add_compile_definitions(USE_TERNARY) endif() if(NOT USE_TERNARY) if(USE_KEY_BUNDLE) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_KEY_BUNDLE" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_KEY_BUNDLE" + PARENT_SCOPE) add_compile_definitions(USE_KEY_BUNDLE) endif() endif() @@ -85,11 +105,15 @@ if(USE_AVX512) endif() if(USE_FFTW3) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_FFTW3" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_FFTW3" + PARENT_SCOPE) add_compile_definitions(USE_FFTW3) add_subdirectory(thirdparties/fftw) elseif(USE_SPQLIOX_AARCH64) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_SPQLIOX_AARCH64" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_SPQLIOX_AARCH64" + PARENT_SCOPE) add_compile_definitions(USE_SPQLIOX_AARCH64) add_subdirectory(thirdparties/spqliox_aarch64) # Check if the platform is macOS and the architecture is ARM64 @@ -101,7 +125,9 @@ else() endif() if(USE_HEXL) - set(TFHEpp_DEFINITIONS "${TFHEpp_DEFINITIONS};USE_HEXL" PARENT_SCOPE) + set(TFHEpp_DEFINITIONS + "${TFHEpp_DEFINITIONS};USE_HEXL" + PARENT_SCOPE) add_compile_definitions(USE_HEXL) add_subdirectory(thirdparties/hexl) # set(CMAKE_CXX_FLAGS "-march=native -O3 -g -funroll-loops -Wall -Wextra diff --git a/include/cloudkey.hpp b/include/cloudkey.hpp index 242b605..4a758e6 100644 --- a/include/cloudkey.hpp +++ b/include/cloudkey.hpp @@ -127,7 +127,7 @@ void bkrainttgen(BootstrappingKeyRAINTT

& bkraintt, const Key& domainkey, const Key& targetkey) { - #pragma omp parallel for +#pragma omp parallel for for (int i = 0; i < P::domainP::k * P::domainP::n; i++) { Polynomial plainpoly = {}; plainpoly[0] = domainkey[i]; @@ -378,9 +378,11 @@ struct EvalKey { template void serialize(Archive& archive) { - archive(params, bklvl01, bklvlh1, bklvl02, bklvlh2, bkfftlvl01, bkfftlvlh1, bkfftlvl02, bkfftlvlh2, bknttlvl01, - bknttlvlh1, bknttlvl02, bknttlvlh2, iksklvl10, iksklvl1h, iksklvl20, iksklvl21, iksklvl22, iksklvl31, - privksklvl11, privksklvl21, privksklvl22); + archive(params, bklvl01, bklvlh1, bklvl02, bklvlh2, bkfftlvl01, + bkfftlvlh1, bkfftlvl02, bkfftlvlh2, bknttlvl01, bknttlvlh1, + bknttlvl02, bknttlvlh2, iksklvl10, iksklvl1h, iksklvl20, + iksklvl21, iksklvl22, iksklvl31, privksklvl11, privksklvl21, + privksklvl22); } // emplace keys @@ -505,7 +507,7 @@ struct EvalKey { for (int i = 0; i < lvl01param::domainP::n; i++) (*bknttlvl01)[i] = ApplyNTT2trgsw((*bklvl01)[i][0]); } - else if constexpr (std::is_same_v){ + else if constexpr (std::is_same_v) { bknttlvlh1 = std::make_unique_for_overwrite< BootstrappingKeyNTT>(); for (int i = 0; i < lvlh1param::domainP::n; i++) diff --git a/include/homdecomp.hpp b/include/homdecomp.hpp index 0c12e2e..3e4d8ce 100644 --- a/include/homdecomp.hpp +++ b/include/homdecomp.hpp @@ -7,37 +7,47 @@ #include "gatebootstrapping.hpp" namespace TFHEpp { - /*! - * @brief Generates a Polynomial with each coefficient subtracted by a base value - * @tparam P The parameter set for the Polynomial - * @tparam basebit The base to be subtracted - * @return A Polynomial of the parameter type with coefficients subtracted by the base value - */ - template constexpr Polynomial

subtractpolygen() { +/*! + * @brief Generates a Polynomial with each coefficient subtracted by a base + * value + * @tparam P The parameter set for the Polynomial + * @tparam basebit The base to be subtracted + * @return A Polynomial of the parameter type with coefficients subtracted by + * the base value + */ +template +constexpr Polynomial

subtractpolygen() +{ Polynomial

poly; for (int i = 0; i < P::n; i++) - poly[i] = 1ULL << (std::numeric_limits::digits - basebit - 2); + poly[i] = + 1ULL << (std::numeric_limits::digits - basebit - 2); return poly; - } +} - // https://eprint.iacr.org/2023/645 - /*! - * @brief Homomorphically decomposes an input ciphertext into an array of level 1 ciphertexts - * @tparam high2midP The parameter set for the transition from high to mid level - * @tparam mid2lowP The parameter set for the transition from mid to low level - * @tparam brP The bootstrapping parameter set - * @tparam basebit The base value - * @tparam numdigit The number of digits - * @param cres Array of output ciphertexts - * @param cin Input ciphertext - * @param kskh2m The key switching key for high to mid level - * @param kskm2l The key switching key for mid to low level - * @param bkfft The bootstrapping key FFT - */ - template - void HomDecomp(std::array, numdigit> &cres, - const TLWE &cin, const KeySwitchingKey &kskh2m, - const KeySwitchingKey &kskm2l, const BootstrappingKeyFFT &bkfft) { +// https://eprint.iacr.org/2023/645 +/*! + * @brief Homomorphically decomposes an input ciphertext into an array of level + * 1 ciphertexts + * @tparam high2midP The parameter set for the transition from high to mid level + * @tparam mid2lowP The parameter set for the transition from mid to low level + * @tparam brP The bootstrapping parameter set + * @tparam basebit The base value + * @tparam numdigit The number of digits + * @param cres Array of output ciphertexts + * @param cin Input ciphertext + * @param kskh2m The key switching key for high to mid level + * @param kskm2l The key switching key for mid to low level + * @param bkfft The bootstrapping key FFT + */ +template +void HomDecomp(std::array, numdigit> &cres, + const TLWE &cin, + const KeySwitchingKey &kskh2m, + const KeySwitchingKey &kskm2l, + const BootstrappingKeyFFT &bkfft) +{ TFHEpp::TLWE tlwelvlhalf; TFHEpp::TLWE subtlwe; @@ -45,25 +55,31 @@ namespace TFHEpp { constexpr uint32_t plain_modulusbit = basebit * numdigit; #pragma omp parallel for default(none) shared(cin, cres, kskh2m) for (int digit = 1; digit <= numdigit; digit++) { - TFHEpp::TLWE switchedtlwe; - for (int i = 0; i <= high2midP::domainP::k * high2midP::domainP::n; i++) - switchedtlwe[i] = cin[i] << (plain_modulusbit - basebit * digit); - IdentityKeySwitch(cres[digit - 1], switchedtlwe, kskh2m); + TFHEpp::TLWE switchedtlwe; + for (int i = 0; i <= high2midP::domainP::k * high2midP::domainP::n; i++) + switchedtlwe[i] = cin[i] << (plain_modulusbit - basebit * digit); + IdentityKeySwitch(cres[digit - 1], switchedtlwe, kskh2m); } for (int digit = 1; digit <= numdigit; digit++) { - if (digit != 1) { - for (int i = 0; i <= high2midP::targetP::k * high2midP::targetP::n; i++) - cres[digit - 1][i] += subtlwe[i]; - cres[digit - 1][high2midP::targetP::k * high2midP::targetP::n] -= - 1ULL << (std::numeric_limits::digits - basebit - 1); - } - IdentityKeySwitch(tlwelvlhalf, cres[digit - 1], kskm2l); - tlwelvlhalf[mid2lowP::targetP::k * mid2lowP::targetP::n] += - 1ULL << (std::numeric_limits::digits - basebit - 1); - if (digit != numdigit) - GateBootstrappingTLWE2TLWEFFT(subtlwe, tlwelvlhalf, bkfft, - subtractpolygen()); + if (digit != 1) { + for (int i = 0; i <= high2midP::targetP::k * high2midP::targetP::n; + i++) + cres[digit - 1][i] += subtlwe[i]; + cres[digit - 1][high2midP::targetP::k * high2midP::targetP::n] -= + 1ULL << (std::numeric_limits< + typename high2midP::targetP::T>::digits - + basebit - 1); + } + IdentityKeySwitch(tlwelvlhalf, cres[digit - 1], kskm2l); + tlwelvlhalf[mid2lowP::targetP::k * mid2lowP::targetP::n] += + 1ULL + << (std::numeric_limits::digits - + basebit - 1); + if (digit != numdigit) + GateBootstrappingTLWE2TLWEFFT( + subtlwe, tlwelvlhalf, bkfft, + subtractpolygen()); } - } +} -} // namespace TFHEpp \ No newline at end of file +} // namespace TFHEpp \ No newline at end of file diff --git a/include/params/128bit.hpp b/include/params/128bit.hpp index 3346d8e..2a7d97a 100644 --- a/include/params/128bit.hpp +++ b/include/params/128bit.hpp @@ -14,7 +14,8 @@ struct lvl0param { ErrorDistribution::ModularGaussian; static const inline double α = 0.000'092'511'997'467'675'6; // fresh noise using T = uint16_t; // Torus representation - static constexpr std::make_signed_t μ = 1LL << (std::numeric_limits::digits - 3); + static constexpr std::make_signed_t μ = + 1LL << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / @@ -25,15 +26,17 @@ struct lvlhalfparam { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = 0; static constexpr int32_t key_value_diff = key_value_max - key_value_min; - static constexpr std::uint32_t n = 760; // dimension + static constexpr std::uint32_t n = 760; // dimension static constexpr std::uint32_t k = 1; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -17); // fresh noise - using T = uint32_t; // Torus representation + static const inline double α = std::pow(2.0, -17); // fresh noise + using T = uint32_t; // Torus representation static constexpr T μ = 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; - static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; + static constexpr double Δ = + static_cast(1ULL << std::numeric_limits::digits) / + plain_modulus; }; struct lvl1param { @@ -81,17 +84,17 @@ struct lvl2param { struct lvl3param { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = -1; - static const std::uint32_t nbit = 13; // dimension must be a power of 2 for + static const std::uint32_t nbit = 13; // dimension must be a power of 2 for // ease of polynomial multiplication. - static constexpr std::uint32_t n = 1 << nbit; // dimension + static constexpr std::uint32_t n = 1 << nbit; // dimension static constexpr std::uint32_t k = 1; static constexpr std::uint32_t l = 4; static constexpr std::uint32_t Bgbit = 9; static constexpr std::uint32_t Bg = 1 << Bgbit; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -47); // fresh noise - using T = uint64_t; // Torus representation + static const inline double α = std::pow(2.0, -47); // fresh noise + using T = uint64_t; // Torus representation static constexpr T μ = 1ULL << 61; static constexpr uint32_t plain_modulusbit = 31; static constexpr uint64_t plain_modulus = 1ULL << plain_modulusbit; @@ -111,9 +114,11 @@ struct lvl10param { }; struct lvl1hparam { - static constexpr std::uint32_t t = 10; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 3; // how many bit should be encrypted in keyswitching key - static const inline double α = lvlhalfparam::α; // key noise + static constexpr std::uint32_t t = + 10; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 3; // how many bit should be encrypted in keyswitching key + static const inline double α = lvlhalfparam::α; // key noise using domainP = lvl1param; using targetP = lvlhalfparam; }; @@ -165,9 +170,10 @@ struct lvl22param { }; struct lvl31param { - static constexpr std::uint32_t t = 7; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 2; // how many bit should be encrypted in keyswitching key - static const inline double α = lvl1param::α; // key noise + static constexpr std::uint32_t t = 7; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 2; // how many bit should be encrypted in keyswitching key + static const inline double α = lvl1param::α; // key noise using domainP = lvl3param; using targetP = lvl1param; }; \ No newline at end of file diff --git a/include/params/CGGI16.hpp b/include/params/CGGI16.hpp index 8c1bffa..7c9a578 100644 --- a/include/params/CGGI16.hpp +++ b/include/params/CGGI16.hpp @@ -20,20 +20,22 @@ struct lvl0param { plain_modulus; }; -//Dummy +// Dummy struct lvlhalfparam { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = 0; static constexpr int32_t key_value_diff = key_value_max - key_value_min; - static constexpr std::uint32_t n = 760; // dimension + static constexpr std::uint32_t n = 760; // dimension static constexpr std::uint32_t k = 1; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -17); // fresh noise - using T = uint32_t; // Torus representation + static const inline double α = std::pow(2.0, -17); // fresh noise + using T = uint32_t; // Torus representation static constexpr T μ = 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; - static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; + static constexpr double Δ = + static_cast(1ULL << std::numeric_limits::digits) / + plain_modulus; }; struct lvl1param { @@ -74,21 +76,21 @@ struct lvl2param { static constexpr double Δ = μ; }; -//Dummy +// Dummy struct lvl3param { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = -1; - static const std::uint32_t nbit = 13; // dimension must be a power of 2 for + static const std::uint32_t nbit = 13; // dimension must be a power of 2 for // ease of polynomial multiplication. - static constexpr std::uint32_t n = 1 << nbit; // dimension + static constexpr std::uint32_t n = 1 << nbit; // dimension static constexpr std::uint32_t k = 1; static constexpr std::uint32_t l = 4; static constexpr std::uint32_t Bgbit = 9; static constexpr std::uint32_t Bg = 1 << Bgbit; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -47); // fresh noise - using T = uint64_t; // Torus representation + static const inline double α = std::pow(2.0, -47); // fresh noise + using T = uint64_t; // Torus representation static constexpr T μ = 1ULL << 61; static constexpr uint32_t plain_modulusbit = 31; static constexpr uint64_t plain_modulus = 1ULL << plain_modulusbit; @@ -105,11 +107,13 @@ struct lvl10param { using targetP = lvl0param; }; -//Dummy +// Dummy struct lvl1hparam { - static constexpr std::uint32_t t = 10; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 3; // how many bit should be encrypted in keyswitching key - static const inline double α = lvlhalfparam::α; // key noise + static constexpr std::uint32_t t = + 10; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 3; // how many bit should be encrypted in keyswitching key + static const inline double α = lvlhalfparam::α; // key noise using domainP = lvl1param; using targetP = lvlhalfparam; }; @@ -160,9 +164,10 @@ struct lvl22param { }; struct lvl31param { - static constexpr std::uint32_t t = 7; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 2; // how many bit should be encrypted in keyswitching key - static const inline double α = lvl1param::α; // key noise + static constexpr std::uint32_t t = 7; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 2; // how many bit should be encrypted in keyswitching key + static const inline double α = lvl1param::α; // key noise using domainP = lvl3param; using targetP = lvl1param; }; \ No newline at end of file diff --git a/include/params/CGGI19.hpp b/include/params/CGGI19.hpp index 56ccdee..6a3bf4b 100644 --- a/include/params/CGGI19.hpp +++ b/include/params/CGGI19.hpp @@ -22,20 +22,22 @@ struct lvl0param { plain_modulus; }; -//Dummy +// Dummy struct lvlhalfparam { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = 0; static constexpr int32_t key_value_diff = key_value_max - key_value_min; - static constexpr std::uint32_t n = 760; // dimension + static constexpr std::uint32_t n = 760; // dimension static constexpr std::uint32_t k = 1; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -17); // fresh noise - using T = uint32_t; // Torus representation + static const inline double α = std::pow(2.0, -17); // fresh noise + using T = uint32_t; // Torus representation static constexpr T μ = 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; - static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; + static constexpr double Δ = + static_cast(1ULL << std::numeric_limits::digits) / + plain_modulus; }; struct lvl1param { @@ -76,21 +78,21 @@ struct lvl2param { static constexpr double Δ = μ; }; -//Dummy +// Dummy struct lvl3param { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = -1; - static const std::uint32_t nbit = 13; // dimension must be a power of 2 for + static const std::uint32_t nbit = 13; // dimension must be a power of 2 for // ease of polynomial multiplication. - static constexpr std::uint32_t n = 1 << nbit; // dimension + static constexpr std::uint32_t n = 1 << nbit; // dimension static constexpr std::uint32_t k = 1; static constexpr std::uint32_t l = 4; static constexpr std::uint32_t Bgbit = 9; static constexpr std::uint32_t Bg = 1 << Bgbit; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -47); // fresh noise - using T = uint64_t; // Torus representation + static const inline double α = std::pow(2.0, -47); // fresh noise + using T = uint64_t; // Torus representation static constexpr T μ = 1ULL << 61; static constexpr uint32_t plain_modulusbit = 31; static constexpr uint64_t plain_modulus = 1ULL << plain_modulusbit; @@ -119,11 +121,13 @@ struct lvl10param { using targetP = lvl0param; }; -//Dummy +// Dummy struct lvl1hparam { - static constexpr std::uint32_t t = 10; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 3; // how many bit should be encrypted in keyswitching key - static const inline double α = lvlhalfparam::α; // key noise + static constexpr std::uint32_t t = + 10; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 3; // how many bit should be encrypted in keyswitching key + static const inline double α = lvlhalfparam::α; // key noise using domainP = lvl1param; using targetP = lvlhalfparam; }; @@ -161,11 +165,12 @@ struct lvl22param { using targetP = lvl2param; }; -//Dummy +// Dummy struct lvl31param { - static constexpr std::uint32_t t = 7; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 2; // how many bit should be encrypted in keyswitching key - static const inline double α = lvl1param::α; // key noise + static constexpr std::uint32_t t = 7; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 2; // how many bit should be encrypted in keyswitching key + static const inline double α = lvl1param::α; // key noise using domainP = lvl3param; using targetP = lvl1param; }; \ No newline at end of file diff --git a/include/params/compress.hpp b/include/params/compress.hpp index f6979b0..419aeb5 100644 --- a/include/params/compress.hpp +++ b/include/params/compress.hpp @@ -17,27 +17,30 @@ struct lvl0param { static constexpr inline double α = 0.000'092'511'997'467'675'6; // fresh noise, 2^{-13.4} using T = uint32_t; // Torus representation - static constexpr std::make_signed_t μ = 1U << (std::numeric_limits::digits - 3); + static constexpr std::make_signed_t μ = + 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; }; -//Dummy +// Dummy struct lvlhalfparam { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = 0; static constexpr int32_t key_value_diff = key_value_max - key_value_min; - static constexpr std::uint32_t n = 760; // dimension + static constexpr std::uint32_t n = 760; // dimension static constexpr std::uint32_t k = 1; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -17); // fresh noise - using T = uint32_t; // Torus representation + static const inline double α = std::pow(2.0, -17); // fresh noise + using T = uint32_t; // Torus representation static constexpr T μ = 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; - static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; + static constexpr double Δ = + static_cast(1ULL << std::numeric_limits::digits) / + plain_modulus; }; struct lvl1param { @@ -57,7 +60,8 @@ struct lvl1param { using T = uint32_t; // Torus representation static constexpr T q = 40960001; static constexpr uint qbit = 27; - static constexpr std::make_signed_t μ = 1U << (std::numeric_limits::digits - 3); + static constexpr std::make_signed_t μ = + 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 2; static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / @@ -85,22 +89,21 @@ struct lvl2param { static constexpr double Δ = μ; }; - -//Dummy +// Dummy struct lvl3param { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = -1; - static const std::uint32_t nbit = 13; // dimension must be a power of 2 for + static const std::uint32_t nbit = 13; // dimension must be a power of 2 for // ease of polynomial multiplication. - static constexpr std::uint32_t n = 1 << nbit; // dimension + static constexpr std::uint32_t n = 1 << nbit; // dimension static constexpr std::uint32_t k = 1; static constexpr std::uint32_t l = 4; static constexpr std::uint32_t Bgbit = 9; static constexpr std::uint32_t Bg = 1 << Bgbit; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -47); // fresh noise - using T = uint64_t; // Torus representation + static const inline double α = std::pow(2.0, -47); // fresh noise + using T = uint64_t; // Torus representation static constexpr T μ = 1ULL << 61; static constexpr uint32_t plain_modulusbit = 31; static constexpr uint64_t plain_modulus = 1ULL << plain_modulusbit; @@ -116,11 +119,13 @@ struct lvl10param { using targetP = lvl0param; }; -//Dummy +// Dummy struct lvl1hparam { - static constexpr std::uint32_t t = 10; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 3; // how many bit should be encrypted in keyswitching key - static const inline double α = lvlhalfparam::α; // key noise + static constexpr std::uint32_t t = + 10; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 3; // how many bit should be encrypted in keyswitching key + static const inline double α = lvlhalfparam::α; // key noise using domainP = lvl1param; using targetP = lvlhalfparam; }; @@ -159,11 +164,12 @@ struct lvl22param { using targetP = lvl2param; }; -//Dummy +// Dummy struct lvl31param { - static constexpr std::uint32_t t = 7; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 2; // how many bit should be encrypted in keyswitching key - static const inline double α = lvl1param::α; // key noise + static constexpr std::uint32_t t = 7; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 2; // how many bit should be encrypted in keyswitching key + static const inline double α = lvl1param::α; // key noise using domainP = lvl3param; using targetP = lvl1param; }; \ No newline at end of file diff --git a/include/params/concrete.hpp b/include/params/concrete.hpp index 95654a7..34aadb4 100644 --- a/include/params/concrete.hpp +++ b/include/params/concrete.hpp @@ -19,27 +19,30 @@ struct lvl0param { static constexpr inline double α = 0.000'092'511'997'467'675'6; // fresh noise, 2^{-13.4} using T = uint16_t; // Torus representation - static constexpr std::make_signed_t μ = 1 << (std::numeric_limits::digits - 3); + static constexpr std::make_signed_t μ = + 1 << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; }; -//Dummy +// Dummy struct lvlhalfparam { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = 0; static constexpr int32_t key_value_diff = key_value_max - key_value_min; - static constexpr std::uint32_t n = 760; // dimension + static constexpr std::uint32_t n = 760; // dimension static constexpr std::uint32_t k = 1; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -17); // fresh noise - using T = uint32_t; // Torus representation + static const inline double α = std::pow(2.0, -17); // fresh noise + using T = uint32_t; // Torus representation static constexpr T μ = 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; - static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; + static constexpr double Δ = + static_cast(1ULL << std::numeric_limits::digits) / + plain_modulus; }; struct lvl1param { @@ -84,21 +87,20 @@ struct lvl2param { static constexpr double Δ = μ; }; - struct lvl3param { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = -1; - static const std::uint32_t nbit = 13; // dimension must be a power of 2 for + static const std::uint32_t nbit = 13; // dimension must be a power of 2 for // ease of polynomial multiplication. - static constexpr std::uint32_t n = 1 << nbit; // dimension + static constexpr std::uint32_t n = 1 << nbit; // dimension static constexpr std::uint32_t k = 1; static constexpr std::uint32_t l = 4; static constexpr std::uint32_t Bgbit = 9; static constexpr std::uint32_t Bg = 1 << Bgbit; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -47); // fresh noise - using T = uint64_t; // Torus representation + static const inline double α = std::pow(2.0, -47); // fresh noise + using T = uint64_t; // Torus representation static constexpr T μ = 1ULL << 61; static constexpr uint32_t plain_modulusbit = 31; static constexpr uint64_t plain_modulus = 1ULL << plain_modulusbit; @@ -117,11 +119,13 @@ struct lvl10param { using targetP = lvl0param; }; -//Dummy +// Dummy struct lvl1hparam { - static constexpr std::uint32_t t = 10; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 3; // how many bit should be encrypted in keyswitching key - static const inline double α = lvlhalfparam::α; // key noise + static constexpr std::uint32_t t = + 10; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 3; // how many bit should be encrypted in keyswitching key + static const inline double α = lvlhalfparam::α; // key noise using domainP = lvl1param; using targetP = lvlhalfparam; }; @@ -172,11 +176,12 @@ struct lvl22param { using targetP = lvl2param; }; -//Dummy +// Dummy struct lvl31param { - static constexpr std::uint32_t t = 7; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 2; // how many bit should be encrypted in keyswitching key - static const inline double α = lvl1param::α; // key noise + static constexpr std::uint32_t t = 7; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 2; // how many bit should be encrypted in keyswitching key + static const inline double α = lvl1param::α; // key noise using domainP = lvl3param; using targetP = lvl1param; }; \ No newline at end of file diff --git a/include/params/ternary.hpp b/include/params/ternary.hpp index 50a66c4..ff1734e 100644 --- a/include/params/ternary.hpp +++ b/include/params/ternary.hpp @@ -14,27 +14,30 @@ struct lvl0param { ErrorDistribution::ModularGaussian; static const inline double α = std::pow(2.0, -15); // fresh noise using T = uint32_t; // Torus representation - static constexpr std::make_signed_t μ = 1 << (std::numeric_limits::digits - 3); + static constexpr std::make_signed_t μ = + 1 << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 2; static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; }; -//Dummy +// Dummy struct lvlhalfparam { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = 0; static constexpr int32_t key_value_diff = key_value_max - key_value_min; - static constexpr std::uint32_t n = 760; // dimension + static constexpr std::uint32_t n = 760; // dimension static constexpr std::uint32_t k = 1; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -17); // fresh noise - using T = uint32_t; // Torus representation + static const inline double α = std::pow(2.0, -17); // fresh noise + using T = uint32_t; // Torus representation static constexpr T μ = 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; - static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; + static constexpr double Δ = + static_cast(1ULL << std::numeric_limits::digits) / + plain_modulus; }; struct lvl1param { @@ -78,21 +81,20 @@ struct lvl2param { static constexpr double Δ = μ; }; - struct lvl3param { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = -1; - static const std::uint32_t nbit = 13; // dimension must be a power of 2 for + static const std::uint32_t nbit = 13; // dimension must be a power of 2 for // ease of polynomial multiplication. - static constexpr std::uint32_t n = 1 << nbit; // dimension + static constexpr std::uint32_t n = 1 << nbit; // dimension static constexpr std::uint32_t k = 1; static constexpr std::uint32_t l = 4; static constexpr std::uint32_t Bgbit = 9; static constexpr std::uint32_t Bg = 1 << Bgbit; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -47); // fresh noise - using T = uint64_t; // Torus representation + static const inline double α = std::pow(2.0, -47); // fresh noise + using T = uint64_t; // Torus representation static constexpr T μ = 1ULL << 61; static constexpr uint32_t plain_modulusbit = 31; static constexpr uint64_t plain_modulus = 1ULL << plain_modulusbit; @@ -111,11 +113,13 @@ struct lvl10param { using targetP = lvl0param; }; -//Dummy +// Dummy struct lvl1hparam { - static constexpr std::uint32_t t = 10; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 3; // how many bit should be encrypted in keyswitching key - static const inline double α = lvlhalfparam::α; // key noise + static constexpr std::uint32_t t = + 10; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 3; // how many bit should be encrypted in keyswitching key + static const inline double α = lvlhalfparam::α; // key noise using domainP = lvl1param; using targetP = lvlhalfparam; }; @@ -165,11 +169,12 @@ struct lvl22param { using targetP = lvl2param; }; -//Dummy +// Dummy struct lvl31param { - static constexpr std::uint32_t t = 7; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 2; // how many bit should be encrypted in keyswitching key - static const inline double α = lvl1param::α; // key noise + static constexpr std::uint32_t t = 7; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 2; // how many bit should be encrypted in keyswitching key + static const inline double α = lvl1param::α; // key noise using domainP = lvl3param; using targetP = lvl1param; }; \ No newline at end of file diff --git a/include/params/tfhe-rs.hpp b/include/params/tfhe-rs.hpp index 20788fe..ca46e06 100644 --- a/include/params/tfhe-rs.hpp +++ b/include/params/tfhe-rs.hpp @@ -26,20 +26,22 @@ struct lvl0param { plain_modulus; }; -//Dummy +// Dummy struct lvlhalfparam { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = 0; static constexpr int32_t key_value_diff = key_value_max - key_value_min; - static constexpr std::uint32_t n = 760; // dimension + static constexpr std::uint32_t n = 760; // dimension static constexpr std::uint32_t k = 1; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -17); // fresh noise - using T = uint32_t; // Torus representation + static const inline double α = std::pow(2.0, -17); // fresh noise + using T = uint32_t; // Torus representation static constexpr T μ = 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; - static constexpr double Δ = static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; + static constexpr double Δ = + static_cast(1ULL << std::numeric_limits::digits) / + plain_modulus; }; struct lvl1param { @@ -84,22 +86,21 @@ struct lvl2param { static constexpr double Δ = μ; }; - -//Dummy +// Dummy struct lvl3param { static constexpr int32_t key_value_max = 1; static constexpr int32_t key_value_min = -1; - static const std::uint32_t nbit = 13; // dimension must be a power of 2 for + static const std::uint32_t nbit = 13; // dimension must be a power of 2 for // ease of polynomial multiplication. - static constexpr std::uint32_t n = 1 << nbit; // dimension + static constexpr std::uint32_t n = 1 << nbit; // dimension static constexpr std::uint32_t k = 1; static constexpr std::uint32_t l = 4; static constexpr std::uint32_t Bgbit = 9; static constexpr std::uint32_t Bg = 1 << Bgbit; static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; - static const inline double α = std::pow(2.0, -47); // fresh noise - using T = uint64_t; // Torus representation + static const inline double α = std::pow(2.0, -47); // fresh noise + using T = uint64_t; // Torus representation static constexpr T μ = 1ULL << 61; static constexpr uint32_t plain_modulusbit = 31; static constexpr uint64_t plain_modulus = 1ULL << plain_modulusbit; @@ -118,11 +119,13 @@ struct lvl10param { using targetP = lvl0param; }; -//Dummy +// Dummy struct lvl1hparam { - static constexpr std::uint32_t t = 10; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 3; // how many bit should be encrypted in keyswitching key - static const inline double α = lvlhalfparam::α; // key noise + static constexpr std::uint32_t t = + 10; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 3; // how many bit should be encrypted in keyswitching key + static const inline double α = lvlhalfparam::α; // key noise using domainP = lvl1param; using targetP = lvlhalfparam; }; @@ -172,11 +175,12 @@ struct lvl22param { using targetP = lvl2param; }; -//Dummy +// Dummy struct lvl31param { - static constexpr std::uint32_t t = 7; // number of addition in keyswitching - static constexpr std::uint32_t basebit = 2; // how many bit should be encrypted in keyswitching key - static const inline double α = lvl1param::α; // key noise + static constexpr std::uint32_t t = 7; // number of addition in keyswitching + static constexpr std::uint32_t basebit = + 2; // how many bit should be encrypted in keyswitching key + static const inline double α = lvl1param::α; // key noise using domainP = lvl3param; using targetP = lvl1param; }; \ No newline at end of file diff --git a/include/tfhe++.hpp b/include/tfhe++.hpp index 4c4c55f..7a23e79 100644 --- a/include/tfhe++.hpp +++ b/include/tfhe++.hpp @@ -13,6 +13,7 @@ #include "externs/trlwe.hpp" #include "gate.hpp" #include "gatebootstrapping.hpp" +#include "homdecomp.hpp" #include "io-packet.hpp" #include "key.hpp" #include "keyswitch.hpp" @@ -20,7 +21,6 @@ #include "tlwe.hpp" #include "trgsw.hpp" #include "trlwe.hpp" -#include "homdecomp.hpp" #ifndef __clang__ // Because of some resons (may be clang bug?) this will gives linking error diff --git a/include/tlwe.hpp b/include/tlwe.hpp index 0ea813f..a353208 100644 --- a/include/tlwe.hpp +++ b/include/tlwe.hpp @@ -96,16 +96,20 @@ bool tlweSymDecrypt(const TLWE

&c, const Key

&key) template typename P::T tlweSymIntDecrypt(const TLWE

&c, const Key

&key) { - constexpr double Δ = 2* static_cast(1ULL << (std::numeric_limits::digits - 1))/plain_modulus; + constexpr double Δ = + 2 * + static_cast( + 1ULL << (std::numeric_limits::digits - 1)) / + plain_modulus; const typename P::T phase = tlweSymPhase

(c, key); typename P::T res = static_cast(std::round(phase / Δ)); - return res >= plain_modulus/2 ? res - plain_modulus : res; + return res >= plain_modulus / 2 ? res - plain_modulus : res; } template typename P::T tlweSymIntDecrypt(const TLWE

&c, const Key

&key) { - return tlweSymIntDecrypt(c, key); + return tlweSymIntDecrypt(c, key); } template @@ -113,7 +117,7 @@ std::vector> bootsSymEncrypt(const std::vector &p, const Key

&key) { vector> c(p.size()); - #pragma omp parallel for +#pragma omp parallel for for (int i = 0; i < p.size(); i++) c[i] = tlweSymEncrypt

(p[i] ? P::μ : -P::μ, key); return c; @@ -131,7 +135,7 @@ std::vector bootsSymDecrypt(const std::vector> &c, const Key

&key) { vector p(c.size()); - #pragma omp parallel for +#pragma omp parallel for for (int i = 0; i < c.size(); i++) p[i] = tlweSymDecrypt

(c[i], key); return p; } diff --git a/src/key.cpp b/src/key.cpp index f817ded..decd903 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -6,8 +6,8 @@ lweKey::lweKey() { std::uniform_int_distribution lvl0gen(lvl0param::key_value_min, lvl0param::key_value_max); - std::uniform_int_distribution lvlhalfgen(lvlhalfparam::key_value_min, - lvlhalfparam::key_value_max); + std::uniform_int_distribution lvlhalfgen( + lvlhalfparam::key_value_min, lvlhalfparam::key_value_max); std::uniform_int_distribution lvl1gen(lvl1param::key_value_min, lvl1param::key_value_max); std::uniform_int_distribution lvl2gen(lvl2param::key_value_min, diff --git a/test/homdecomp.cpp b/test/homdecomp.cpp index 7c50858..b513f43 100644 --- a/test/homdecomp.cpp +++ b/test/homdecomp.cpp @@ -15,54 +15,62 @@ int main() using low2midP = TFHEpp::lvlh1param; constexpr auto numtest = 10; constexpr uint basebit = 4; - constexpr uint64_t numdigits = 64/4; + constexpr uint64_t numdigits = 64 / 4; TFHEpp::SecretKey sk; TFHEpp::EvalKey ek; - std::uniform_int_distribution lvl3gen(TFHEpp::lvl3param::key_value_min, - TFHEpp::lvl3param::key_value_max); - for (typename TFHEpp::lvl3param::T &i : sk.key.lvl3) i = lvl3gen(TFHEpp::generator); + std::uniform_int_distribution lvl3gen( + TFHEpp::lvl3param::key_value_min, TFHEpp::lvl3param::key_value_max); + for (typename TFHEpp::lvl3param::T &i : sk.key.lvl3) + i = lvl3gen(TFHEpp::generator); ek.emplacebkfft(sk); ek.emplaceiksk(sk); ek.emplaceiksk(sk); // Test input - std::uniform_int_distribution messagegen(0, - 2 * TFHEpp::lvl3param::plain_modulus - 1); - std::uniform_int_distribution maskgen(0, - std::numeric_limits::max()); + std::uniform_int_distribution messagegen( + 0, 2 * TFHEpp::lvl3param::plain_modulus - 1); + std::uniform_int_distribution maskgen( + 0, std::numeric_limits::max()); std::array plains{}; - for (typename TFHEpp::lvl3param::T &i: plains) { - i = messagegen(engine); + for (typename TFHEpp::lvl3param::T &i : plains) { + i = messagegen(engine); } std::array, numtest> ciphers{}; for (uint i = 0; i < numtest; i++) { - ciphers[i] = TFHEpp::tlweSymIntEncrypt(plains[i], TFHEpp::lvl3param::α, sk.key.lvl3); - ciphers[i][TFHEpp::lvl3param::n] += maskgen(engine); + ciphers[i] = TFHEpp::tlweSymIntEncrypt( + plains[i], TFHEpp::lvl3param::α, sk.key.lvl3); + ciphers[i][TFHEpp::lvl3param::n] += maskgen(engine); } // Test output - std::array, numdigits>, numtest> + std::array, numdigits>, + numtest> result_multiple{}; // Convert TLWE for (uint i = 0; i < numtest; i++) { - // converter.toLv1TLWE(ciphers.at(i), result_multiple.at(i)); - TFHEpp::HomDecomp(result_multiple.at(i), ciphers.at(i), ek.getiksk(), ek.getiksk(), ek.getbkfft()); + // converter.toLv1TLWE(ciphers.at(i), result_multiple.at(i)); + TFHEpp::HomDecomp( + result_multiple.at(i), ciphers.at(i), ek.getiksk(), + ek.getiksk(), ek.getbkfft()); } // Check the correctness of the results for (uint test = 0; test < numtest; test++) { - uint64_t phase = TFHEpp::tlweSymPhase( - ciphers.at(test), sk.key.lvl3); - for (uint digit = 0; digit < numdigits; digit++) { - int plainResult = TFHEpp::tlweSymIntDecrypt( - result_multiple[test][digit], sk.key.get()); - const uint64_t plainExpected = ((phase >> (basebit * digit)) & ((1ULL << basebit) - 1)); - plainResult = (plainResult + (1U<( + ciphers.at(test), sk.key.lvl3); + for (uint digit = 0; digit < numdigits; digit++) { + int plainResult = + TFHEpp::tlweSymIntDecrypt( + result_multiple[test][digit], + sk.key.get()); + const uint64_t plainExpected = + ((phase >> (basebit * digit)) & ((1ULL << basebit) - 1)); + plainResult = (plainResult + (1U << basebit)) % (1U << basebit); + assert(plainExpected == plainResult); + } } - std::cout<<"PASS"<(res, skey.key.lvl1)); + dump_histgram_of_phase_of_TRLWELvl1( + std::cout, TFHEpp::trlwePhase(res, skey.key.lvl1)); for (size_t i = 0; i < N; i++) { TRLWELvl1 tmp = res; TFHEpp::CMUXFFT(res, guard.at(i), tmp, c0); } - dump_histgram_of_phase_of_TRLWELvl1(std::cout, - TFHEpp::trlwePhase(res, skey.key.lvl1)); + dump_histgram_of_phase_of_TRLWELvl1( + std::cout, TFHEpp::trlwePhase(res, skey.key.lvl1)); /* PolyLvl1 testvec1 = {}, testvec2 = {}; diff --git a/test/nested_cmux_from_cb.cpp b/test/nested_cmux_from_cb.cpp index 1e0e95a..5768ff7 100644 --- a/test/nested_cmux_from_cb.cpp +++ b/test/nested_cmux_from_cb.cpp @@ -66,14 +66,14 @@ int main() TRLWELvl1 c1 = trivial_TRLWELvl1(uint2weight(1)), c0 = trivial_TRLWELvl1(uint2weight(0)); TRLWELvl1 res = c1; - dump_histgram_of_phase_of_TRLWELvl1(std::cout, - TFHEpp::trlwePhase(res, skey.key.lvl1)); + dump_histgram_of_phase_of_TRLWELvl1( + std::cout, TFHEpp::trlwePhase(res, skey.key.lvl1)); for (size_t i = 0; i < N; i++) { TRLWELvl1 tmp = res; TFHEpp::CMUXFFT(res, guard.at(i), tmp, c0); } - dump_histgram_of_phase_of_TRLWELvl1(std::cout, - TFHEpp::trlwePhase(res, skey.key.lvl1)); + dump_histgram_of_phase_of_TRLWELvl1( + std::cout, TFHEpp::trlwePhase(res, skey.key.lvl1)); /* PolyLvl1 testvec1 = {}, testvec2 = {};