From 3aa1b8783f34db056bc14b348ebdff75035601bc Mon Sep 17 00:00:00 2001 From: nindanaoto Date: Tue, 22 Oct 2024 16:18:43 +0000 Subject: [PATCH] Cheng's Packing --- include/keyswitch.hpp | 43 ++++++++++++++++++++++++++++++++++++ test/chengspacking.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 test/chengspacking.cpp diff --git a/include/keyswitch.hpp b/include/keyswitch.hpp index 2760f6e..6cf2c35 100644 --- a/include/keyswitch.hpp +++ b/include/keyswitch.hpp @@ -342,4 +342,47 @@ void SubsetPrivKeySwitch(TRLWE &res, } } +template +void PackLWEs(TRLWE

&res, const std::vector> &tlwe, const AnnihilateKey

&ahk, const uint l, const uint offset, const uint interval) +{ + if(l==0) InvSampleExtractIndex

(res,tlwe[offset],0); + else{ + TRLWE

tempeven; + PackLWEs

(tempeven, tlwe, ahk, l-1, offset, interval*2); + TRLWE

tempodd; + PackLWEs

(tempodd, tlwe, ahk, l-1, offset+interval, interval*2); + TRLWE

tempoddmul; + for(int i = 0; i < P::k+1; i++){ + PolynomialMulByXai

(tempoddmul[i], tempodd[i], P::n>>l); + for(int j = 0; j < P::n; j++){ + tempeven[i][j] /= 2; + tempoddmul[i][j] /= 2; + tempodd[i][j] = tempeven[i][j] - tempoddmul[i][j]; + // tempodd[i][j] = (tempeven[i][j] - tempoddmul[i][j])/2; + } + } + EvalAuto

(res, tempodd, (1< +void TLWE2TRLWEChengsPacking(TRLWE

&res, std::vector> &tlwe, const AnnihilateKey

&ahk) +{ + uint l = std::bit_width(tlwe.size()) - 1; + if(!std::has_single_bit(tlwe.size())){ + l++; + tlwe.resize(1<(res, tlwe, ahk, l, 0, 1); + for (int i = 0; i < P::nbit - l; i++) { + TRLWE

evaledauto; + for (int j = 0; j < (P::k+1) * P::n; j++) res[0][j] /= 2; + EvalAuto

(evaledauto, res, (1 << (P::nbit - i)) + 1, ahk[i]); + for (int j = 0; j < (P::k+1) * P::n; j++) res[0][j] += evaledauto[0][j]; + } +} } // namespace TFHEpp \ No newline at end of file diff --git a/test/chengspacking.cpp b/test/chengspacking.cpp new file mode 100644 index 0000000..6ff809c --- /dev/null +++ b/test/chengspacking.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include + +int main() +{ + constexpr uint32_t num_test = 1000; + constexpr uint l = 4; + constexpr uint numtlwe = 1< binary(0, 1); + + std::unique_ptr sk(new TFHEpp::SecretKey()); + + std::vector>> ca(num_test); + + std::vector> pin(num_test); + for (std::vector &i : pin){ + i.resize(numtlwe); + for (uint8_t &p : i) p = binary(engine); + } + for (int i = 0; i < num_test; i++) ca[i] = TFHEpp::bootsSymEncrypt(pin[i], *sk); + + std::vector> cres(num_test); + + std::unique_ptr> ahk(new TFHEpp::AnnihilateKey()); + TFHEpp::annihilatekeygen(*ahk, *sk); + + std::chrono::system_clock::time_point start, end; + start = std::chrono::system_clock::now(); + + for (int test = 0; test < num_test; test++) { + TFHEpp::TLWE2TRLWEChengsPacking(cres[test], ca[test], *ahk); + } + + end = std::chrono::system_clock::now(); + + for (int i = 0; i < num_test; i++){ + std::array pres = TFHEpp::trlweSymDecrypt(cres[i], sk->key.lvl1); + for(int j = 0; j < numtlwe; j++) assert(pres[j*(TFHEpp::lvl1param::n>>l)] == (pin[i][j] > 0)); + } + + std::cout << "Passed" << std::endl; + double elapsed = std::chrono::duration_cast(end - start).count(); + std::cout << elapsed / num_test << "ms" << std::endl; +} \ No newline at end of file