Skip to content

Commit 99fcab5

Browse files
committed
Added InvSbox
1 parent 41772b5 commit 99fcab5

File tree

9 files changed

+105
-14
lines changed

9 files changed

+105
-14
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ add_subdirectory(src)
165165

166166
if(ENABLE_TEST)
167167
add_subdirectory(test)
168+
add_subdirectory(thirdparties/AES)
168169
endif()
169170
if(ENABLE_BENCHMARK)
170171
add_subdirectory(benchmark)

include/aes.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,41 @@
11
#pragma once
2+
#include <AES.h>
23
//Transciphering by AES
34
// Based on Hippogryph
45
namespace TFHEpp
56
{
67

8+
template <class P>
9+
inline Polynomial<P> AESInvSboxPoly(const uint8_t upperindex){
10+
Polynomial<P> poly;
11+
constexpr uint segment = P::n/16;
12+
for(int i = 0; i < 16; i++)
13+
for(int j = 0; j < segment/2; j++){
14+
poly[i*segment+2*j] = (inv_sbox[upperindex][i]&0xF)*(1ULL<<(std::numeric_limits<typename P::T>::digits-5));
15+
poly[i*segment+2*j+1] = (inv_sbox[upperindex][i]>>4)*(1ULL<<(std::numeric_limits<typename P::T>::digits-5));
16+
}
17+
return poly;
18+
}
19+
20+
template <class iksP, class brP>
21+
void AESInvSbox(std::array<TLWE<typename brP::targetP>, 2> &res,
22+
const std::array<TLWE<typename iksP::domainP>, 2> &tlwe,
23+
const EvalKey &ek)
24+
{
25+
std::array<std::array<TLWE<typename brP::targetP>,2>,16> midtlwes;
26+
TLWE<typename iksP::targetP> shifted;
27+
IdentityKeySwitch<iksP>(shifted, tlwe[0], ek.getiksk<iksP>());
28+
shifted[iksP::targetP::k*iksP::targetP::n] += 1ULL<<(std::numeric_limits<typename iksP::targetP::T>::digits-6);
29+
for (int i = 0; i < 16; i++)
30+
GateBootstrappingManyLUT<brP, 2>(midtlwes[i], shifted, ek.getbkfft<brP>(), AESInvSboxPoly<typename brP::targetP>(i));
31+
IdentityKeySwitch<iksP>(shifted, tlwe[1], ek.getiksk<iksP>());
32+
shifted[iksP::targetP::k*iksP::targetP::n] += 1ULL<<(std::numeric_limits<typename iksP::targetP::T>::digits-6);
33+
for(int i = 0; i < 2; i++){
34+
TRLWE<typename brP::targetP> trlwe;
35+
std::array<TLWE<typename iksP::domainP>, 16> tabletlwe;
36+
for(int j = 0; j < 16; j++) tabletlwe[j] = midtlwes[j][i];
37+
TLWE2TablePacking<typename brP::targetP, 16>(trlwe, tabletlwe, ek.getahk<typename brP::targetP>());
38+
GateBootstrappingTLWE2TLWEFFT<brP>(res[i], shifted, ek.getbkfft<brP>(), trlwe);
39+
}
40+
}
741
}

include/gatebootstrapping.hpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ void BlindRotate(TRLWE<typename P::targetP> &res,
119119
<< bitwidth;
120120
if (ā == 0) continue;
121121
// Do not use CMUXFFT to avoid unnecessary copy.
122-
CMUXFFTwithPolynomialMulByXaiMinusOne<typename P::targetP>(res,
122+
CMUXFFTwithPolynomialMulByXaiMinusOne<P>(res,
123123
bkfft[i], ā);
124124
}
125125
#endif
@@ -196,6 +196,17 @@ void GateBootstrappingTLWE2TLWEFFT(
196196
SampleExtractIndex<typename P::targetP>(res, acc, 0);
197197
}
198198

199+
template <class P>
200+
void GateBootstrappingTLWE2TLWEFFT(
201+
TLWE<typename P::targetP> &res, const TLWE<typename P::domainP> &tlwe,
202+
const BootstrappingKeyFFT<P> &bkfft,
203+
const TRLWE<typename P::targetP> &testvector)
204+
{
205+
alignas(64) TRLWE<typename P::targetP> acc;
206+
BlindRotate<P>(acc, tlwe, bkfft, testvector);
207+
SampleExtractIndex<typename P::targetP>(res, acc, 0);
208+
}
209+
199210
template <class P>
200211
void GateBootstrappingTLWE2TLWENTT(
201212
TLWE<typename P::targetP> &res, const TLWE<typename P::domainP> &tlwe,

include/params/128bit.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ struct lvl2param {
102102
static constexpr std::uint32_t Bgₐ = 1 << Bgₐbit;
103103
static constexpr ErrorDistribution errordist =
104104
ErrorDistribution::ModularGaussian;
105-
static const inline double α = std::pow(2.0, -47); // fresh noise
105+
static const inline double α = std::pow(2.0, -51); // fresh noise
106106
using T = uint64_t; // Torus representation
107107
static constexpr std::make_signed_t<T> μ = 1LL << 61;
108108
static constexpr uint32_t plain_modulus = 8;

include/tfhe++.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@
2828
#include "externs/circuitbootstrapping.hpp"
2929
#include "externs/gate.hpp"
3030
#include "externs/gatebootstrapping.hpp"
31-
#endif
31+
#endif
32+
33+
// Application
34+
#include "aes.hpp"

include/tlwe.hpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ bool tlweSymDecrypt(const TLWE<P> &c, const Key<P> &key)
104104
return res;
105105
}
106106

107-
template <class P, const uint plain_modulus>
107+
template <class P, uint plain_modulus = P::plain_modulus>
108108
typename P::T tlweSymIntDecrypt(const TLWE<P> &c, const Key<P> &key)
109109
{
110110
constexpr double Δ =
@@ -117,16 +117,10 @@ typename P::T tlweSymIntDecrypt(const TLWE<P> &c, const Key<P> &key)
117117
return res >= plain_modulus / 2 ? res - plain_modulus : res;
118118
}
119119

120-
template <class P>
121-
typename P::T tlweSymIntDecrypt(const TLWE<P> &c, const Key<P> &key)
122-
{
123-
return tlweSymIntDecrypt<P, P::plain_modulus>(c, key);
124-
}
125-
126-
template <class P>
120+
template <class P, uint plain_modulus=P::plain_modulus>
127121
typename P::T tlweSymIntDecrypt(const TLWE<P> &c, const SecretKey &sk)
128122
{
129-
return tlweSymIntDecrypt<P, P::plain_modulus>(c, sk.key.get<P>());
123+
return tlweSymIntDecrypt<P, plain_modulus>(c, sk.key.get<P>());
130124
}
131125

132126
template <class P, std::make_signed_t<typename P::T> μ>

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ target_include_directories(
1818
${PROJECT_SOURCE_DIR}/thirdparties/spqliox_aarch64/xbyak_aarch64/xbyak_aarch64
1919
${PROJECT_SOURCE_DIR}/thirdparties/hexl/hexl/hexl/include
2020
${PROJECT_SOURCE_DIR}/thirdparties/randen
21+
${PROJECT_SOURCE_DIR}/thirdparties/AES/src
2122
${PROJECT_SOURCE_DIR}/thirdparties/HLS_arbitrary_Precision_Types/include
2223
${PROJECT_SOURCE_DIR}/thirdparties/cereal/include)
2324

test/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ foreach(test_source ${test_sources})
99
add_executable(${test_name} ${test_source})
1010
if(USE_PERF)
1111
add_compile_definitions(USE_PERF)
12-
target_link_libraries(${test_name} tfhe++ profiler)
12+
target_link_libraries(${test_name} tfhe++ AES profiler)
1313
else()
14-
target_link_libraries(${test_name} tfhe++)
14+
target_link_libraries(${test_name} tfhe++ AES)
1515
endif()
1616
endforeach(test_source ${test_sources})
1717

test/aesinvsbox.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <cassert>
2+
#include <chrono>
3+
#include <iostream>
4+
#include <memory>
5+
#include <random>
6+
#include <tfhe++.hpp>
7+
8+
int main(){
9+
using brP = TFHEpp::lvlh2param;
10+
using iksP = TFHEpp::lvl2hparam;
11+
std::random_device seed_gen;
12+
std::default_random_engine engine(seed_gen());
13+
constexpr uint32_t plain_modulus = 1<<(4+1);
14+
std::unique_ptr<TFHEpp::SecretKey> sk(new TFHEpp::SecretKey());
15+
constexpr uint num_test = 1U<<8;
16+
// constexpr uint num_test = 1U<<4;
17+
std::vector<std::array<TFHEpp::TLWE<typename iksP::domainP>,2>> cin(num_test);
18+
19+
for (int i = 0; i < num_test; i++){
20+
cin[i][0] = TFHEpp::tlweSymIntEncrypt<typename iksP::domainP, plain_modulus>(i&0xF, *sk);
21+
cin[i][1] = TFHEpp::tlweSymIntEncrypt<typename iksP::domainP, plain_modulus>((i>>4), *sk);
22+
}
23+
std::vector<std::array<TFHEpp::TLWE<typename brP::targetP>,2>> cres(num_test);
24+
TFHEpp::EvalKey ek;
25+
ek.emplacebkfft<brP>(*sk);
26+
ek.emplaceiksk<iksP>(*sk);
27+
ek.emplaceahk<typename brP::targetP>(*sk);
28+
29+
std::chrono::system_clock::time_point start, end;
30+
start = std::chrono::system_clock::now();
31+
for (int test = 0; test < num_test; test++) {
32+
std::cout<<"test: " << test << std::endl;
33+
TFHEpp::AESInvSbox<iksP,brP>(cres[test], cin[test], ek);
34+
}
35+
36+
end = std::chrono::system_clock::now();
37+
double elapsed =
38+
std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
39+
.count();
40+
std::cout << elapsed / num_test << "ms" << std::endl;
41+
for (int i = 0; i < num_test; i++) {
42+
const uint8_t pres = (TFHEpp::tlweSymIntDecrypt<typename brP::targetP, plain_modulus>(cres[i][1], *sk)<<4)+TFHEpp::tlweSymIntDecrypt<typename brP::targetP, plain_modulus>(cres[i][0], *sk);
43+
// std::cout << "test: " << i << " pres: " << (int)pres << " expected: " << (int)inv_sbox[i>>4][i&0xF] << std::endl;
44+
assert(pres == inv_sbox[i>>4][i&0xF]);
45+
}
46+
std::cout << "Passed" << std::endl;
47+
}

0 commit comments

Comments
 (0)