Seal库官方示例(二):encoders.cpp解析

news/2024/4/26 12:02:39/文章来源:https://blog.csdn.net/qq_43271194/article/details/128106354

补充一个常用的SIMD操作原理
1928790-20220311160927293-1090011372.png
图片来自的Hang Shao的文章。

完整代码
这个代码主要功能是编码明文,使得能够使用更加完整的明文多项式(前一个只用到了一个多项式的常量),也就是SIMD操作。主要包含了两个部分,一个是BGV、BFV的BatchEncoder,另一个是CKKS的CKKSEncoder。

BatchEncoder

for BFV or BFV
批处理编码,将明文多项式视为一个矩阵(假设多项式阶数为N,明文模数为T,那么这个矩阵就是一个2×N22 \times \frac N22×2N的矩阵,其中每个元素都需要mod T),在矩阵视角之下,批处理可以通过一些方法来加速运算优势就是,对密文的操作相当于对所有N个明文(也就是插槽)做同样的操作,速度远超过没有使用批处理的。

首先是比较常规的参数设置,bgv和bfv一样的,直接换方案名字就行了。

EncryptionParameters parms(scheme_type::bfv);
size_t poly_modulus_degree = 8192;
parms.set_poly_modulus_degree(poly_modulus_degree);
parms.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));

要能使用批处理,需要设置明文模数为一个 **1mod2*多项式阶数 **的一个素数,下面的代码创建了这样以恶个20-bits大小的素数。

parms.set_plain_modulus(PlainModulus::Batching(poly_modulus_degree, 20));SEALContext context(parms);
print_parameters(context);
cout << endl;

看看输出结果
image.png

验证一下批处理是否是启用状态

auto qualifiers = context.first_context_data()->qualifiers();
cout << "Batching enabled: " << boolalpha << qualifiers.using_batching << endl;

结果
image.png

接着生成加密相关的公钥,私钥,评估密钥等。

KeyGenerator keygen(context);
SecretKey secret_key = keygen.secret_key();
PublicKey public_key;
keygen.create_public_key(public_key);
RelinKeys relin_keys;
keygen.create_relin_keys(relin_keys);
Encryptor encryptor(context, public_key);
Evaluator evaluator(context);
Decryptor decryptor(context, secret_key);

创建批处理实例和设置批处理的插槽,插槽的数量等于多项式的模阶数N,

BatchEncoder batch_encoder(context);
size_t slot_count = batch_encoder.slot_count();
size_t row_size = slot_count / 2;
cout << "Plaintext matrix row size: " << row_size << endl;

创建明文矩阵2×N22 \times \frac N22×2N,每个元素要模T

vector<uint64_t> pod_matrix(slot_count, 0ULL);
pod_matrix[0] = 0ULL;
pod_matrix[1] = 1ULL;
pod_matrix[2] = 2ULL;
pod_matrix[3] = 3ULL;
pod_matrix[row_size] = 4ULL;
pod_matrix[row_size + 1] = 5ULL;
pod_matrix[row_size + 2] = 6ULL;
pod_matrix[row_size + 3] = 7ULL;cout << "Input plaintext matrix:" << endl;
print_matrix(pod_matrix, row_size);

这里创建的矩阵输出如下
image.png

接着是将矩阵编码为多项式

Plaintext plain_matrix;
print_line(__LINE__);
cout << "Encode plaintext matrix:" << endl;
batch_encoder.encode(pod_matrix, plain_matrix);

可以解码来看看正确性

vector<uint64_t> pod_result;
cout << "    + Decode plaintext matrix ...... Correct." << endl;
batch_encoder.decode(plain_matrix, pod_result);
print_matrix(pod_result, row_size);

结果
image.png

现在,来加密明文

Ciphertext encrypted_matrix;
print_line(__LINE__);
cout << "Encrypt plain_matrix to encrypted_matrix." << endl;
encryptor.encrypt(plain_matrix, encrypted_matrix);
cout << "    + Noise budget in encrypted_matrix: " << decryptor.invariant_noise_budget(encrypted_matrix) << " bits"<< endl;

看看噪声预算
image.png

现在,操作密文就相当于对8192个明文槽同时进行操作!为了显示效果,首先创建第二个明文矩阵

vector<uint64_t> pod_matrix2;
for (size_t i = 0; i < slot_count; i++)
{pod_matrix2.push_back((i & size_t(0x1)) + 1);
}
Plaintext plain_matrix2;
batch_encoder.encode(pod_matrix2, plain_matrix2);
cout << endl;
cout << "Second input plaintext matrix:" << endl;
print_matrix(pod_matrix2, row_size);

image.png

这里执行的同态操作是第一个矩阵的密文加上第二个矩阵的明文,并且取平方

print_line(__LINE__);
cout << "Sum, square, and relinearize." << endl;
evaluator.add_plain_inplace(encrypted_matrix, plain_matrix2);
evaluator.square_inplace(encrypted_matrix);
evaluator.relinearize_inplace(encrypted_matrix, relin_keys);

查看一下噪声预算,看看是否能正确的解密

cout << "    + Noise budget in result: " << decryptor.invariant_noise_budget(encrypted_matrix) << " bits" << endl;

不为0,那么可以解密
image.png

解密,解码并输出

Plaintext plain_result;
print_line(__LINE__);
cout << "Decrypt and decode result." << endl;
decryptor.decrypt(encrypted_matrix, plain_result);
batch_encoder.decode(plain_result, pod_result);
cout << "    + Result plaintext matrix ...... Correct." << endl;
print_matrix(pod_result, row_size);

image.png

然后有个奇怪的点,密文加上明文的操作怎么单独写了一个函数,同态操作是密文之间的运算,那么大概这个密文加上明文就是,先把明文加密,再相加,于是写了段代码试了一下

/*
自己添加的代码
*/
cout << "+++++++++++++++" << endl;
Ciphertext encrypted_matrix1, encrypted_matrix2, ciphertext_result;
encryptor.encrypt(plain_matrix2, encrypted_matrix2);
encryptor.encrypt(plain_matrix, encrypted_matrix1);
evaluator.add(encrypted_matrix2, encrypted_matrix1, ciphertext_result);
evaluator.square_inplace(ciphertext_result);
evaluator.relinearize_inplace(ciphertext_result, relin_keys);
cout << "    + Noise budget in result: " << decryptor.invariant_noise_budget(ciphertext_result) << " bits"<< endl;
Plaintext plain_result2;
decryptor.decrypt(ciphertext_result, plain_result2);
batch_encoder.decode(plain_result2, pod_result);
print_matrix(pod_result, row_size);

运行截图,噪声预算是一样的,那么这个函数的实质就是先明文加密,再相加,调用能少写点代码。
image.png

当然,bfv,bgv方案里面的处理都是以整数形式,那么在代码中,整数类型的位数是比较少的,那么通过多次同态计算后就容易造成数据类型溢出。所以接下来就有了ckks的编码。

CKKSEncoder

CKKS是针对浮点数类型的近似运算,也就是会丢失一定的精度。CKKS没有明文模数哦。
首先依然是方案参数设置,至于为什么这么设置5个40bit的,ckks方案用的是模数链,每一个模数因子都接近缩放因子Δ\DeltaΔ,用于rescale重缩放。

EncryptionParameters parms(scheme_type::ckks);size_t poly_modulus_degree = 8192;
parms.set_poly_modulus_degree(poly_modulus_degree);
parms.set_coeff_modulus(CoeffModulus::Create(poly_modulus_degree, { 40, 40, 40, 40, 40 }));
SEALContext context(parms);
print_parameters(context);
cout << endl;

参数结果
image.png

密钥生成(包含私钥,公钥,评估密钥)

KeyGenerator keygen(context);
auto secret_key = keygen.secret_key();
PublicKey public_key;
keygen.create_public_key(public_key);
RelinKeys relin_keys;
keygen.create_relin_keys(relin_keys);

加解密器,同态计算,编码的实例化

Encryptor encryptor(context, public_key);
Evaluator evaluator(context);
Decryptor decryptor(context, secret_key);
CKKSEncoder encoder(context);

ckks的编码是把复数或实数数字向量编码为明文对象

ckks的插槽数量为多项式阶数/2(它的明文空间就是CN/2\mathbb C^{N/2}CN/2),这里就没有像BFV一样化为两行矩阵了。

size_t slot_count = encoder.slot_count();
cout << "Number of slots: " << slot_count << endl;

定义明文向量

vector<double> input{ 0.0, 1.1, 2.2, 3.3 };
cout << "Input vector: " << endl;
print_vector(input);

image.png

好了,现在来回顾一下CKKS算法里的编码步骤:首先从N/2维扩张到N维,接着乘以一个缩放因子(用于提高精确度,这个因子就接近与重缩放要用的模数),最后是取整并编码为多项式

设立缩放因子并编码,这里设置的为2^30,使用0填充到N维(这好像跟方案里写的不一样,方案里是取的共轭再拼接)

Plaintext plain;
double scale = pow(2.0, 30);
print_line(__LINE__);
cout << "Encode input vector." << endl;
encoder.encode(input, scale, plain);

可以立刻解码看看

vector<double> output;
cout << "    + Decode input vector ...... Correct." << endl;
encoder.decode(plain, output);
print_vector(output);

image.png

接着是加密

Ciphertext encrypted;
print_line(__LINE__);
cout << "Encrypt input vector, square, and relinearize." << endl;
encryptor.encrypt(plain, encrypted);

计算平方,重线性化缩小密文规模

evaluator.square_inplace(encrypted);
evaluator.relinearize_inplace(encrypted, relin_keys);

平方后,缩放因子也跟着平方,所以现在缩放因子达到了2^60

cout << "    + Scale in squared input: " << encrypted.scale() << " (" << log2(encrypted.scale()) << " bits)"<< endl;print_line(__LINE__);
cout << "Decrypt and decode." << endl;
decryptor.decrypt(encrypted, plain);
encoder.decode(plain, output);
cout << "    + Result vector ...... Correct." << endl;
print_vector(output);

image.png

当然这里演示的不是完整的ckks方案,还少了rescale过程,也就是重缩放(还原缩放因子和降低噪声),主要看看如何编码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_38961.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HLS + ffmpeg 实现动态码流视频服务

一、简介 如下图&#xff0c;包含三部分&#xff0c;右边一列为边缘节点&#xff1b;中间一列代表数据中心&#xff1b;左边一列是项目为客户提供的一系列web管理工具&#xff1a; 具体来说在我们项目中有一堆边缘节点&#xff0c;每个节点上部署一台强大的GPU服务器及N个网络…

精彩回顾 | 苏州农商银行新一代云原生信息科技架构体系实践

11月18日&#xff0c;2022年第五届中国金融科技产业大会暨第四届中新&#xff08;苏州&#xff09;数字金融应用博览会“基础软件与云原生系统软件”分论坛成功举办。该论坛由由中国计算机学会CTO CLUB&#xff08;苏州&#xff09;承办&#xff0c;江苏省金融科技云原生融合创…

目标检测数据标注项目分析-产品缺陷检测

什么是生产过程中的产品缺陷检测? 生产过程中的缺陷检测是保证产品质量的重要环节。及时发现故障或缺陷&#xff0c;并采取适当的措施&#xff0c;我们可以降低运行和质量相关的风险。但在一般视觉系统中&#xff0c;每个缺陷都必须经过检查及预处理才能被检测到&#xff0c;…

javaSE - Arrays - 数组的定义与使用

一、数组基本用法 1.1、什么是数组 数组本质上就是让我们能 “批量” 创建相同类型的变量 也可以说是存储一组相同数据类型的数据的集合 如: 如果需要表示两个数据, 那么直接创建两个变量即可 int a; int b 如果需要表示五个数据, 那么可以创建五个变量 int a1; int a2; int …

[附源码]Python计算机毕业设计Django的4s店车辆管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

DPU网络开发SDK——DPDK(一)

随着软件定义网络SDN的不断发展&#xff0c;网络数据转发面的需求越来越多样化&#xff0c;这体现在更快的数据包处理速率&#xff0c;更高的网络吞吐带宽&#xff0c;更灵活的自定义网络协议。传统的硬件设备无法满足网络协议的自定义&#xff0c;而基于Linux内核网络协议栈的…

【能效管理】变电所运维云平台在上海某医院的设计分析

摘要&#xff1a;本文概述了变电所电力运维技术&#xff0c;分析了医院变电所中存在的技术设备老化和技术荷载不足的技术性问题&#xff0c;并从主变低压进出线路监测故障、环境监测故障、设备档案记录、运维排班记录、分析报告五个方面探讨了变电所电力运维技术的具体应用。变…

Java定时器选择

java计时器和死循环哪个好&#xff1f;哪个建议使用&#xff1f; 计时器性能更好&#xff0c;但是写起来稍微复杂一点。如果是非常短暂的延迟&#xff0c;用死循环也未尝不可。一般来说能不用死循环的尽量不用死循环&#xff01;如果你使用的是JDK1.5以上的&#xff0c;可以使…

高空简易水果采摘装置设计(CAD+proe)

目 录 摘 要 I Abstract II 1 绪论 1 1.1 选题背景及意义 1 1.2研究现状 1 1.2.1国外果园采摘机械现状 1 1.2.2国内果园采摘机械现状 4 1.2.3果园机械存在问题 5 1.2.4果园采摘机械的发展趋势 6 1.3研究主要内容 7 2 高空简易水果采摘装置原理 8 2.1 水果实采摘方式的选择 8 2.…

时间序列:时间序列模型---随机游走过程(The Random Walk Process)

本文是Quantitative Methods and Analysis: Pairs Trading此书的读书笔记。 随机游走过程是一种特殊的ARMA序列。从分子运动到股价波动等现象都被建模为随机游走。 随机游走过程是AR(1)序列&#xff0c;而且,时间序列在时刻的值为&#xff1a; 随机游走过程本质上是到当前时间…

供应双功能螯合剂THP-Mal,THP 马来酰亚胺,CAS:1314929-99-1

一&#xff1a;产品描述 1、名称 THP-Mal THP Maleimide THP 马来酰亚胺 2、CAS编号&#xff1a;1314929-99-1 3、分子式&#xff1a;C44H57N9O13 4、分子量&#xff1a;919.41 5、外观&#xff1a;白色或者灰白色粉末 6、沸点&#xff1a;1389.365.0 C(Predicted) …

Lint-staged自动修复格式错误及小结

文章目录一、背景二、Lint-staged2.1 简介2.2 修改package.json2.3 修改pre-commit2.4 测试三、小结3.1 代码格式规范3.2 Git提交规范一、背景 通过前面几节的介绍&#xff0c;目前想要提交代码&#xff0c;就要保证代码格式规范和提交信息格式规范&#xff0c;特别是pre-subm…

CSS布局的三种方式

绝对定位 绝对定位&#xff1a; ​ 属性&#xff1a;position 值&#xff1a;absolute <style> p.abs{position: absolute;left: 150px;top: 50px; }</style><p >正常文字1</p> <p >正常文字2</p> <p class"abs" >绝对定…

图库 | 图计算的适用场景有哪些?

图计算适用的场景非常广泛。在其肇始的早期阶段&#xff0c;图计算仅限于学术界以及工业界资深的研究机构内部&#xff0c;随着计算机体系架构的发展&#xff0c;图计算也在更广泛的行业和场景中得到应用。按照时间维度我们大体可以把图计算的发展及适用范围分为如下几个阶段&a…

umask 设置文件权限掩码

我们在创建文件或者目录时&#xff0c;看到的权限往往和我们设置的不一样&#xff0c;原因就在于创建文件时要受到 umask的影响。 目录 一、实际情景介绍 二、文件权限掩码 1、什么是权限掩码&#xff1f; 2、权限掩码的作用过程 3、设置权限掩码的两种方式 (1) umask 命…

【SpringCloud】08 分布式事务 seata

文章目录seata一、seata服务端的搭建&#xff08;1&#xff09;下载seata服务端&#xff08;2&#xff09;解压&#xff08;3&#xff09;配置seata的存储方式&#xff08;4&#xff09;创建seata数据库并导入相关表&#xff08;5&#xff09;把mysql的驱动jar放入到seata服务的…

智能运维应用之道,告别企业数字化转型危机

面临的问题及挑战 数据中心发展历程 2000 年中国数据中心始建&#xff0c;至今已经历以下 3 大阶段。早期&#xff1a;离散型数据中心 IT 因以项目建设为导向&#xff0c;故缺乏规划且无专门运维管理体系&#xff0c;此外&#xff0c;开发建设完的项目均是独立运维维护&#…

产品经理要不要考PMP?进化你能力的阶梯!(附:新版考纲及教材)

产品经理和项目经理看起来是毫不相关的两个专业&#xff0c;那么产品经理要不要考PMP呢&#xff1f;其实是非常有必要的。 以前去面试产品经理&#xff0c;HR只会问1个问题&#xff1a;会用axure吗&#xff1f;一开始对产品经理的定义就是设计产品原型的。能设计产品原型&…

Pytest接口测试框架实战项目搭建(三)

一、前言 前面相当于已经讲完整体框架搭建了&#xff0c;本篇主要讲述在实际业务系统的接口请求中&#xff0c;如何运用好该接口自动化测试框架。 二、步骤演示 1、在conf/api_path.py新增需要测试的接口&#xff0c;标黄底色为新加 存放测试接口仅这一个文件就行&#xff0c…

【DevPress】V2.4.3版本发布,增加内容收录管理

DevPress V2.4.3版本于2022年11月10日发版&#xff0c;增加内容收录模块&#xff0c;方便用户内容收录。 一、该版本功能包含 1、新需求 1&#xff09;控制台增加内容收录管理模块&#xff0c;包括收录内容额度管理、自动收录功能、基于内容搜索做收录以及收录内容列表。 - …