Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
nindanaoto committed Mar 25, 2024
2 parents 6bfb9e2 + 9aa259b commit a58bfa9
Showing 12 changed files with 414 additions and 92 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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()
90 changes: 64 additions & 26 deletions include/circuitbootstrapping.hpp
Original file line number Diff line number Diff line change
@@ -21,16 +21,14 @@ constexpr Polynomial<typename P::domainP> CBtestvector()
return poly;
}

template <class iksP, class bkP, class privksP>
template <class bkP, class privksP>
void CircuitBootstrapping(TRGSW<typename privksP::targetP> &trgsw,
const TLWE<typename iksP::domainP> &tlwe,
const TLWE<typename bkP::domainP> &tlwe,
const EvalKey &ek)
{
TLWE<typename bkP::domainP> tlwelvl0;
IdentityKeySwitch<iksP>(tlwelvl0, tlwe, ek.getiksk<iksP>());
std::array<TLWE<typename bkP::targetP>, privksP::targetP::l> temp;
GateBootstrappingManyLUT<bkP, privksP::targetP::l>(
temp, tlwelvl0, ek.getbkfft<bkP>(), CBtestvector<privksP>());
temp, tlwe, ek.getbkfft<bkP>(), CBtestvector<privksP>());
for (int i = 0; i < privksP::targetP::l; i++) {
temp[i][privksP::domainP::k * privksP::domainP::n] +=
1ULL << (numeric_limits<typename privksP::domainP::T>::digits -
@@ -42,26 +40,27 @@ void CircuitBootstrapping(TRGSW<typename privksP::targetP> &trgsw,
}
}

// template <class iksP, class bkP, class privksP>
// void AnnihilateCircuitBootstrapping(TRGSW<typename privksP::targetP> &trgsw,
// const TLWE<typename iksP::domainP> &tlwe,
// const EvalKey &ek)
// {
// TLWE<typename bkP::domainP> tlwelvl0;
// IdentityKeySwitch<iksP>(tlwelvl0, tlwe, ek.getiksk<iksP>());
// TRLWE<typename bkP::targetP>> trlwe;
// BlindRotate<bkP, privksP::targetP::l>(
// trlwe, tlwelvl0, ek.getbkfft<bkP>(), CBtestvector<privksP>());
// for (int i = 0; i < privksP::targetP::l; i++)
// temp[i][privksP::domainP::k * privksP::domainP::n] +=
// 1ULL << (numeric_limits<typename privksP::domainP::T>::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<privksP>(
// trgsw[i + k * privksP::targetP::l], temp[i],
// ek.getprivksk<privksP>("privksk4cb_" + std::to_string(k)));
// }
template <class iksP, class bkP, class privksP>
void CircuitBootstrapping(TRGSW<typename privksP::targetP> &trgsw,
const TLWE<typename iksP::domainP> &tlwe,
const EvalKey &ek)
{
TLWE<typename bkP::domainP> tlwelvl0;
IdentityKeySwitch<iksP>(tlwelvl0, tlwe, ek.getiksk<iksP>());
CircuitBootstrapping<bkP, privksP>(trgsw, tlwelvl0, ek);
}

template <class brP, class privksP>
void CircuitBootstrappingFFT(TRGSWFFT<typename privksP::targetP> &trgswfft,
const TLWE<typename brP::domainP> &tlwe,
const EvalKey &ek)
{
TRGSW<typename privksP::targetP> trgsw;
CircuitBootstrapping<brP, privksP>(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<typename privksP::targetP>(trgswfft[i][j], trgsw[i][j]);
}

template <class iksP, class bkP, class privksP>
void CircuitBootstrappingFFT(TRGSWFFT<typename privksP::targetP> &trgswfft,
@@ -113,17 +112,56 @@ void CircuitBootstrappingSubFFT(TRGSWFFT<typename privksP::targetP> &trgswfft,
TwistIFFT<typename privksP::targetP>(trgswfft[i][j], trgsw[i][j]);
}

template <class brP, class privksP>
void CircuitBootstrappingFFTInv(
TRGSWFFT<typename privksP::targetP> &invtrgswfft,
const TLWE<typename brP::domainP> &tlwe, const EvalKey &ek)
{
TLWE<typename brP::domainP> invtlwe;
// HomNot
for (int i = 0; i <= brP::domainP::k * brP::domainP::n; i++)
invtlwe[i] = -tlwe[i];
CircuitBootstrappingFFT<brP, privksP>(invtrgswfft, invtlwe, ek);
}

template <class iksP, class bkP, class privksP>
void CircuitBootstrappingFFTInv(
TRGSWFFT<typename privksP::targetP> &invtrgswfft,
const TLWE<typename iksP::domainP> &tlwe, const EvalKey &ek)
{
TLWE<typename iksP::domainP> 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<iksP, bkP, privksP>(invtrgswfft, invtlwe, ek);
}

template <class brP, class privksP>
void CircuitBootstrappingFFTwithInv(
TRGSWFFT<typename privksP::targetP> &trgswfft,
TRGSWFFT<typename privksP::targetP> &invtrgswfft,
const TLWE<typename brP::domainP> &tlwe, const EvalKey &ek)
{
constexpr array<typename privksP::targetP::T, privksP::targetP::l> h =
hgen<typename privksP::targetP>();

TRGSW<typename privksP::targetP> trgsw;
CircuitBootstrapping<brP, privksP>(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<typename privksP::targetP>(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<typename privksP::targetP>(invtrgswfft[i][j],
trgsw[i][j]);
}

template <class iksP, class bkP, class privksP>
void CircuitBootstrappingFFTwithInv(
TRGSWFFT<typename privksP::targetP> &trgswfft,
30 changes: 15 additions & 15 deletions include/cloudkey.hpp
Original file line number Diff line number Diff line change
@@ -332,28 +332,28 @@ relinKeyFFT<P> relinKeyFFTgen(const Key<P>& key)

struct EvalKey {
lweParams params;
std::unique_ptr<BootstrappingKey<lvl01param>> bklvl01;
std::unique_ptr<BootstrappingKey<lvl02param>> bklvl02;
std::unique_ptr<BootstrappingKeyFFT<lvl01param>> bkfftlvl01;
std::unique_ptr<BootstrappingKeyFFT<lvl02param>> bkfftlvl02;
std::unique_ptr<BootstrappingKeyNTT<lvl01param>> bknttlvl01;
std::unique_ptr<BootstrappingKeyNTT<lvl02param>> bknttlvl02;
std::unique_ptr<KeySwitchingKey<lvl10param>> iksklvl10;
std::unique_ptr<KeySwitchingKey<lvl20param>> iksklvl20;
std::unique_ptr<KeySwitchingKey<lvl21param>> iksklvl21;
std::unique_ptr<KeySwitchingKey<lvl22param>> iksklvl22;
std::unique_ptr<SubsetKeySwitchingKey<lvl21param>> subiksklvl21;
std::shared_ptr<BootstrappingKey<lvl01param>> bklvl01;
std::shared_ptr<BootstrappingKey<lvl02param>> bklvl02;
std::shared_ptr<BootstrappingKeyFFT<lvl01param>> bkfftlvl01;
std::shared_ptr<BootstrappingKeyFFT<lvl02param>> bkfftlvl02;
std::shared_ptr<BootstrappingKeyNTT<lvl01param>> bknttlvl01;
std::shared_ptr<BootstrappingKeyNTT<lvl02param>> bknttlvl02;
std::shared_ptr<KeySwitchingKey<lvl10param>> iksklvl10;
std::shared_ptr<KeySwitchingKey<lvl20param>> iksklvl20;
std::shared_ptr<KeySwitchingKey<lvl21param>> iksklvl21;
std::shared_ptr<KeySwitchingKey<lvl22param>> iksklvl22;
std::shared_ptr<SubsetKeySwitchingKey<lvl21param>> subiksklvl21;
std::unordered_map<std::string,
std::unique_ptr<PrivateKeySwitchingKey<lvl11param>>>
std::shared_ptr<PrivateKeySwitchingKey<lvl11param>>>
privksklvl11;
std::unordered_map<std::string,
std::unique_ptr<PrivateKeySwitchingKey<lvl21param>>>
std::shared_ptr<PrivateKeySwitchingKey<lvl21param>>>
privksklvl21;
std::unordered_map<std::string,
std::unique_ptr<PrivateKeySwitchingKey<lvl22param>>>
std::shared_ptr<PrivateKeySwitchingKey<lvl22param>>>
privksklvl22;
std::unordered_map<
std::string, std::unique_ptr<SubsetPrivateKeySwitchingKey<lvl21param>>>
std::string, std::shared_ptr<SubsetPrivateKeySwitchingKey<lvl21param>>>
subprivksklvl21;

EvalKey(SecretKey sk) { params = sk.params; }
62 changes: 45 additions & 17 deletions include/gate.hpp
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@

namespace TFHEpp {
template <class brP, typename brP::targetP::T μ, class iksP, int casign,
int cbsign, typename brP::targetP::T offset>
int cbsign, std::make_signed_t<typename brP::domainP::T> offset>
inline void HomGate(TLWE<typename iksP::targetP> &res,
const TLWE<typename brP::domainP> &ca,
const TLWE<typename brP::domainP> &cb, const EvalKey &ek)
@@ -17,7 +17,7 @@ inline void HomGate(TLWE<typename iksP::targetP> &res,
GateBootstrapping<brP, μ, iksP>(res, res, ek);
}
template <class iksP, class brP, typename brP::targetP::T μ, int casign,
int cbsign, typename brP::targetP::T offset>
int cbsign, typename iksP::domainP::T offset>
inline void HomGate(TLWE<typename brP::targetP> &res,
const TLWE<typename iksP::domainP> &ca,
const TLWE<typename iksP::domainP> &cb, const EvalKey &ek)
@@ -291,32 +291,60 @@ void HomMUXwoIKSandSE(TRLWE<typename bkP::targetP> &res,
};
res[1][0] += bkP::targetP::μ;
}
template <class iksP, class bkP>
void HomMUXwoSE(TRLWE<typename bkP::targetP> &res,

template <class brP, typename brP::targetP::T μ = brP::targetP::μ>
void HomMUXwoSE(TRLWE<typename brP::targetP> &res,
const TLWE<typename brP::domainP> &cs,
const TLWE<typename brP::domainP> &c1,
const TLWE<typename brP::domainP> &c0, const EvalKey &ek)
{
TLWE<typename brP::domainP> 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<typename brP::targetP> and0trlwe;
BlindRotate<brP>(res, and1, ek.getbkfft<brP>(),
μpolygen<typename brP::targetP, brP::targetP::μ>());
BlindRotate<brP>(and0trlwe, and0, ek.getbkfft<brP>(),
μpolygen<typename brP::targetP, brP::targetP::μ>());

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 <class iksP, class brP, typename brP::targetP::T μ = brP::targetP::μ>
void HomMUXwoSE(TRLWE<typename brP::targetP> &res,
const TLWE<typename iksP::domainP> &cs,
const TLWE<typename iksP::domainP> &c1,
const TLWE<typename iksP::domainP> &c0, const EvalKey &ek)
{
TLWE<typename iksP::domainP> temp1;
TLWE<typename iksP::domainP> 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<typename iksP::domainP> 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<typename iksP::targetP> and1, and0;
IdentityKeySwitch<iksP>(and1, temp1, ek.getiksk<iksP>());
IdentityKeySwitch<iksP>(and0, temp0, ek.getiksk<iksP>());
TRLWE<typename bkP::targetP> and0trlwe;
BlindRotate<bkP>(res, and1, ek.getbkfft<bkP>(),
μpolygen<typename bkP::targetP, bkP::targetP::μ>());
BlindRotate<bkP>(and0trlwe, and0, ek.getbkfft<bkP>(),
μpolygen<typename bkP::targetP, bkP::targetP::μ>());
TRLWE<typename brP::targetP> and0trlwe;
BlindRotate<brP>(res, and1, ek.getbkfft<brP>(),
μpolygen<typename brP::targetP, brP::targetP::μ>());
BlindRotate<brP>(and0trlwe, and0, ek.getbkfft<brP>(),
μpolygen<typename brP::targetP, brP::targetP::μ>());

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<lvl1param> &res, const TRLWE<lvl1param> &csr,
Loading

0 comments on commit a58bfa9

Please sign in to comment.