1.HElib庫簡介
- HElib是一個實現(xiàn)全同態(tài)加密的軟件庫,開發(fā)語言是C++,是根據(jù)Brakerski,Gentry,Vaikuntanathan(BGV)的全同態(tài)方案實現(xiàn)。HElib仍然是一個研究性質(zhì)的項目。在現(xiàn)階段,這個庫主要面向研究HE及其用途的研究人員。目前它還相當?shù)图?,最好把它看成是“面向HE(homomorphic encryption)的匯編語言”。
- 項目地址:https://github.com/homenc/HElib
- 相關(guān)論文:Halevi S , Shoup V . Algorithms in HElib[J]. Lecture Notes in Computer Science, 2014, 8616:554-571.
2.安裝步驟
第一步:下載代碼并解壓。
- 解壓后如下所示:
[07:52:34][root@dl]19:52:34/home/HK_Workplace/SomeLib/HElib# ls
changes.md cmake CMakeLists.txt dependencies doc Dockerfile DOCKER_USAGE.md Doxyfile example_program INSTALL.md issue_template.md LICENSE mainpage.dox NOTICE OLD_INSTALL.txt README.md src TESTS.md
第二步:安裝依賴軟件。
- 打開INSTALL.md文件,查看安裝說明,其中安裝HElib所依賴的軟件為:
cmake >= 3.5.1
GNU make
g++ >= 5.4.0 or clang >= 3.8
pthreads
git (if you want to build the tests)
- 其中cmake可以根據(jù)CMakeLists.txt自動生成makefile編譯文件;make是執(zhí)行makefile文件所需的工具;g++或clang為c++編譯器;pthreads是多線程編譯所需要的;git這里其實不是很需要(如果后面安裝過程中選擇了DENABLE_TEST=ON的話,會在make test一步中利用git安裝google c++測試框架,這一步并不是必須的)。
第三步:配置HElib所需環(huán)境。
- 我們這里選擇INSTALL.md文件介紹的第二種安裝方法:library build,這種方法需要自己手動配置環(huán)境。另一種方法是:package build,這種方法可以自動安裝所需環(huán)境,但是不幸的是,筆者使用這種方法安裝失敗了。
- HElib所需的環(huán)境為:GMP和NTL庫。其中GMP庫的安裝可以參考筆者的另一篇文章:Charm-crypto庫安裝記錄。安裝好GMP庫后,安裝NTL庫。NTL庫安裝也很簡單,下載代碼解壓后(地址:https://www.shoup.net/ntl/download.html
,選擇Unix版本,并且版本號 NTL>=11.0.0),cd進入ntl-11.4.1/src文件夾(筆者下載的是11.4.1版本),依次輸入命令:
./configure
make
make check
sudo make install
即可安裝好。安裝好后,進入/usr/local/lib文件夾中查看,顯示有相關(guān)的庫,如下所示,有l(wèi)ibgmp.a,libntl.a文件,即可認為安裝成功。
[08:43:49][root@dl]20:43:49/usr/local/lib# ls
libgmp.a libgmp.la libgmp.so libgmp.so.10 libgmp.so.10.3.2 libntl.a libpbc.a libpbc.la libpbc.so libpbc.so.1 libpbc.so.1.0.0
第四步,按照INSTALL.md文件介紹的library build安裝方法進行安裝:
- 首先需要建立一個build文件夾:
cd HElib
mkdir build
cd build
- 之后需要利用Cmake生成makefile文件:確認處于HElib文件夾下,在HElib文件下輸入命令:
cmake -DGMP_DIR="${GMPDIR}" -DNTL_DIR="${NTLDIR}" -DCMAKE_INSTALL_PREFIX=/usr/local
其中,-DGMP_DIR="${GMPDIR}" -DNTL_DIR="${NTLDIR}","${GMPDIR}"和"${NTLDIR}"會指定去哪里尋找NTL和GMP庫(這里我們就不畫蛇添足,把具體的路徑寫上去了,筆者曾經(jīng)嘗試寫了進去,安裝失?。?,系統(tǒng)會默認去一些文件夾尋找。
-
DCMAKE_INSTALL_PREFIX=/usr/local是我們要安裝庫所在的地址前綴,這里我選了/usr/local,這樣就可以把HElib庫安裝在/usr/local/include下,編程時正好可以include進去。如果需要自己指定安裝目錄也可以,只需修改/usr/local為指定安裝目錄即可,這樣的話在編譯時需要指定頭文件地址(g++里的-I參數(shù))。
后面還可以添加選項-DENABLE_TEST=ON,這樣可以對安裝進行測試(筆者這里不推薦)。生成的makefile文件如下圖:
生成makefile文件 之后根據(jù)makefile文件進行編譯,輸入命令:
make -j16
-j16是指定線程數(shù),是一個可選選項。
- 我們跳過INSTALL.md文件所說的第四步make test(這一步是第二步選擇-DENABLE_TEST=ON后才可以的。不過會一直卡在安裝google c++測試框架上面),直接輸入在HElib文件夾下輸入:
make install
之后cd進入/usr/local/lib文件夾,顯示有l(wèi)ibhelib.a文件,cd進入/usr/local/include文件夾,顯示有helib庫,即可認為安裝成功。如下所示:
[09:25:51][root@dl]21:25:51/usr/local/lib# ls
libgmp.a libgmp.la libgmp.so libgmp.so.10 libgmp.so.10.3.2 libhelib.a libntl.a libpbc.a libpbc.la libpbc.so libpbc.so.1 libpbc.so.1.0.0 python3.5
[09:29:44][root@dl]21:29:44/usr/local/include# ls
gmp.h helib NTL pbc
3.測試
- 測試文件main.cpp如下:
#include <helib/FHE.h>
#include <helib/EncryptedArray.h>
int main(int argc, char *argv[]) {
/* Example of BGV scheme */
// Plaintext prime modulus
unsigned long p = 4999;
// Cyclotomic polynomial - defines phi(m)
unsigned long m = 32109;
// Hensel lifting (default = 1)
unsigned long r = 1;
// Number of bits of the modulus chain
unsigned long bits = 300;
// Number of columns of Key-Switching matix (default = 2 or 3)
unsigned long c = 2;
std::cout << "Initialising context object..." << std::endl;
// Intialise context
FHEcontext context(m, p, r);
// Modify the context, adding primes to the modulus chain
std::cout << "Building modulus chain..." << std::endl;
buildModChain(context, bits, c);
// Print the context
context.zMStar.printout();
std::cout << std::endl;
// Print the security level
std::cout << "Security: " << context.securityLevel() << std::endl;
// Secret key management
std::cout << "Creating secret key..." << std::endl;
// Create a secret key associated with the context
FHESecKey secret_key(context);
// Generate the secret key
secret_key.GenSecKey();
std::cout << "Generating key-switching matrices..." << std::endl;
// Compute key-switching matrices that we need
addSome1DMatrices(secret_key);
// Public key management
// Set the secret key (upcast: FHESecKey is a subclass of FHEPubKey)
const FHEPubKey& public_key = secret_key;
// Get the EncryptedArray of the context
const EncryptedArray& ea = *(context.ea);
// Get the number of slot (phi(m))
long nslots = ea.size();
std::cout << "Number of slots: " << nslots << std::endl;
// Create a vector of long with nslots elements
std::vector<long> ptxt(nslots);
// Set it with numbers 0..nslots - 1
for (int i = 0; i < nslots; ++i) {
ptxt[i] = i;
}
// Print the plaintext
std::cout << "Initial Ptxt: " << ptxt << std::endl;
// Create a ciphertext
Ctxt ctxt(public_key);
// Encrypt the plaintext using the public_key
ea.encrypt(ctxt, public_key, ptxt);
// Square the ciphertext
ctxt *= ctxt;
// Double it (using additions)
ctxt += ctxt;
// Create a plaintext for decryption
std::vector<long> decrypted(nslots);
// Decrypt the modified ciphertext
ea.decrypt(ctxt, secret_key, decrypted);
// Print the decrypted plaintext
std::cout << "Decrypted Ptxt: " << decrypted << std::endl;
return 0;
}
- 編譯命令:
g++ -std=c++11 -pthread -g -O2 -DFHE_THREADS -fmax-errors=4 -o app1 main.cpp -lhelib -lntl -lgmp -lm
編譯生成可執(zhí)行文件app1。其中:-lhelib -lntl -lgmp -lm即告訴編譯器需要將helib,ntl,gmp,m四個庫一起加入編譯(helib要放在前面,否則會報錯)。
- 執(zhí)行app1,輸入./app1即可,結(jié)果:
Initialising context object...
Building modulus chain...
m = 32109, p = 4999, phi(m) = 16560
ord(p)=690
generator 320 has order (== Z_m^*) of 6
generator 3893 has order (== Z_m^*) of 2
generator 14596 has order (== Z_m^*) of 2
T = [1 14596 3893 21407 320 14915 25618 11023 6073 20668 9965 27479 16820 31415 10009 27523 20197 2683 24089 9494 9131 23726 2320 19834 ]
Security: 127.626
Creating secret key...
Generating key-switching matrices..
Number of slots: 24
Initial ptxt:[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
Decrypted Ptxt: [0 2 8 18 32 50 72 98 128 162 200 242 288 338 392 450 512 578 648 722 800 882 968 1058]
正常運行,測試結(jié)束。
