diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fa54b5..2e8ca93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,10 @@ if(USE_FFTW3) elseif(USE_SPQLIOX_AARCH64) add_compile_definitions(USE_SPQLIOX_AARCH64) add_subdirectory(thirdparties/spqliox_aarch64) + # Check if the platform is macOS and the architecture is ARM64 + if(APPLE AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") + include_directories(/opt/homebrew/include) + endif() else() add_subdirectory(thirdparties/spqlios) endif() diff --git a/include/circuitbootstrapping.hpp b/include/circuitbootstrapping.hpp index c8f0830..eb1053e 100644 --- a/include/circuitbootstrapping.hpp +++ b/include/circuitbootstrapping.hpp @@ -21,16 +21,14 @@ constexpr Polynomial CBtestvector() return poly; } -template +template void CircuitBootstrapping(TRGSW &trgsw, - const TLWE &tlwe, + const TLWE &tlwe, const EvalKey &ek) { - TLWE tlwelvl0; - IdentityKeySwitch(tlwelvl0, tlwe, ek.getiksk()); std::array, privksP::targetP::l> temp; GateBootstrappingManyLUT( - temp, tlwelvl0, ek.getbkfft(), CBtestvector()); + temp, tlwe, ek.getbkfft(), CBtestvector()); for (int i = 0; i < privksP::targetP::l; i++) { temp[i][privksP::domainP::k * privksP::domainP::n] += 1ULL << (numeric_limits::digits - @@ -42,26 +40,27 @@ void CircuitBootstrapping(TRGSW &trgsw, } } -// template -// void AnnihilateCircuitBootstrapping(TRGSW &trgsw, -// const TLWE &tlwe, -// const EvalKey &ek) -// { -// TLWE tlwelvl0; -// IdentityKeySwitch(tlwelvl0, tlwe, ek.getiksk()); -// TRLWE> trlwe; -// BlindRotate( -// trlwe, tlwelvl0, ek.getbkfft(), CBtestvector()); -// for (int i = 0; i < privksP::targetP::l; i++) -// temp[i][privksP::domainP::k * privksP::domainP::n] += -// 1ULL << (numeric_limits::digits - -// (i + 1) * privksP::targetP::Bgbit - 1); -// for (int i = 0; i < privksP::targetP::l; i++) -// for (int k = 0; k < privksP::targetP::k + 1; k++) -// PrivKeySwitch( -// trgsw[i + k * privksP::targetP::l], temp[i], -// ek.getprivksk("privksk4cb_" + std::to_string(k))); -// } +template +void CircuitBootstrapping(TRGSW &trgsw, + const TLWE &tlwe, + const EvalKey &ek) +{ + TLWE tlwelvl0; + IdentityKeySwitch(tlwelvl0, tlwe, ek.getiksk()); + CircuitBootstrapping(trgsw, tlwelvl0, ek); +} + +template +void CircuitBootstrappingFFT(TRGSWFFT &trgswfft, + const TLWE &tlwe, + const EvalKey &ek) +{ + TRGSW trgsw; + CircuitBootstrapping(trgsw, tlwe, ek); + for (int i = 0; i < (privksP::targetP::k + 1) * privksP::targetP::l; i++) + for (int j = 0; j < privksP::targetP::k + 1; j++) + TwistIFFT(trgswfft[i][j], trgsw[i][j]); +} template void CircuitBootstrappingFFT(TRGSWFFT &trgswfft, @@ -113,6 +112,18 @@ void CircuitBootstrappingSubFFT(TRGSWFFT &trgswfft, TwistIFFT(trgswfft[i][j], trgsw[i][j]); } +template +void CircuitBootstrappingFFTInv( + TRGSWFFT &invtrgswfft, + const TLWE &tlwe, const EvalKey &ek) +{ + TLWE invtlwe; + // HomNot + for (int i = 0; i <= brP::domainP::k * brP::domainP::n; i++) + invtlwe[i] = -tlwe[i]; + CircuitBootstrappingFFT(invtrgswfft, invtlwe, ek); +} + template void CircuitBootstrappingFFTInv( TRGSWFFT &invtrgswfft, @@ -120,10 +131,37 @@ void CircuitBootstrappingFFTInv( { TLWE invtlwe; // HomNot - for (int i = 0; i <= iksP::domainP::n; i++) invtlwe[i] = -tlwe[i]; + for (int i = 0; i <= iksP::domainP::k * iksP::domainP::n; i++) + invtlwe[i] = -tlwe[i]; CircuitBootstrappingFFT(invtrgswfft, invtlwe, ek); } +template +void CircuitBootstrappingFFTwithInv( + TRGSWFFT &trgswfft, + TRGSWFFT &invtrgswfft, + const TLWE &tlwe, const EvalKey &ek) +{ + constexpr array h = + hgen(); + + TRGSW trgsw; + CircuitBootstrapping(trgsw, tlwe, ek); + for (int i = 0; i < (privksP::targetP::k + 1) * privksP::targetP::l; i++) + for (int j = 0; j < privksP::targetP::k + 1; j++) { + TwistIFFT(trgswfft[i][j], trgsw[i][j]); + for (int k = 0; k < privksP::targetP::n; k++) trgsw[i][j][k] *= -1; + } + for (int i = 0; i < privksP::targetP::l; i++) { + trgsw[i][0][0] += h[i]; + trgsw[i + privksP::targetP::l][1][0] += h[i]; + } + for (int i = 0; i < (privksP::targetP::k + 1) * privksP::targetP::l; i++) + for (int j = 0; j < privksP::targetP::k + 1; j++) + TwistIFFT(invtrgswfft[i][j], + trgsw[i][j]); +} + template void CircuitBootstrappingFFTwithInv( TRGSWFFT &trgswfft, diff --git a/include/cloudkey.hpp b/include/cloudkey.hpp index 0a69865..f400e7d 100644 --- a/include/cloudkey.hpp +++ b/include/cloudkey.hpp @@ -332,28 +332,28 @@ relinKeyFFT

relinKeyFFTgen(const Key

& key) struct EvalKey { lweParams params; - std::unique_ptr> bklvl01; - std::unique_ptr> bklvl02; - std::unique_ptr> bkfftlvl01; - std::unique_ptr> bkfftlvl02; - std::unique_ptr> bknttlvl01; - std::unique_ptr> bknttlvl02; - std::unique_ptr> iksklvl10; - std::unique_ptr> iksklvl20; - std::unique_ptr> iksklvl21; - std::unique_ptr> iksklvl22; - std::unique_ptr> subiksklvl21; + std::shared_ptr> bklvl01; + std::shared_ptr> bklvl02; + std::shared_ptr> bkfftlvl01; + std::shared_ptr> bkfftlvl02; + std::shared_ptr> bknttlvl01; + std::shared_ptr> bknttlvl02; + std::shared_ptr> iksklvl10; + std::shared_ptr> iksklvl20; + std::shared_ptr> iksklvl21; + std::shared_ptr> iksklvl22; + std::shared_ptr> subiksklvl21; std::unordered_map>> + std::shared_ptr>> privksklvl11; std::unordered_map>> + std::shared_ptr>> privksklvl21; std::unordered_map>> + std::shared_ptr>> privksklvl22; std::unordered_map< - std::string, std::unique_ptr>> + std::string, std::shared_ptr>> subprivksklvl21; EvalKey(SecretKey sk) { params = sk.params; } diff --git a/include/gate.hpp b/include/gate.hpp index c49eaa2..decf02b 100644 --- a/include/gate.hpp +++ b/include/gate.hpp @@ -6,7 +6,7 @@ namespace TFHEpp { template + int cbsign, std::make_signed_t offset> inline void HomGate(TLWE &res, const TLWE &ca, const TLWE &cb, const EvalKey &ek) @@ -17,7 +17,7 @@ inline void HomGate(TLWE &res, GateBootstrapping(res, res, ek); } template + int cbsign, typename iksP::domainP::T offset> inline void HomGate(TLWE &res, const TLWE &ca, const TLWE &cb, const EvalKey &ek) @@ -291,32 +291,60 @@ void HomMUXwoIKSandSE(TRLWE &res, }; res[1][0] += bkP::targetP::μ; } -template -void HomMUXwoSE(TRLWE &res, + +template +void HomMUXwoSE(TRLWE &res, + const TLWE &cs, + const TLWE &c1, + const TLWE &c0, const EvalKey &ek) +{ + TLWE and1, and0; + for (int i = 0; i <= brP::domainP::k * brP::domainP::n; i++) + and1[i] = cs[i] + c1[i]; + for (int i = 0; i <= brP::domainP::k * brP::domainP::n; i++) + and0[i] = -cs[i] + c0[i]; + and1[brP::domainP::k * brP::domainP::n] -= brP::domainP::μ; + and0[brP::domainP::k * brP::domainP::n] -= brP::domainP::μ; + TRLWE and0trlwe; + BlindRotate(res, and1, ek.getbkfft(), + μpolygen()); + BlindRotate(and0trlwe, and0, ek.getbkfft(), + μpolygen()); + + for (int i = 0; i < brP::targetP::k * brP::targetP::n; i++) { + res[0][i] += and0trlwe[0][i]; + res[1][i] += and0trlwe[1][i]; + }; + res[1][0] += brP::targetP::μ; +} + +template +void HomMUXwoSE(TRLWE &res, const TLWE &cs, const TLWE &c1, const TLWE &c0, const EvalKey &ek) { - TLWE temp1; - TLWE temp0; - for (int i = 0; i <= iksP::domainP::n; i++) temp1[i] = cs[i] + c1[i]; - for (int i = 0; i <= iksP::domainP::n; i++) temp0[i] = -cs[i] + c0[i]; - temp1[iksP::domainP::n] -= iksP::domainP::μ; - temp0[iksP::domainP::n] -= iksP::domainP::μ; + TLWE temp1, temp0; + for (int i = 0; i <= iksP::domainP::k * iksP::domainP::n; i++) + temp1[i] = cs[i] + c1[i]; + for (int i = 0; i <= iksP::domainP::k * iksP::domainP::n; i++) + temp0[i] = -cs[i] + c0[i]; + temp1[iksP::domainP::k * iksP::domainP::n] -= iksP::domainP::μ; + temp0[iksP::domainP::k * iksP::domainP::n] -= iksP::domainP::μ; TLWE and1, and0; IdentityKeySwitch(and1, temp1, ek.getiksk()); IdentityKeySwitch(and0, temp0, ek.getiksk()); - TRLWE and0trlwe; - BlindRotate(res, and1, ek.getbkfft(), - μpolygen()); - BlindRotate(and0trlwe, and0, ek.getbkfft(), - μpolygen()); + TRLWE and0trlwe; + BlindRotate(res, and1, ek.getbkfft(), + μpolygen()); + BlindRotate(and0trlwe, and0, ek.getbkfft(), + μpolygen()); - for (int i = 0; i < bkP::targetP::n; i++) { + for (int i = 0; i < brP::targetP::k * brP::targetP::n; i++) { res[0][i] += and0trlwe[0][i]; res[1][i] += and0trlwe[1][i]; }; - res[1][0] += bkP::targetP::μ; + res[1][0] += brP::targetP::μ; } void ExtractSwitchAndHomMUX(TRLWE &res, const TRLWE &csr, diff --git a/include/nussbaumer.hpp b/include/nussbaumer.hpp new file mode 100644 index 0000000..897d047 --- /dev/null +++ b/include/nussbaumer.hpp @@ -0,0 +1,130 @@ +#pragma once +#include + +namespace Nussbaumer { + +template +inline void PolynomialMulByXai(const std::span res, + const size_t a) +{ + if (a == 0) + return; + else { + constexpr size_t r = 1ull << rbit; + std::array temp; + std::copy(res.begin(), res.end(), temp.begin()); + if (a < r) { + for (int i = 0; i < a; i++) res[i] = -temp[i - a + r]; + for (int i = a; i < r; i++) res[i] = temp[i - a]; + } + else { + const size_t aa = a - r; + for (int i = 0; i < aa; i++) res[i] = temp[i - aa + r]; + for (int i = aa; i < r; i++) res[i] = -temp[i - aa]; + } + } +} + +template +void NussbaumerButterfly(const std::span res) +{ + constexpr size_t m = 1ull << mbit; + constexpr size_t r = 1ull << rbit; + for (int i = 0; i < m / 2; i++) + for (int j = 0; j < r; j++) { + const T temp = res[i * r + j]; + res[i * r + j] += res[(i + m / 2) * r + j]; + res[(i + m / 2) * r + j] = temp - res[(i + m / 2) * r + j]; + } + if constexpr (mbit != 1) { + constexpr size_t stride = 1ull << (rbit - mbit); + for (int i = 1; i < m / 2; i++) + PolynomialMulByXai( + static_cast>(res.subspan((i + m / 2) * r, r)), + i * stride); + NussbaumerButterfly( + res.template subspan<0, m * r / 2>()); + NussbaumerButterfly( + res.template subspan()); + } +} + +template +void NussbaumerTransform(std::span res) +{ + if constexpr (Nbit == 1) { + const T temp = res[0]; + res[0] += res[1]; + res[1] = temp - res[1]; + return; + } + else { + // initialize + constexpr uint mbit = Nbit / 2; + constexpr size_t m = 1ull << mbit; + constexpr uint rbit = Nbit - mbit; + constexpr size_t r = 1ull << rbit; + std::array temp; + std::copy(res.begin(), res.end(), temp.begin()); + // reorder + for (int i = 0; i < m; i++) { + for (int j = 0; j < r; j++) res[i * r + j] = temp[m * j + i]; + } + NussbaumerButterfly(res); + for (int i = 0; i < m; i++) + NussbaumerTransform( + static_cast>(res.subspan(i * r, r))); + } +} + +template +void InverseNussbaumerButterfly(const std::span res) +{ + constexpr size_t m = 1ull << mbit; + constexpr size_t r = 1ull << rbit; + if constexpr (mbit != 1) { + constexpr size_t stride = 1ull << (rbit - mbit); + InverseNussbaumerButterfly( + res.template subspan<0, m * r / 2>()); + InverseNussbaumerButterfly( + res.template subspan()); + for (int i = 1; i < m / 2; i++) + PolynomialMulByXai( + static_cast>(res.subspan((i + m / 2) * r, r)), + 2 * r - i * stride); + } + for (int i = 0; i < m / 2; i++) + for (int j = 0; j < r; j++) { + const T temp = res[i * r + j]; + res[i * r + j] += res[(i + m / 2) * r + j]; + res[(i + m / 2) * r + j] = temp - res[(i + m / 2) * r + j]; + } +} + +template +void InverseNussbaumerTransform(std::span res) +{ + if constexpr (Nbit == 1) { + const T temp = res[0]; + res[0] += res[1]; + res[1] = temp - res[1]; + return; + } + else { + // initialize + constexpr uint mbit = Nbit / 2; + constexpr size_t m = 1ull << mbit; + constexpr uint rbit = Nbit - mbit; + constexpr size_t r = 1ull << rbit; + for (int i = 0; i < m; i++) + InverseNussbaumerTransform( + static_cast>(res.subspan(i * r, r))); + InverseNussbaumerButterfly(res); + std::array temp; + std::copy(res.begin(), res.end(), temp.begin()); + // reorder + for (int i = 0; i < m; i++) + for (int j = 0; j < r; j++) res[m * j + i] = temp[i * r + j]; + } +} +} // namespace Nussbaumer \ No newline at end of file diff --git a/include/params/128bit.hpp b/include/params/128bit.hpp index 1d8075c..dfd84e5 100644 --- a/include/params/128bit.hpp +++ b/include/params/128bit.hpp @@ -13,7 +13,7 @@ struct lvl0param { static constexpr ErrorDistribution errordist = ErrorDistribution::ModularGaussian; static const inline double α = 0.000'092'511'997'467'675'6; // fresh noise - using T = uint32_t; // Torus representation + using T = uint16_t; // Torus representation static constexpr T μ = 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; static constexpr double Δ = @@ -39,7 +39,8 @@ struct lvl1param { static constexpr T μ = 1U << 29; static constexpr uint32_t plain_modulus = 8; static constexpr double Δ = - static_cast(1ULL << std::numeric_limits::digits) / plain_modulus; + static_cast(1ULL << std::numeric_limits::digits) / + plain_modulus; }; struct lvl2param { diff --git a/include/params/concrete.hpp b/include/params/concrete.hpp index b3113da..86704dc 100644 --- a/include/params/concrete.hpp +++ b/include/params/concrete.hpp @@ -18,7 +18,7 @@ struct lvl0param { ErrorDistribution::ModularGaussian; static constexpr inline double α = 0.000'092'511'997'467'675'6; // fresh noise, 2^{-13.4} - using T = uint32_t; // Torus representation + using T = uint16_t; // Torus representation static constexpr T μ = 1U << (std::numeric_limits::digits - 3); static constexpr uint32_t plain_modulus = 8; static constexpr double Δ = diff --git a/include/tlwe.hpp b/include/tlwe.hpp index ce858a8..ddd12af 100644 --- a/include/tlwe.hpp +++ b/include/tlwe.hpp @@ -103,6 +103,7 @@ std::vector> bootsSymEncrypt(const std::vector &p, const Key

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

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

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

(c[i], key); return p; } diff --git a/test/gate.cpp b/test/gate.cpp index 3e2f123..8478b3e 100644 --- a/test/gate.cpp +++ b/test/gate.cpp @@ -144,39 +144,77 @@ void RunTest() vector> cres(kNumTests); vector> c(3 * kNumTests); - Test

("NOT", TFHEpp::HomNOT

, NotChegk, p, cres, c, kNumTests, *sk, ek); - Test

("COPY", TFHEpp::HomCOPY

, CopyChegk, p, cres, c, kNumTests, *sk, - ek); - Test

("NAND", TFHEpp::HomNAND, - NandChegk, p, cres, c, kNumTests, *sk, ek); - Test

("OR", TFHEpp::HomOR, OrChegk, - p, cres, c, kNumTests, *sk, ek); - Test

("ORYN", TFHEpp::HomORYN, - OrYNChegk, p, cres, c, kNumTests, *sk, ek); - Test

("ORNY", TFHEpp::HomORNY, - OrNYChegk, p, cres, c, kNumTests, *sk, ek); - Test

("AND", TFHEpp::HomAND, - AndChegk, p, cres, c, kNumTests, *sk, ek); - Test

("ANDYN", TFHEpp::HomANDYN, - AndYNChegk, p, cres, c, kNumTests, *sk, ek); - Test

("ANDNY", TFHEpp::HomANDNY, - AndNYChegk, p, cres, c, kNumTests, *sk, ek); - Test

("XOR", TFHEpp::HomXOR, - XorChegk, p, cres, c, kNumTests, *sk, ek); - Test

("XNOR", TFHEpp::HomXNOR, - XnorChegk, p, cres, c, kNumTests, *sk, ek); - Test

("MUX", TFHEpp::HomMUX

, MuxChegk, p, cres, c, kNumTests, *sk, ek); - Test

("NMUX", TFHEpp::HomNMUX

, NMuxChegk, p, cres, c, kNumTests, *sk, - ek); - Test

("ConstantZero", TFHEpp::HomCONSTANTZERO

, ConstantZeroChegk, p, - cres, c, kNumTests, *sk, ek); - Test

("ConstantOne", TFHEpp::HomCONSTANTONE

, ConstantOneChegk, p, cres, - c, kNumTests, *sk, ek); + if constexpr (std::is_same_v) { + cout << "lvl0param" << endl; + Test

("NOT", TFHEpp::HomNOT

, NotChegk, p, cres, c, kNumTests, *sk, + ek); + Test

("COPY", TFHEpp::HomCOPY

, CopyChegk, p, cres, c, kNumTests, + *sk, ek); + Test

("NAND", TFHEpp::HomNAND, + NandChegk, p, cres, c, kNumTests, *sk, ek); + Test

("OR", TFHEpp::HomOR, + OrChegk, p, cres, c, kNumTests, *sk, ek); + Test

("ORYN", TFHEpp::HomORYN, + OrYNChegk, p, cres, c, kNumTests, *sk, ek); + Test

("ORNY", TFHEpp::HomORNY, + OrNYChegk, p, cres, c, kNumTests, *sk, ek); + Test

("AND", TFHEpp::HomAND, + AndChegk, p, cres, c, kNumTests, *sk, ek); + Test

("ANDYN", TFHEpp::HomANDYN, + AndYNChegk, p, cres, c, kNumTests, *sk, ek); + Test

("ANDNY", TFHEpp::HomANDNY, + AndNYChegk, p, cres, c, kNumTests, *sk, ek); + Test

("XOR", TFHEpp::HomXOR, + XorChegk, p, cres, c, kNumTests, *sk, ek); + Test

("XNOR", TFHEpp::HomXNOR, + XnorChegk, p, cres, c, kNumTests, *sk, ek); + Test

("MUX", TFHEpp::HomMUX

, MuxChegk, p, cres, c, kNumTests, *sk, + ek); + Test

("NMUX", TFHEpp::HomNMUX

, NMuxChegk, p, cres, c, kNumTests, + *sk, ek); + Test

("ConstantZero", TFHEpp::HomCONSTANTZERO

, ConstantZeroChegk, + p, cres, c, kNumTests, *sk, ek); + Test

("ConstantOne", TFHEpp::HomCONSTANTONE

, ConstantOneChegk, p, + cres, c, kNumTests, *sk, ek); + } + else if constexpr (std::is_same_v) { + cout << "lvl1param" << endl; + Test

("NOT", TFHEpp::HomNOT

, NotChegk, p, cres, c, kNumTests, *sk, + ek); + Test

("COPY", TFHEpp::HomCOPY

, CopyChegk, p, cres, c, kNumTests, + *sk, ek); + Test

("NAND", TFHEpp::HomNAND, + NandChegk, p, cres, c, kNumTests, *sk, ek); + Test

("OR", TFHEpp::HomOR, + OrChegk, p, cres, c, kNumTests, *sk, ek); + Test

("ORYN", TFHEpp::HomORYN, + OrYNChegk, p, cres, c, kNumTests, *sk, ek); + Test

("ORNY", TFHEpp::HomORNY, + OrNYChegk, p, cres, c, kNumTests, *sk, ek); + Test

("AND", TFHEpp::HomAND, + AndChegk, p, cres, c, kNumTests, *sk, ek); + Test

("ANDYN", TFHEpp::HomANDYN, + AndYNChegk, p, cres, c, kNumTests, *sk, ek); + Test

("ANDNY", TFHEpp::HomANDNY, + AndNYChegk, p, cres, c, kNumTests, *sk, ek); + Test

("XOR", TFHEpp::HomXOR, + XorChegk, p, cres, c, kNumTests, *sk, ek); + Test

("XNOR", TFHEpp::HomXNOR, + XnorChegk, p, cres, c, kNumTests, *sk, ek); + Test

("MUX", TFHEpp::HomMUX

, MuxChegk, p, cres, c, kNumTests, *sk, + ek); + Test

("NMUX", TFHEpp::HomNMUX

, NMuxChegk, p, cres, c, kNumTests, + *sk, ek); + Test

("ConstantZero", TFHEpp::HomCONSTANTZERO

, ConstantZeroChegk, + p, cres, c, kNumTests, *sk, ek); + Test

("ConstantOne", TFHEpp::HomCONSTANTONE

, ConstantOneChegk, p, + cres, c, kNumTests, *sk, ek); + } } int main() { RunTest(); - // RunTest(); + RunTest(); return 0; } \ No newline at end of file diff --git a/test/nussbaumer.cpp b/test/nussbaumer.cpp new file mode 100644 index 0000000..2286059 --- /dev/null +++ b/test/nussbaumer.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include + +int main() +{ + constexpr uint32_t num_test = 1000; + std::random_device seed_gen; + std::default_random_engine engine(seed_gen()); + std::uniform_int_distribution Bgdist(0, TFHEpp::lvl1param::Bg); + std::uniform_int_distribution Torus32dist(0, UINT32_MAX); + + // std::cout << "Start LVL1 test." << std::endl; + for (int test = 0; test < num_test; test++) { + using T = uint64_t; + std::array a, res; + for (T &i : a) i = Torus32dist(engine); + res = a; + Nussbaumer::NussbaumerTransform( + std::span{res}); + Nussbaumer::InverseNussbaumerTransform( + std::span{res}); + for (int i = 0; i < TFHEpp::lvl1param::n; i++) + assert(abs(static_cast( + a[i] - res[i] / TFHEpp::lvl1param::n) <= 1)); + } + std::cout << "Id Passed" << std::endl; + + // for (int test = 0; test < num_test; test++) { + // array a; + // for (int i = 0; i < lvl1param::n; i++) + // a[i] = Bgdist(engine) - lvl1param::Bg / 2; + // for (typename TFHEpp::lvl1param::T &i : a) + // i = Bgdist(engine) - lvl1param::Bg / 2; + // array b; + // for (typename TFHEpp::lvl1param::T &i : b) i = Torus32dist(engine); + + // Polynomial polymul; + // TFHEpp::PolyMul(polymul, a, b); + // Polynomial naieve = {}; + // for (int i = 0; i < lvl1param::n; i++) { + // for (int j = 0; j <= i; j++) + // naieve[i] += static_cast(a[j]) * b[i - j]; + // for (int j = i + 1; j < lvl1param::n; j++) + // naieve[i] -= + // static_cast(a[j]) * b[lvl1param::n + i - j]; + // } + // for (int i = 0; i < lvl1param::n; i++) + // assert(abs(static_cast(naieve[i] - polymul[i])) <= 1); + // } + // cout << "PolyMul Passed" << endl; + + // uniform_int_distribution Bgbardist(0, lvl2param::Bg); + // uniform_int_distribution Torus64dist(0, UINT64_MAX); + + // cout << "Start LVL2 test." << endl; + // for (int test = 0; test < num_test; test++) { + // Polynomial a; + // for (uint64_t &i : a) i = Torus64dist(engine); + // PolynomialInFD resfft; + // TFHEpp::TwistIFFT(resfft, a); + // Polynomial res; + // TFHEpp::TwistFFT(res, resfft); + // for (int i = 0; i < lvl2param::n; i++) + // assert(abs(static_cast(a[i] - res[i])) <= (1 << 14)); + // } + // cout << "FFT Passed" << endl; + + return 0; +} \ No newline at end of file diff --git a/thirdparties/cereal b/thirdparties/cereal index d1fcec8..ddd4672 160000 --- a/thirdparties/cereal +++ b/thirdparties/cereal @@ -1 +1 @@ -Subproject commit d1fcec807b372f04e4c1041b3058e11c12853e6e +Subproject commit ddd467244713ea4fe63733628992efcdd6a9187d diff --git a/thirdparties/spqliox_aarch64/CMakeLists.txt b/thirdparties/spqliox_aarch64/CMakeLists.txt index 0f12a99..ea37a2d 100644 --- a/thirdparties/spqliox_aarch64/CMakeLists.txt +++ b/thirdparties/spqliox_aarch64/CMakeLists.txt @@ -5,4 +5,12 @@ set(SPQLIOX_AARCH64_HEADERS fft_processor_spqliox_aarch64.h add_library(spqliox_aarch64 STATIC ${SPQLIOX_AARCH64_SRCS} ${SPQLIOX_AARCH64_HEADERS}) -target_include_directories(spqliox_aarch64 PUBLIC ${PROJECT_SOURCE_DIR}/include) +# Check if the platform is macOS and the architecture is ARM64 +if(APPLE AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") + # Add the include directory provided by Homebrew + target_include_directories( + spqliox_aarch64 PUBLIC ${PROJECT_SOURCE_DIR}/include /opt/homebrew/include) +else() + target_include_directories(spqliox_aarch64 + PUBLIC ${PROJECT_SOURCE_DIR}/include) +endif()