本文将会介绍最基本的同态加密BGV的基本操作,包括加密,乘法,加法和解密。
在进行加密之前最麻烦的,也是用户最关心的就是参数的设置问题。同态加密的参数的设置是一个比较难的问题,需要对同态加密有一个比较深入的理解。所以,大多数同态密码库都给出了默认的参数设置。
首先设置一个参数变量来记录你要设置的参数:
CCParams<CryptoContextBGVRNS> parameters;
这里的 CryptoContextBGVRNS 是说你要构建一个BGV的方案。
下面介绍BGV必须要设置的几个参数。
这里的明文模是明文多项式的系数模。明文的运算是在有限域 Z p \mathbb{Z}_p Zp上,这里的明文模就是指 p p p。默认的明文模为0,但是0在实际中是不可以的,所以你必须设置一个明文模。一般会按照他推荐的来设置。建议默认为536903681。
语法为:
parameters.SetPlaintextModulus(536903681);
你要执行运算的乘法深度,如果把密文当作未知数,那么要计算的函数的最高次项的次数,就可以简单理解为乘法深度。比如 x 2 x^2 x2的乘法深度为2, x 3 x^3 x3乘法深度为3.
加密生成的密文层级为0,两个密文的乘法的层级为两个密文最大的层级加一。加法密文的层级为两个密文的层级中最大的。
乘法深度指在运算中密文可以达到的最大层级。你可以设更大一点,但是会降低效率。
parameters.SetMultiplicativeDepth(2);
加密上下文保存了一些公开的参数信息,是进行下面操作必须的。利用上文的参数,生成加密上下文。
CryptoContext<DCRTPoly> cryptoContext = GenCryptoContext(parameters);
OpenFHE需要你主动开启相应的功能,才能够进行加密、乘法等操作。
只需要加解密、加法和乘法的话,只需要下面几个就可以了。
cryptoContext->Enable(PKE);
cryptoContext->Enable(LEVELEDSHE);
cryptoContext->Enable(ADVANCEDSHE);
准备好参数以后,就可以生成密钥,然后进行加密了。
调用加密上下文的密钥生成算法,就可以生成公钥、私钥密码对:
KeyPair<DCRTPoly> keyPair;
//generate key
keyPair = cryptoContext->KeyGen();
这里的密钥对是使用 KeyPair 这个数据结构存储的,里面包含了公钥和私钥,可以直接进行访问:
keyPair.secretKey
keyPair.publicKey
由于我们需要乘法,所以,还需要为乘法生成一个计算密钥:
cryptoContext->EvalMultKeyGen(keyPair.secretKey);
生成乘法密钥是需要私钥的,生成后的计算密钥保存在加密上下文中。
要加密的数据,需要编码乘明文多项式,才可以进行加密。
BGV一般支持加密整数,默认的一个明文多项式最多可以加密16384个整数。
假设我们有这样一个数组:
vector<int64_t> v1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
然后我们可以使用加密上下文进行编码:
Plaintext p1;
p1=cryptoContext->MakePackedPlaintext(v1);
返回的 Plaintext 实际上是一个多项式。
调用加密上下文,使用公钥加密:
auto c1 = cryptoContext->Encrypt(keyPair.publicKey, p1);
密文的数据类型一半是 Ciphertext,如果你不关注具体的类型,可以直接使用 auto 让编译器自己推导类型。
加法和乘法你可以调用加密上下文:
auto r1=cryptoContext->EvalAdd(c1,c1);
auto r2=cryptoContext->EvalMult(c1,c1);
也可以直接使用“*”和“+”,已经实现了密文运算符的重载:
auto mult=c1*c1;
auto sum=c1+c1;
解密首先需要一个明文多项式类型的变量来接收解密结果,然后将指针传入,使用加密上下文和私钥来解密:
Plaintext ans_mul;
cryptoContext->Decrypt(keyPair.secretKey,mult,&ans_mul);
/*
OpenFHE test code by zyf.
basic operations of bgv.
basic_bgv.cpp
*/
#include
#include"openfhe.h"
//The functions or classes of OpenFHE are in the namespace lbcrypto
using namespace lbcrypto;
using namespace std;
int main(){
// set the parameters of bgv
CCParams<CryptoContextBGVRNS> parameters;
//plaintext modulus
parameters.SetPlaintextModulus(536903681);
//set the multiplication depth
parameters.SetMultiplicativeDepth(4);
CryptoContext<DCRTPoly> cryptoContext = GenCryptoContext(parameters);
//enable the functions of scheme.
cryptoContext->Enable(PKE);
cryptoContext->Enable(LEVELEDSHE);
KeyPair<DCRTPoly> keyPair;
//generate key
keyPair = cryptoContext->KeyGen();
cryptoContext->EvalMultKeyGen(keyPair.secretKey);
//original data
vector<int64_t> v1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
//pack the original data to plaintext polynomial
Plaintext p1;
p1=cryptoContext->MakePackedPlaintext(v1);
//encryption
auto c1 = cryptoContext->Encrypt(keyPair.publicKey, p1);
//homomorphic computation using ciphertext
//x*x
auto mult=c1*c1;
//x+x
auto sum=c1+c1;
//decryption
Plaintext ans_mul;
cryptoContext->Decrypt(keyPair.secretKey,mult,&ans_mul);
cout<<ans_mul<<endl;
Plaintext ans_sum;
cryptoContext->Decrypt(keyPair.secretKey,sum,&ans_sum);
cout<<ans_sum<<endl;
}
cmake_minimum_required (VERSION 3.5.1)
project(demo CXX)
set(CMAKE_CXX_STANDARD 17)
option( BUILD_STATIC "Set to ON to include static versions of the library" OFF)
find_package(OpenFHE)
set( CMAKE_CXX_FLAGS ${OpenFHE_CXX_FLAGS} )
include_directories( ${OPENMP_INCLUDES} )
include_directories( ${OpenFHE_INCLUDE} )
include_directories( ${OpenFHE_INCLUDE}/third-party/include )
include_directories( ${OpenFHE_INCLUDE}/core )
include_directories( ${OpenFHE_INCLUDE}/pke )
### add directories for other OpenFHE modules as needed for your project
link_directories( ${OpenFHE_LIBDIR} )
link_directories( ${OPENMP_LIBRARIES} )
if(BUILD_STATIC)
set( CMAKE_EXE_LINKER_FLAGS "${OpenFHE_EXE_LINKER_FLAGS} -static")
link_libraries( ${OpenFHE_STATIC_LIBRARIES} )
else()
set( CMAKE_EXE_LINKER_FLAGS ${OpenFHE_EXE_LINKER_FLAGS} )
link_libraries( ${OpenFHE_SHARED_LIBRARIES} )
endif()
add_executable(basic_bgv basic_bgv.cpp)
将 CMakeLists.txt 文件和 basic_bgv.cpp 文件放在一个目录,然后使用:
cmake .
make
就可以得到可执行文件basic_bgv。