OpenFHE之BGV基本操作

本文详细介绍了OpenFHE框架中的BGV同态加密的基本操作,包括参数设置(如明文模和乘法深度)、加密、加法、乘法以及解密的过程,并提供了一个完整示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BGV基本操作

本文将会介绍最基本的同态加密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<iostream>
#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文件

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 )
include_directories( ${OpenFHE_INCLUDE}/binfhe )
### 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。

### 实现 BGV 同态加密方案 为了使用 Python 实现 BGV(Brakerski-Gentry-Vaikuntanathan)同态加密方案,通常会依赖专门设计用于支持全同态加密操作的。目前最常用的开源之一是 `OpenFHE`[^3]。 #### 安装 OpenFHE 由于 OpenFHE 主要是 C++ 编写的,并不直接提供 Python 接口,因此需要借助一些桥梁工具来实现在 Python 中调用这些功能。一种方法是利用 SWIG 或者 pybind11 将 C++ 函数绑定到 Python 上下文中。另一种更简便的方法可能是寻找已经存在的封装好的 Python 包,比如 PySEAL 或者 Concrete-Numpy 的扩展版本。 对于想要快速上手并专注于实验性质的应用场景来说,推荐先尝试现有的 Python 绑定解决方案: ```bash pip install concrete-numpy # 这是一个基于 FHE 的机器学习框架,也提供了基础的 FHE 功能 ``` 请注意,具体安装命令取决于所选的具体包及其文档说明。 #### 使用 Concrete-Numpy 创建简单的 BGV 加密实例 下面展示了一个简化版的例子,展示了如何创建上下文、生成密钥以及执行加法运算: ```python import numpy as np from concrete import fhe @fhe.compiler({"x": "encrypted", "y": "encrypted"}) def add(x, y): return x + y inputset = [(np.random.randint(0, 5), np.random.randint(0, 5)) for _ in range(10)] circuit = add.compile(inputset) # 测试编译后的电路 result = circuit.encrypt_run_decrypt(2, 3) print(f"The result of adding two encrypted numbers is: {result}") ``` 这段代码定义了一个接受两个整数输入并将它们相加的功能函数 `add()` 。通过装饰器指定了参数应被视作已加密的形式传入。之后构建了一组随机测试样本来帮助编译过程理解可能遇到的数据范围。最后一步则是实际运行这个经过优化处理过的同态加密逻辑,并验证输出是否正确反映了预期的结果。 需要注意的是上述例子仅适用于小型数值间的简单算术运算;真实的 BGV 方案涉及更多复杂的配置选项和技术细节,如多项式的选取、噪声管理机制等,这超出了当前示例所能覆盖的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值