HElib-2 向量内积

news/2024/7/3 20:28:19

本文翻译自:
https://mshcruz.wordpress.com/2016/09/27/scalar-product-using-helib/

假设输入两个向量 u=[1,2,3,4],v=[1,2,3,4] u = [ 1 , 2 , 3 , 4 ] , v = [ 1 , 2 , 3 , 4 ] ,目的是计算两个向量的内积。

以下介绍三种方式可以在密文下进行运算,首先假设已经初始化(需要的公共参数以及密钥都已经创建好了), VEC_SIZE V E C _ S I Z E 表示输入向量的大小(此处为4)。

方法一:

单独加密向量的每一个数字,得到一个密文向量:

std::vector<Ctxt> encU;
std::vector<Ctxt> encV;

for (int i=0; i<VEC_SIZE; i++) {
    Ctxt tempU(pk);
    pk.Encrypt(tempU, to_ZZX(u[i]));
    encU.push_back(tempU);
    Ctxt tempV(pk);
    pk.Encrypt(tempV, to_ZZX(v[i]));
    encV.push_back(tempV);
}

之后将两个密文向量相乘:

// Store the result in encU
for (int i=0; i<VEC_SIZE; i++) {
    encU[i] *= encV[i];
}

最后计算encU向量中所有元素的总和:

// Save the result in the first position of the vector
for (int i=0; i<VEC_SIZE; i++) {
    encU[0] += encU[i];
}

解密向量中的第一个元素,获得结果:

// Decrypt the first position, which holds the value of the scalar product
// ZZX is a class from the NTL library that represents polynomials
ZZX result;
sk.Decrypt(result, encU[0]);

return result[0];

HElib提供了 ciphertext packing c i p h e r t e x t   p a c k i n g 操作,将整个向量加密成一个密文。

方法二:

将向量中的元素编码成多项式的系数,对于向量 u u ,得到多项式u(x)=1+2x+3x2+4x3.
可以通过将一个向量编码成的多项式乘以另一个向量以“逆形式”编码的多项式(比如向量 v v 的逆形式为v(x)=4+3x+2x2+x3),并且找到一个特定项的系数来表示两个向量的内积。

ZZX U,V;

U.SetLength(VEC_SIZE);
V.SetLength(VEC_SIZE);

for (int i=0; i<VEC_SIZE; i++) {
    SetCoeff(U, i, u[i]); // u(x) = 1 + 2x + 3x^2 + 4x^3
    SetCoeff(V, VEC_SIZE-1-i, v[i]);  // v(x) = 4 + 3x + 2x^2 + 1x^3
}

之后,将每个多项式加密成一个密文:

// Ciphertexts that will hold the polynomials encrypted using public key pk
Ctxt encU(pk);
Ctxt encV(pk);

// Encrypt the polynomials into the ciphertexts
pk.Encrypt(encU, U);
pk.Encrypt(encV, V);

密文乘法:

// Multiply the ciphertexts and store the result in encU
encU *= encV;

解密之后,运算的结果为多项式第( VEC_SIZE1 V E C _ S I Z E − 1 )项的系数:

// Decrypt the multiplied ciphertext into a polynomial using the secret key sk
ZZX result;
sk.Decrypt(result, encU); 

return result[VEC_SIZE - 1];

这种方法利用密文打包技术,避免加密每一个元素,节省了时间。但同时,我们失去了访问每个元素的能力。

方法三

仍然利用密文打包技术,但不是用多项式,需要用到HElib库中的EncryptedArray类。密文向量应该和EncryptedArray具有相同的大小,由初始化的参数决定,如果输入数组中的元素不能填充密文的向量,可以用0填充,因为利用0不会改变最终的运算结果。

// Create a helper object based on the context
EncryptedArray ea(context, context.alMod.getFactorsOverZZ()[0]);

// Create vectors from the values from the arrays
// The vectors should have the same size as the EncryptedArray (ea.size),
// so fill the other positions with 0. This won't affect the result.
vector<long int> U(u, u + VEC_SIZE);
vector<long int> V(v, v + VEC_SIZE);
for (int i = VEC_SIZE; i < ea.size(); i++) {
    U.push_back(0);
    V.push_back(0);
}

利用EncryptedArray进行加密:

// Ciphertexts that will hold the encrypted vectors
Ctxt encU(pk);
Ctxt encV(pk);

// Encrypt the whole vector into one ciphertext using packing
ea.encrypt(encU, pk, U);
ea.encrypt(encV, pk, V);

计算密文的乘法,使用函数 totalSums() t o t a l S u m s ( ) 来计算向量中元素的和,并将结果存在向量的第一个元素:

// Multiply ciphertexts and store the result in encU
encU.multiplyBy(encV);

// Use the totalSums functions to sum all the elements
// The result will have the sum in all positions of the vector
totalSums(ea, encU);

解密,并返回解密的结果:

// Decrypt the result (i.e., the scalar product value)
ZZX result;
sk.Decrypt(result, encU);

return result[0];

注:这种方法也避免了单独对元素进行加密,但是它失去了一点灵活性,因为我们必须使用与创建的EncryptedArray大小相同的向量。

结论

综合考虑,如果仅仅计算向量的乘法,则方法二是最好的选择;若其他的操作也在密文上执行,则方法三可能是最好的选择。


http://www.niftyadmin.cn/n/639965.html

相关文章

第九十二课.什么是多态

什么是java的多态&#xff1a; 多态分为两种1.编译时多态&#xff1a;方法的重载&#xff1b;2.运行时多态&#xff1a;JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。&#xff08;我们平时说得多的事运行时多态&#xff0c;所以多态主…

前端周记20190211-20190215

1、静态公有方法 (function(){var privateVariable10;function privateFunction(){return false;}MyObjectfunction(){}MyObject.prototype.publicMethodfunction(){privateVariable;return this;} })(); var anew MyObject(); console.log(a.publicMethod()); MyObject在私有作…

windows下安装使用gmp

windows下的安装配置&#xff1a;https://blog.csdn.net/u012629110/article/details/51220727 使用&#xff1a; 添加头文件&#xff1a; #include <gmpxx.h> 编译必须链接相应的库&#xff1a; g mycxxprog.cc -lgmpxx -lgmp -o mycxxprog (1)gmp整数操作&#x…

dark gdk+visual c++2008在虚拟机中的运行问题

最近在开始学习做游戏&#xff0c;但是自己用的系统是ubuntu&#xff0c;所以就装了一个virtualbox,并且装了一个xp&#xff0c;于是就开始了游戏之路&#xff0c;但是我发现游戏之路是如此的坎坷&#xff0c;很多小问题&#xff0c;不过都能很快的解决&#xff0c;由于我用的是…

号码隐私保护,让用户数据更安全

常言道“出行靠滴滴&#xff0c;吃饭有饿了么”&#xff0c;在科技的时代&#xff0c;互联网平台赋予了生活更多的选择&#xff0c;一切正变得丰富、便捷。小雨淅淅沥沥地湿润着春天&#xff0c;如往常般打开手机&#xff0c;我突然发现一些APP悄然无息地有了些共同的变化&…

Wordpress博客安装异次元分享工具条的方法

异次元单篇文章顶部的分享工具条做的很美观&#xff0c;集成了新浪微博、腾讯微博、QQ空间、人人网等分享按钮&#xff0c;页面浏览数以及支付宝捐赠等功能。可惜的是没有分享出来&#xff0c;黑苹果博客分享高仿版&#xff0c;具体方法&#xff1a; 基于 eliteYang 的 Version…

第九十三课.向上转型

Java 转型问题其实并不复杂&#xff0c;只要记住一句话&#xff1a;父类引用指向子类对象。什么叫父类引用指向子类对象&#xff0c;父类定义的对象存放的子类的地址 向上转型&#xff1a;通俗地讲即是将子类对象转为父类对象。此处父类对象可以是接口 举个例子&#xff1a;有…

python 列表,数组,矩阵之间转换

# -*- coding: utf-8 -*- from numpy import *a1 [[1,2,3],[4,5,6]] #列表 print(a1 :,a1) #(a1 :, [[1, 2, 3], [4, 5, 6]])a2 array(a1) #列表 -----> 数组 print(a2 :,a2) #(a2 :, array([[1, 2, 3],[4, 5, 6]]))a3 mat(a1) #列表 ----> 矩阵 print(a3 :,a3)…