FHE의 대표적인 라이브러리인 HElib을 이용한 코딩환경을 구축한다.
기본 조건은 다음과 같다.
- OS: 우분투 (Windows + cygwin 비추)
- 컴파일러: gcc, g++ 사용
- 통합개발툴: Eclipse CDT + makefile
1. 기본 환경 구축(gcc, g++, Eclipse)
- home의 사용자 폴더에 'dev'폴더를 만들고, 여기에 필요한 모든 개발툴들을 까는것으로 전제하자.
(나는 jeff이기에 /heml/jeff/dev)
- gcc, g++
sudo apt-get install build-essential
- Eclipse CDT
Eclipse site에서 Eclipse Mars fore CDT 다운로드한 후 dev/eclipse_cdt에 압축 해제
2. HElib를 포함한 필요 라이브러리 소스 다운로드
- HElib은 GMP와 NTL라이브러리가 깔려 있어야 한다.
- HElib 다운로드: https://github.com/shaih/HElib 에서 'Download ZIP'눌러서 다운로드
. 압축해제 후 dev폴더로 이동 -> home/jeff/dev/HElib-master
. 폴더 밑에 보면 install.txt파일이 있고, 여기에 HElib 설치 방법 나와 있음 (GMP, NTL 깔고 make하라는. 아래 설명과 동일)
- GMP 다운로드: https://gmplib.org/ 에서 gmp-6.1.0.tar.lz 다운로드
(https://gmplib.org/download/gmp/gmp-6.1.0.tar.lz)
. 압축해제 후 dev폴더로 이동 -> home/jeff/dev/gmp-6.1.0
. 터미널을 열고(Ctrl-Alt-T) gmp폴더에서,
./configure
make
sudo make install
- NTL 라이브러리 다운로드: http://www.shoup.net/ntl/download.html 에서 Unix용 다운로드
. 압축해제 후 dev폴더로 이동 -> home/jeff/dev/ntl-9.6.4
. 터미널을 열고 ntl폴더 밑에 있는 src폴더에서,
./configure NTL_GMP_LIP=on
make
sudo make install
- HElib 컴파일
. 터미널에서 home/jeff/dev/HElib-master/src 폴더로 이동한 후,
make
. 3분쯤 후에 src폴더 밑에 fhe.a 파일이 생성
3. Eclipse를 에디터로, 컴파일은 make 이용
* 아래 <참조>처럼 Eclipse에서 make를 실행할 수도 있지만, 에디팅만 Eclipse에서 하고, make와 실행은 콘솔에서 하는 것이 속 편하다.(2017.1.1)
먼저, Eclipse에서 HElib-master를 사용하는 프로젝트를 만들자.
1)File/Import/하고, C/C++의 "Existing Code as Makefile Project"선택
2)Project Name입력하고, Location으로 dev/HElib-master 폴더 선택
참조로, Test_General.cpp를 열어서 한 번 살펴보고, make이용해서 컴파일 해보자.
컴파일 방법은, 콘솔에서, dev/HElib-master/src 폴더에서,
make Test_General_x
실행방법은,
./Test_General_x
간단한 코드를 직접 작성해보는 것은 다음 페이지에서 다루겠다.
참조. Eclipse에서 HElib라이브러리 이용한 코딩환경 구축하기
- New C++ Project 만든다
. Eclipse열고 New/Project/C++ Project
. Project name:HElibTest, project type:Executable/Empty project, Toolchains:Linux GCC
- Project Properties 설정
. Project선택하고 마우스 우클릭해서 Properties 선택
. C/C++ Build에서,
Build type:External builder
'Generate makefile automatically' 체크 해제
Build directory: ${workspace_loc:/HElibTest}/
- 프로젝트 밑에 다음과 같은 폴더 생성: src, obj, inc, lib
. inc폴더에 HElib-master/src에 있는 모든 헤더파일(.h) 복사
cp /home/jeff/dev/HElib-master/src/*.h /home/jeff/dev/workspace_c/HElibTest/inc
. lib폴더에 fhe.a 파일 복사
cp /home/jeff/dev/HElib-master/src/fhe.a /home/jeff/dev/workspace_c/HElibTest/lib
. src폴더에 테스트 샘플 복사
cp /home/jeff/dev/HElib-master/src/Test_General.cpp /home/jeff/dev/workspace_c/HElibTest/src
- Makefile 만들기
프로젝트폴더 밑에 Makefiel 생성: New/File Filename:Makefile
CC = g++
CFLAGS = -g -O2
INC = -Iinc -I.
GMP = -lgmp
LDLIBS = -L/usr/local/lib -lntl $(GMP) -lm
.PHONY = all clean
all : obj/Test_General_x
./$<
obj/%_x : src/%.cpp lib/fhe.a
$(CC) $(CFLAGS) $(INC) -o $@ $^ $(LDLIBS)
clean :
rm -f obj/*_
- Makefile이 열려있는 상태에서, 오른편 outline탭에서 'all'선택하고 마우스우클릭해서 "Add mask target". '%_x' 'clean'에 대해서도 동일.
- 'Make Target' 탭에서, all 더블클릭하면, Test_General.cpp가 컴파일되고 실행됨.
10:37:15 **** Build of configuration Debug for project HElibTest ****
make all
./obj/Test_General_x
*** Bound N=6096, choosing m=7781, phi(m)=7500
******** TestIt: R=1, p=2, r=1, d=1, c=2, k=80, w=64, L=6, m=7781, gens=[], ords=[]
m = 7781, p = 2, phi(m) = 7500
ord(p)=50
generator 3 has order (!= Z_m^*) of 150
G = [0 1]
generating key-switching matrices... done
computing masks and tables for rotation...done
*** round 0...
c1*=c0, level=3, log(noise/modulus)~-50.6613
c0+=k1, level=5, log(noise/modulus)~-70.8981
c2*=k2, level=4, log(noise/modulus)~-60.601
c2>>=35, level=3, log(noise/modulus)~-46.2
c2+=tmp, level=3, log(noise/modulus)~-46.2
c2>>>=123, level=3, log(noise/modulus)~-41.3921
c1=-c1, level=3, log(noise/modulus)~-50.6613
c3*=c2, level=2, log(noise/modulus)~-33.0541
c0=-c3, level=2, log(noise/modulus)~-33.0541
CRT_reconstruct: 3.2e-05 / 2 = 1.6e-05 [PAlgebra.cpp:554]
Circuit: 0.281629 / 1 = 0.281629 [src/Test_General.cpp:136]
DoubleCRT: 0.080246 / 21 = 0.00382124 [DoubleCRT.cpp:354]
FFT: 0.127646 / 97 = 0.00131594 [CModulus.cpp:191]
FFT: 0.127704 / 34 = 0.003756 [DoubleCRT.cpp:90]
FFT_remainder: 0.01916 / 97 = 0.000197526 [CModulus.cpp:196]
addPrimes: 0.093125 / 13 = 0.00716346 [DoubleCRT.cpp:297]
automorph: 0.00199 / 6 = 0.000331667 [Ctxt.cpp:887]
breakIntoDigits: 0.09362 / 7 = 0.0133743 [DoubleCRT.cpp:248]
embedInSlots: 7.7e-05 / 2 = 3.85e-05 [PAlgebra.cpp:511]
iFFT: 0.083433 / 49 = 0.00170271 [CModulus.cpp:244]
iFFT_division: 0.029525 / 49 = 0.000602551 [CModulus.cpp:294]
keySwitchPart: 0.11495 / 7 = 0.0164214 [Ctxt.cpp:343]
modDownToSet: 0.140582 / 9 = 0.0156202 [Ctxt.cpp:172]
multByConstant: 0.003939 / 1 = 0.003939 [Ctxt.cpp:834]
multByConstant: 0.00058 / 3 = 0.000193333 [Ctxt.cpp:816]
operator*=: 0.059255 / 2 = 0.0296275 [Ctxt.cpp:695]
randomize: 0.015089 / 13 = 0.00116069 [DoubleCRT.cpp:857]
reLinearize: 0.199145 / 7 = 0.0284493 [Ctxt.cpp:274]
rotate: 0.159764 / 1 = 0.159764 [EncryptedArray.cpp:162]
rotate1D: 0.159755 / 1 = 0.159755 [EncryptedArray.cpp:62]
shift: 0.042124 / 1 = 0.042124 [EncryptedArray.cpp:246]
shift1D: 0.042123 / 1 = 0.042123 [EncryptedArray.cpp:117]
smartAutomorph: 0.19172 / 3 = 0.0639067 [Ctxt.cpp:912]
toPoly: 0.113294 / 30 = 0.00377647 [DoubleCRT.cpp:677]
Check: 0.081444 / 1 = 0.081444 [src/Test_General.cpp:206]
Decrypt: 0.046461 / 4 = 0.0116153 [FHE.cpp:652]
decode: 0.033645 / 4 = 0.00841125 [EncryptedArray.cpp:332]
iFFT: 0.0302 / 16 = 0.0018875 [CModulus.cpp:244]
iFFT_division: 0.010684 / 16 = 0.00066775 [CModulus.cpp:294]
toPoly: 0.042253 / 4 = 0.0105632 [DoubleCRT.cpp:677]
10:37:16 Build Finished (took 1s.451ms)
-끝-