赞
踩
HElib是IBM用C++写成的一个开源的同态加密库。至于同态加密是什么,网上有一堆教程,无须赘述。
对于同态加密库HElib而言,所有的输入输出都表示成为vector<long>的形式,vector<long>的大小和HElib的初始化参数有关。需要将原始数据全部全部转换成vector<long>的形式,至于如何转换,与具体的业务逻辑有关系,HElib并不关心具体的转换方式,HElib所做的只是对vector<long>进行加解密,以及进行加减乘等运算。
首先先介绍一下HElib的几个重要的类:
FHEcontext类:初始化所必须的类,程序根据初始化的参数生成FHEcontext对象,进而通过FHEcontext对象生成同态加密的公私钥。
ZZX类:生成EncryptedArray所必须的。
FHESecKey类:同态加密私钥类
FHEPubKey类:同态加密公钥类
EncryptedArray类:贯穿整个同态加密的代码,用于将vector<long>编码成同态加密的明文对象,对于数据进行同态加密和解密,用于将明文对象解码成vector<long>。
NewPlaintextArray类:明文对象,输入vector<long>转换成明文对象进而进一步被HElib处理,如果利用cout将NewPlaintextArray对象输出的话也是以向量形式输出,维度与对应位置的元素与vector<long>相同。提供了加、减、乘、移位、异或等运算。加减乘运算即向量对应位置的元素进行加减乘。
Ctxt对象:同态加密的密文对象,NewPlaintextArray类进行同态加密以后得到Ctxt对象。提供了和NewPlaintextArray一样的运算。
示例代码:
- #include <NTL/ZZ.h>
- #include <NTL/BasicThreadPool.h>
- #include "FHE.h"
- #include "timing.h"
- #include "EncryptedArray.h"
- #include <NTL/lzz_pXFactoring.h>
-
- #include <cassert>
- #include <cstdio>
-
- int main(){
- long R=1;
- long p=619;//p决定了进行同态加密的数值可以有多大
- long r=1;
- long d=1;
- long c=2;
- long k=80;
- long w=64;
- long L=6;
- long m=7781;
- Vec<long> gens;
- Vec<long> ords;//以上都是进行同态加密初始化的参数,其中p参数比较重要,它是Ctxt类中Plaintextspace成员的值,决定了我们进行同态加密运算的数据范围并且p必须为素数。例如本例中p=619,则进行同态加密运算的数据不得超过619,明文运算的结果也不能超过619,否则没有办法解密出正确的结果。
- vector<long> gens1, ords1;
- convert(gens1, gens);
- convert(ords1, ords);
- FHEcontext context(m, p, r, gens1, ords1);
- buildModChain(context, L, c);
-
- ZZX G;
- if (d == 0)
- G = context.alMod.getFactorsOverZZ()[0];
- else
- G = makeIrredPoly(p, d);//进行HElib的初始化
-
- //生成同态加密的公私钥,进行同态加密运算的密文对象必须是经过同一公钥加密的数据,否则会报错
- FHESecKey secretKey(context);
- const FHEPubKey& publicKey = secretKey;
- secretKey.GenSecKey(w); // A Hamming-weight-w secret key
- addSome1DMatrices(secretKey); // compute key-switching matrices that we need
-
- EncryptedArray ea(context, G);
- long nslots = ea.size();
-
- NewPlaintextArray plain_text1(ea);
- vector<long> data1;
- data1.resize(nslots);
- data1[0]=7;
- data1[1]=8;//向量数据
- encode(ea,plain_text1,data1);//将向量编码成明文对象
- cout<<"plain_text1="<<plain_text1<<endl;
- Ctxt cipher_text1(publicKey);
- cout<<"encrypt plain_text1"<<endl;
- ea.encrypt(cipher_text1, publicKey, plain_text1);
-
-
- NewPlaintextArray plain_text2(ea);
- data1[0]=5;
- data1[1]=4;
- encode(ea,plain_text2,data1);
- cout<<"plain_text2="<<plain_text2<<endl;
- Ctxt cipher_text2(publicKey);
- ea.encrypt(cipher_text2,publicKey,plain_text2);
-
- NewPlaintextArray plain_text3(ea);
- data1[0]=1;
- data1[1]=2;
- encode(ea,plain_text3,data1);
- cout<<"plain_text3="<<plain_text3<<endl;
- Ctxt cipher_text3(publicKey);
- ea.encrypt(cipher_text3,publicKey,plain_text3);
-
- cout<<"密文相加"<<endl;
- cipher_text1+=cipher_text2;
- cipher_text1+=cipher_text3;
- cout<<"结束"<<endl;
-
- NewPlaintextArray de(ea);
- cout<<"解密:"<<endl;
- ea.decrypt(cipher_text1, secretKey, de);
- vector<long> array2;
- array2.resize(ea.size());
- decode(ea,array2,de);//把解密的结果还原成向量
- cout<<"decrypt:"<<array2<<endl;
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。