基于近似计算的同态加密方案CKKS17----实现库介绍

基于近似计算的同态加密方案CKKS17----实现库介绍,第1张

一、简介

        CKKS17方案提出了近似计算方法,方案可以对实数进行加密,这与此前均是基于整数的同态加密有很大不同。正是这一点,基于近似计算的同态加密方案可以支持现实中的大多数应用环境,具有较大发展潜力。

        目前支持CKKS17方案的库主要有:HEAAN、SEAL、HElib、PALISADE、CIMERA和PEGASUS。本文主要介绍HEAAN和SEAL库的安装环境配置,后面几个库今后了解更多可能会补充进来。

二、SEAL

        SEAL的最大优势就是微软开发的,可以应用在Windows下,并且代码开发规范,注释写得很好。

        SEAL使用较为方便。在使用SEAL3.5版本时,直接打开SEAL.sln就可以对代码进行编辑修改运行。不过在运行时总会报很多玄学错误,时常要重新生成方案,这一点上来说还是比较麻烦的。

        SEAL3.7以上版本取消了SEAL.sln这个文件,具体配置运行方法在README中有提及,按照README中所述方法可以正常进行配置。

        SEAL对Visual Studio版本有要求,比如SEAL3.5中明确指明需要Visual Studio 2019版本以上。

        虽然传说SEAL库不依赖与NLT等计算库,但是还是建议配置前提前安装下NLT和GMP,不然总会有玄学的事情发生。

三、HEAAN

        HEAAN是CKKS17论文作者提供的实现库,README中说在Ubuntu 16.04环境下可配置成功。实际测试时环境为Ubuntu 20.04,也可配置成功。

        HEAAN库有多种版本,如HEAAN-master、HEAANBOOT、FULL-RNS-HEAAN等。HEAANBOOT是CHK+18a中针对方案自举实现的可自举近似计算同态加密库,FULL-RNS-HEAAN则是针对CHK+18b中RNS变体实现的近似计算同态加密库。而HEAAN-master是该课题组一直在维护的实现库,下面的配置使用的是HEAAN-master库。

        HEAAN依赖于NTL库,使用前需安装NTL库。而NTL库需要g++、m4和gmp的支持。

安装g++
sudo apt-get install g++

        可以通过g++ --version查看g++的版本。

安装m4
sudo apt-get install m4
安装gmp

        官网:The GNU MP Bignum Library/

        到达下载文件的路径并执行,我下载的是gmp-6.2.1.tar.lz,具体版本号会有差异需更改:

sudo apt-get install lzip
lzip -d gmp-6.2.1.tar.lz
tar -xvf gmp-6.2.1.tar
cd gmp-6.2.1
./configure --enable-cxx
make
make check
sudo make install

        可以通过如下代码try.cpp进行测试:

#include 
#include 
using namespace std;
 
int main()
{
    mpz_t a,b,c;
    mpz_init(a);
    mpz_init(b);
    mpz_init(c);
    gmp_scanf("%Zd%Zd",a,b);
    mpz_add(c,a,b);
    gmp_printf("%Zd\n",c);
    mpz_clear(a);
    mpz_clear(b);
    mpz_clear(c);
    return 0;
}

        编译:

g++ try.cpp -o try -lgmpxx -lgmp
./try

        运行时可以输入两个巨长的数字测试大整数加法。

安装NTL

        可在 NTL: A Library for doing Number Theory下载,下载后的文件ntl-x.x.x/doc/tour-unix.html文件中有安装教程。

        在安装前确保以下已安装:

sudo apt install -y autoconf
sudo apt install -y libgmp-dev
sudo apt install -y libgf2x-dev

        安装过程如下:

gunzip ntl-xxx.tar.gz
tar xf ntl-xxx.tar
cd ntl-xxx/src
./configure
make
make check
sudo make install

        测试程序:

#include 

using namespace std;
using namespace NTL;

int main()
{
   ZZ a, b, c; 

   cin >> a; 
   cin >> b; 
   c = (a+1)*(b+1);
   cout << c << "\n";
}

        编译运行(假设文件名为tryntl.cpp):

g++ -g -O2 -std=c++11 -pthread -march=native tryntl.cpp -o tryntl -lntl -lgmp -lm
./tryntl

        运行后输入两个大整数就可得到程序中的乘法结果。

        

         安装时可能会遇到:

GMP version check (6.1.2/6.1.0)
*** version number mismatch: inconsistency between gmp.h and libgmp
Aborted (core dumped)
makefile:353: recipe for target ‘setup3’ failed

        可能是gmp版本与ntl版本不一致导致的,解决办法:

sudo ldconfig
安装HEAAN

        在/lib文件夹里执行make all,执行成功可以看到生成libHEAAN.a文件。

        测试

        先在/run文件夹下执行make命令,会生成TestHEAAAN文件,可以通过./TestHEAAN Encrypt来进行测试。TestHEAAN后的参数可见下图。运行时较费时,可能出现许久没有结果,不是电脑卡顿或命令问题,耐心等待就好。

        对于README中附的测试代码:

#include "HEAAN.h"

using namespace std;
using namespace NTL;

int main() {
  /*
  * Basic Parameters are in src/Params.h
  * If you want to use another parameter, you need to change src/Params.h file and re-complie this library.
  */

  // Parameters //
  long logq = 300; ///< Ciphertext modulus (this value should be <= logQ in "scr/Params.h")
  long logp = 30; ///< Scaling Factor (larger logp will give you more accurate value)
  long logn = 10; ///< number of slot is 1024 (this value should be < logN in "src/Params.h")
  long n = 1 << logn;
  long slots = n;
  long numThread = 8;
	
  // Construct and Generate Public Keys //
  srand(time(NULL));
  SetNumThreads(numThread);
  TimeUtils timeutils;
  Ring ring;
  SecretKey secretKey(ring);
  Scheme scheme(secretKey, ring);
  scheme.addLeftRotKeys(secretKey); ///< When you need left rotation for the vectorized message
  scheme.addRightRotKeys(secretKey); ///< When you need right rotation for the vectorized message
  
  // Make Random Array of Complex //
  complex* mvec1 = EvaluatorUtils::randomComplexArray(slots);
  complex* mvec2 = EvaluatorUtils::randomComplexArray(slots);
  
  // Encrypt Two Arry of Complex //
  Ciphertext cipher1;
  scheme.encrypt(cipher1, mvec1, n, logp, logq);
  Ciphertext cipher2;
  scheme.encrypt(cipher2, mvec2, n, logp, logq);
  
  // Addition //
  Ciphertext cipherAdd;
  scheme.add(cipherAdd, cipher1, cipher2);
  
  // Multiplication And Rescale //
  Ciphertext cipherMult;
  scheme.mult(cipherMult, cipher1, cipher2);
  Ciphertext cipherMultAfterReScale;
  scheme.reScaleBy(cipherMultAfterReScale, cipherMult, logp);
  
  // Rotation //
  long idx = 1;
  Ciphertext cipherRot;
  scheme.leftRotateFast(cipherRot, cipher1, idx);
  
  // Decrypt //
  complex* dvec1 = scheme.decrypt(secretKey, cipher1);
  complex* dvec2 = scheme.decrypt(secretKey, cipher2);
  
  return 0;

}

        将其放置在HEAAN/run文件夹下,假设保存的名字叫mytry.cpp,按如下方式进行编译:

g++ mytry.cpp -o mytry -L/usr/local/lib ../lib/libHEAAN.a -lntl -lgmp -lm -std=c++11 -O2 -I/../src -pthread

        g++后面需要带着那么一长串东西,否则编译不通过。该代码仅为测试代码,运行后无具体输出。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/928767.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-17
下一篇 2022-05-17

发表评论

登录后才能评论

评论列表(0条)

保存