TenSEAL库:

TensSEAL是一个python的第三方库,是一个方便的同态加密库。他并不是一个原生库,而是Microsoft SEAL(一个C++库)的python接口。实现了BFV和CKKS两种同态加密算法,可以直接对tensor进行加密,隐藏了很多具体细节,可以很容易上手编写同态加密的代码。是一款新手友好性的同态加密库。

库的安装是比较简单的,可以用以下命令简单安装:

pip install tenseal

这是他的github上的地址github官网

公钥与私钥

由于TenSEAL库实现的是公钥加密算法,所以这一小节简单介绍以下公钥加密的思想。

加密呢,就是对一个消息也叫明文,比如m=1,进行某种变换,成为一个无法识别的随机数c,我们把这个随机数c叫做密文。可以用一个函数表示加密过程,其中表示密钥。将密文还原为明文的操作叫做解密,可以用表示。

时,也就是加密和解密使用的密钥是相同的,这种加密方案是对称加密,也叫做私钥密码体制。这个密钥只能由加密方和解密方知道,为了保证明文不被泄露,密钥不能透露给其他人。

然而这种方法在很多时候使用起来并不是特别方便,尤其是加密的双方需要协商一个共同的私钥。而且,有时候,有很多人都是加密者,但是解密的只能是特定的人。比如要收集员工的一些个人信息,这些个人信息只希望被老板知道,而不愿让其他员工也知道。这时公钥密码体制就可以发挥作用了。

公钥密码体制有两个不同的密钥,公钥pk和私钥sk,其中公钥pk用来进行加密,sk用来解密。加密的公钥可以公开,使得每个人都可以加密,但是只有拥有私钥的人才能解密。

这就是公钥和私钥密码的简单的理解。

下面我们来看如何用TenSEAL生成公私钥(以BFV的为例)。

import tenseal as tsctx=ts.context(ts.SCHEME_TYPE.BFV,poly_modulus_degree=4096,plain_modulus=1032193)if ctx.is_private():print("This context is private!")if ctx.is_public():print("This context is public!")

TenSEAL中定义了一个context的对象用于封装加解密所需要的参数,里面包含了密钥。在导入tenseal包之后,就可以实例化一个context对象,输入需要的参数来生成公钥和私钥了。

但是,值得注意的是,在context的初始化时,公钥和私钥都是放在context对象里面的。也就是这时的context是私有的。

如果我们需要将这个产生的公钥发布出去,那么,要做的第一件事情就是将私钥分离。下面这段代码展示了如何提取私钥并将私钥从context对象中删掉。

sk=ctx.secret_key()ctx.make_context_public()if ctx.is_private():print("This context is private!")if ctx.is_public():print("This context is public!")

这时候的context就是public的,可以将他公开了。这样子,别人就可以通过这个context来加密。

BFV加解密的简单演示

在得到了context之后,就可以进行加密了。

m1=[1,2,3,4,5]m2=[5,4,3,2,1]c1=ts.bfv_vector(ctx,m1)c2=ts.bfv_vector(ctx,m2)print("m1 is ",c1.decrypt(sk))print("m2 is ",c2.decrypt(sk))

在TenSEAL中的加密,并不是直接提供加密函数,而是使用bfv_vector这样含有加密方案名称的方法。他将编码和加密结合到了一起,我只需要传入需要加密的明文就可以了。同时加密是需要提供公钥的,也就是我们生成的那个context对象。

在加密完成后,得到的是一个密文对象,里面包含了公钥等信息。需要解密的话,可以调用密文对象的decrypt方法。解密时,需要传入私钥sk。

当然,如果你在加密时使用的context中含有私钥,那么解密的时候可以不用传入私钥。当加密时使用的公钥和解密传入的私钥不一致的时候,显然就会失败。我想这也是密文对象里面包含公钥的原因之一。

我们加密了两个明文向量,接下来展示一下BFV支持的同态运算。

#homomorphic additionc3=c1+c2print("The sum is ",c3.decrypt(sk))#homomorphic scalec4=2*c1print("2 times of m1 is ",c4.decrypt(sk))#homomorphic multiplicationc5=c1*c2print("The product is ",c5.decrypt(sk))

接下来就可以开始你的愉快的同态探索之旅啦!

下面是演示的完整代码:

import tenseal as tsctx=ts.context(ts.SCHEME_TYPE.BFV,poly_modulus_degree=4096,plain_modulus=1032193)if ctx.is_private():print("This context is private!")if ctx.is_public():print("This context is public!")sk=ctx.secret_key()ctx.make_context_public()if ctx.is_private():print("This context is private!")if ctx.is_public():print("This context is public!")m1=[1,2,3,4,5]m2=[5,4,3,2,1]c1=ts.bfv_vector(ctx,m1)c2=ts.bfv_vector(ctx,m2)print("m1 is ",c1.decrypt(sk))print("m2 is ",c2.decrypt(sk))#homomorphic additionc3=c1+c2print("The sum is ",c3.decrypt(sk))#homomorphic scalec4=2*c1print("2 times of m1 is ",c4.decrypt(sk))#homomorphic multiplicationc5=c1*c2print("The product is ",c5.decrypt(sk))