安装 GMP、NTL、CTMalloc ,编译 OpenFHE
参考文献:
- [ABB+22] Al Badawi A, Bates J, Bergamaschi F, et al. Openfhe: Open-source fully homomorphic encryption library[C]//Proceedings of the 10th Workshop on Encrypted Computing & Applied Homomorphic Cryptography. 2022: 53-63.
- openfheorg/openfhe-development
- Welcome to OpenFHE’s documentation!
- 在Ubuntu上安装NTL库以及编译测试
- Ubuntu上安装NTL库
- 内存优化-如何使用tcmalloc来提升内存性能?
- 在Ubuntu上安装Bazel
- Google Performance Tools安装以及使用
- Git安装教程以及连接Github
- GMP:代码,文档
- gf2x:代码,文档
- NTL:代码,文档
- ctmalloc:代码,文档
- bazel:代码,文档
文章目录
- 安装 GMP
- 安装 gf2x
- 安装 NTL
- 安装 Bazel
- 安装 ctmalloc
- 编译 OpenFHE
- FHE 样例
我使用的是 WSL 子系统,
- 操作系统版本:
Ubuntu 22.04.2 LTS
,位数x86_64
- GMP 版本:
6.2.1
- NTL 版本:
11.5.1
安装 GMP
下载 GMP 6.2.1 版本(必须和 NTL 11.5.1
匹配,如果冲突报错了,在你安装的源码目录 gmp-6.3.0
下执行 sudo make uninstall
卸载),解压并进入 gmp-6.2.1
文件夹,
./configure --prefix=$HOME/gmp
make
make check
sudo make install
如果 prefix
不指定安装的目录,库文件 lib
会产生在 /usr/local/lib
,头文件在 /usr/local/include
。我没有指定,让它默认安装到 /usr/local
内。
安装结果:
----------------------------------------------------------------------
Libraries have been installed in:
/usr/local/lib
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the 'LD_RUN_PATH' environment variable
during linking
- use the '-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to '/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
/usr/bin/mkdir -p '/usr/local/include'
/usr/bin/install -c -m 644 gmp.h '/usr/local/include'
/usr/bin/mkdir -p '/usr/local/lib/pkgconfig'
/usr/bin/install -c -m 644 gmp.pc '/usr/local/lib/pkgconfig'
make install-data-hook
make[4]: Entering directory '/mnt/e/ThirdPartyLibrary/GMP/gmp-6.2.1'
安装 gf2x
如果源码文件夹下没有 ./configure
,但有 configure.am
或 configure.in
,我们用 autoconf
命令来生成。
-
我们先安装
autoconf
工具,sudo apt-get install autoconf
-
下载 gf2x,我们下载
.tar.gz
版本的压缩文件,并在 Linux 下解压(在 Windows 下解压.zip
做编译时会报错,因为 Linux 下的软链接被翻译成了形如../../crypto/opensslconf.h
的一行代码形式),gunzip gf2x-master.tar.gz tar xf gf2x-master.tar cd gf2x-master
-
我们先执行如下指令(直接执行
autoreconf --install
和./configure
会有找不到Makefile.in
文件的报错),aclocal libtoolize --force automake --add-missing autoconf
-
然后生成
./configure
文件,autoreconf --install
-
现在可以安装
gf2x
了,./configure make make check sudo make install
安装结果:
Libraries have been installed in:
/home/wqf/sw/lib
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the 'LD_RUN_PATH' environment variable
during linking
- use the '-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to '/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
安装 NTL
安装好 GMP
之后再编译 NTL
,计算效率快得多,
For this to work, GMP must already be installed (most Unix distributions already come with GMP installed, but see this page for more details). If you really do not want to use GMP, you can pass the option
NTL_GMP_LIP=off
toconfigure
; however, NTL will run significantly faster with GMP, so this is strongly discouraged.
安装好 gf2x
之后再编译 NTL
,使得 GF(2)
的效率快得多,
If you want very high-performance for polynomial arithmetic over GF(2), you may want to consider using the gf2x library. To do this, gf2x must already be installed. In addition, you should invoke configure with the option NTL_GF2X_LIB=on.
-
下载最新版本的 NTL,我们下载
ntl-11.5.1.tar.gz
压缩文件,在 Linux 下解压gunzip ntl-11.5.1.tar.gz tar xf ntl-11.5.1.tar cd ntl-11.5.1/src/
-
默认配置了
GMP
,我们额外配置gf2x
,./configure PREFIX=/usr/local NTL_GF2X_LIB=on GF2X_PREFIX=/usr/local
-
编译
make make check sudo make install
-
如果执行
make check
时找不到.so
的软连接,删除后使用绝对路径重新配置下,sudo rm libgf2x.so.4 sudo rm libgf2x.so sudo ln -s /usr/local/lib/libgf2x.so.4.0.0 /usr/local/lib/libgf2x.so.4 sudo ln -s /usr/local/lib/libgf2x.so.4.0.0 /usr/local/lib/libgf2x.so sudo ldconfig
安装结果:
mkdir -p -m 755 /usr/local/include
rm -rf /usr/local/include/NTL
mkdir -m 755 /usr/local/include/NTL
cp -p ../include/NTL/*.h /usr/local/include/NTL
chmod -R a+r /usr/local/include/NTL
mkdir -p -m 755 /usr/local/share/doc
rm -rf /usr/local/share/doc/NTL
mkdir -m 755 /usr/local/share/doc/NTL
cp -p ../doc/*.txt /usr/local/share/doc/NTL
cp -p ../doc/*.html /usr/local/share/doc/NTL
cp -p ../doc/*.gif /usr/local/share/doc/NTL
chmod -R a+r /usr/local/share/doc/NTL
mkdir -p -m 755 /usr/local/lib
cp -p ntl.a /usr/local/lib/libntl.a #LSTAT
chmod a+r /usr/local/lib/libntl.a #LSTAT
安装 Bazel
Bazel
是 Google 开源的编译构建工具,以 Monolithic Repository 为理念。与 makefile & CMake
不同,Bazel 另起炉灶,采用 client/server 运行模式,为云编译而生。Bazel 工具将编译过程分三个阶段:Load Phase/Analysis Phase/Execution phase。研发人员实现 workspace/build/.bzl 三种文件,Bazel 执行这些文件生成 action graph,执行 action 来构建项目。
下载 bazel,我们下载 installer-linux-x86_64.sh
二进制安装程序,
chmod +x bazel-6.4.0-installer-linux-x86_64.sh
sudo cp ./bazel-6.4.0-installer-linux-x86_64.sh /usr/local/bin/
cd /usr/local/bin/
./bazel-6.4.0-installer-linux-x86_64.sh
安装结果:
Bazel is now installed!
Make sure you have "/usr/local/bin" in your path.
For bash completion, add the following line to your ~/.bashrc:
source /usr/local/lib/bazel/bin/bazel-complete.bash
For fish shell completion, link this file into your
/root/.config/fish/completions/ directory:
ln -s /usr/local/lib/bazel/bin/bazel.fish /root/.config/fish/completions/bazel.fish
See http://bazel.build/docs/getting-started.html to start a new project!
使用 Bazel
编译 ctmalloc
源码时,它总是去链接 https://github.com/protocolbuffers/protobuf/archive/13d559beb6967033a467a7517c35d8ad970f8afb.zip
下载 com_google_protobuf
,但是报错 Connection refused
。明明用浏览器可以打开这个网址啊!无语。。。
安装 ctmalloc
ctmalloc
是一个高效管理内存的工具包,需要使用 bazel
来编译源码,但它连不上 github
,编译不了!!!我们通过安装 gperftools
来实现 ctmalloc
的安装。
TCMalloc (Thread-Caching Malloc) 与标准 glibc
库的 malloc
实现一样的功能,但是 TCMalloc 在效率和速度效率都比标准 malloc 高很多。TCMalloc 是 google-perftools
工具中的一个(四个工具分别是:TCMalloc、heap-checker、heap-profiler 和 cpu-profiler)。
-
下载 libunwind(追踪函数调用栈),源码安装
autoreconf --force -v --install ./configure make sudo make install
-
下载 gperftools(CPU 性能分析器),源码安装
autoreconf --force -v --install ./configure make sudo make install
-
最后把 ctmalloc 加载到 Linux 系统中,
su echo '/usr/local/lib' > /etc/ld.so.conf.d/local.conf /sbin/ldconfig exit
编译 OpenFHE
-
在 https://github.com/openfheorg/openfhe-development 下载 OpenFHE 的源代码,解压得到
openfhe-development-main
-
递归下载依赖的第三方代码(本来是空文件夹),
cd ./third-party git init git submodule update --init --recursive
-
我们配置
./CMakeLists
文件,打开WITH_NTL, WITH_TCM
等优化选项(如果你没有安装它们,就不要打开),构造出Makefile
文件,mkdir build cd build cmake .. BUILD_EXTRAS=ON WITH_NTL=ON WITH_TCM=ON
-
OpenFHE
的源码文件很大,我们启用多线程 ,make -j 16
-
根据需求可以安装到系统中(在
./build
下执行sudo make uninstall
即可卸载),make install
现在我们根据 ./unitest
中的三个测试代码,做正确性测试,
make testall
运行了好长时间后(主要是 pke
的 1489 cases
很慢),得到的测试结果,
-- demoData folder already exists
[ 0%] Built target third-party
[ 21%] Built target coreobj
[ 21%] Built target OPENFHEcore
[ 26%] Built target binfheobj
[ 28%] Built target OPENFHEbinfhe
[ 34%] Built target binfhe_tests
[ 48%] Built target core_tests
[ 80%] Built target pkeobj
[ 80%] Built target OPENFHEpke
[100%] Built target pke_tests
core:
Testing Backends: 4 Native
****** OpenFHE Version 1.1.1
****** Date 2023-10-29T13:55:17
****** End 159 cases 159 passed 0 failed
pke:
Testing Backends: 4 Native
****** OpenFHE Version 1.1.1
****** Date 2023-10-29T13:55:38
****** End 1489 cases 1489 passed 0 failed
binfhe:
Testing Backends: 4 Native
****** OpenFHE Version 1.1.1
****** Date 2023-10-29T14:24:47
****** End 84 cases 84 passed 0 failed
[100%] Built target testall
FHE 样例
测试 BFV 方案,执行 bin/examples/pke/simple-integers
,
Plaintext #1: ( 1 2 3 4 5 6 7 8 9 10 11 12 ... )
Plaintext #2: ( 3 2 1 4 5 6 7 8 9 10 11 12 ... )
Plaintext #3: ( 1 2 5 2 5 6 7 8 9 10 11 12 ... )
Results of homomorphic computations
#1 + #2 + #3: ( 5 6 9 10 15 18 21 24 27 30 33 36 ... )
#1 * #2 * #3: ( 3 8 15 32 125 216 343 512 729 1000 1331 1728 ... )
Left rotation of #1 by 1: ( 2 3 4 5 6 7 8 9 10 11 12 ... )
Left rotation of #1 by 2: ( 3 4 5 6 7 8 9 10 11 12 ... )
Right rotation of #1 by 1: ( 0 1 2 3 4 5 6 7 8 9 10 11 ... )
Right rotation of #1 by 2: ( 0 0 1 2 3 4 5 6 7 8 9 10 ... )
测试 CKKS 方案,执行 bin/examples/pke/simple-real-numbers
,
CKKS scheme is using ring dimension 16384
Input x1: (0.25, 0.5, 0.75, 1, 2, 3, 4, 5, ... ); Estimated precision: 50 bits
Input x2: (5, 4, 3, 2, 1, 0.75, 0.5, 0.25, ... ); Estimated precision: 50 bits
Results of homomorphic computations:
x1 = (0.25, 0.5, 0.75, 1, 2, 3, 4, 5, ... ); Estimated precision: 43 bits
Estimated precision in bits: 43
x1 + x2 = (5.25, 4.5, 3.75, 3, 3, 3.75, 4.5, 5.25, ... ); Estimated precision: 43 bits
Estimated precision in bits: 43
x1 - x2 = (-4.75, -3.5, -2.25, -1, 1, 2.25, 3.5, 4.75, ... ); Estimated precision: 43 bits
4 * x1 = (1, 2, 3, 4, 8, 12, 16, 20, ... ); Estimated precision: 41 bits
x1 * x2 = (1.25, 2, 2.25, 2, 2, 2.25, 2, 1.25, ... ); Estimated precision: 42 bits
In rotations, very small outputs (~10^-10 here) correspond to 0's:
x1 rotate by 1 = (0.5, 0.75, 1, 2, 3, 4, 5, 0.25, ... ); Estimated precision: 43 bits
x1 rotate by -2 = (4, 5, 0.25, 0.5, 0.75, 1, 2, 3, ... ); Estimated precision: 43 bits
测试 TFHE 方案,执行 bin/examples/binfhe/boolean-truth-tables
,
Generate cryptocontext
Finished generating cryptocontext
Generating the bootstrapping keys...
Completed the key generation.
1 NAND 1 = 0
1 NAND 0 = 1
0 NAND 0 = 1
0 NAND 1 = 1
1 AND 1 = 1
1 AND 0 = 0
0 AND 0 = 0
0 AND 1 = 0
1 OR 1 = 1
1 OR 0 = 1
0 OR 0 = 0
0 OR 1 = 1
1 NOR 1 = 0
1 NOR 0 = 0
0 NOR 0 = 1
0 NOR 1 = 0
1 XOR 1 = 0
1 XOR 0 = 1
0 XOR 0 = 0
0 XOR 1 = 1
1 XNOR 1 = 1
1 XNOR 0 = 0
0 XNOR 0 = 1
0 XNOR 1 = 0
1 XOR_FAST 1 = 0
1 XOR_FAST 0 = 1
0 XOR_FAST 0 = 0
0 XOR_FAST 1 = 1
1 XNOR_FAST 1 = 1
1 XNOR_FAST 0 = 0
0 XNOR_FAST 0 = 1
0 XNOR_FAST 1 = 0