一、前言
什么是同态加密?
同态加密就是指对密文做某种运算后相当于对明文做某种运算。例如经典的 RSA 算法就是一个乘法同态的加密算法:
c1≡m1e mod nc2≡m2e mod nc1∗c2≡(m1∗m2)e mod n
一般地,如果一对加解密算法 E(m) 和 D(c) 满足 D(F2(E(m1),E(m2)))=F1(m1,m2) ,那么我们就说这个算法是对操作 F1(x,y) 同态的。
同态加密有什么用?
如果你可以在本地就执行所有的操作,那当然是没有必要加密啦。但是许多场景是要在异地计算的,例如云计算,本地的算力不够,要提交到服务器计算,但是又不希望泄漏计算数据的隐私;或者是多方计算,一个计算涉及多台主机,就可以使用同态加密。
Paillier 是比较入门的一种同态加密算法,支持两个加密数字相加或者一个加密数字乘上一个明文数字,本文就主要介绍这个算法。
二、Paillier 公钥加密系统
Paillier 是一个公钥加密系统,由三部分组成:密钥生成算法、加密算法和解密算法。
密钥生成算法:
-
随机选取两个大质数 p 和 q ,保证 gcd(pq,(p−1)(q−1))=1 。
-
模数 n=pq 。
-
从 [1,n2] 中随机选取一个整数 g 作为公钥,λ=lcm(p−1,q−1) 为私钥。
-
定义 L(x)=nx−1 ,计算 μ≡(L(gλ mod n2))−1 mod n 。如果 μ 不存在则重新执行密钥生成算法。
加密算法:
明文 m 应该是区间 [0,n) 中的一个整数。
-
从 (0,n) 中随机选取一个整数 r 。
-
密文 c≡gmrn mod n2 。
解密算法:
密文 c 应该是区间 (0,n2) 中的一个整数
明文 m≡L(cλ mod n2)⋅μ mod n 。
三、解密算法的正确性证明
有些朋友可能看完加密算法一头雾水,为何会同时存在两个模数 n 和 n2 ?L 函数这么一个奇怪的定义又是怎么回事?这事要从二项式定理说起。
我们都知道二项式定理:
(1+n)x=k=0∑x(xk)nk.
在模 n2 意义下,就有
(1+n)x≡1+nx+(x2)n2+...≡1+nx mod n2.
把两边变化一下,可以得到
x≡n(1+n)x−1 mod n2.
这意味着我们可以轻易地计算形如 (1+kn)x 的数在模 n2 意义下关于 (1+kn) 的对数,方法就是通过 L 函数计算。
此外还需要知道一个结论,Carmichael 定理:p 和 q 是大质数,n=pq ,λ=lcm(p−1,q−1) ,对于任意整数 w 有
{wλ≡1 mod nwnλ≡1 mod n2
证明:
第一条很显然,利用欧拉定理得到。
由第一条可以知道 wλ=1+kn ,那么 wnλ=(1+kn)n ,根据之前有关二项式定理的结论就有
wnλ≡(1+kn)n≡1+kn2+(n2)k2n2+...≡1 mod n2.
现在来看解密公式
L(cλ mod n2)⋅μ≡L(gλ mod n2)L(cλ mod n2) mod n.
其中
cλ≡gmλrnλ≡gmλ mod n2.
所以
L(gλ mod n2)L(cλ mod n2)≡L(gλ mod n2)L(gmλ mod n2) mod n.
考察 gλ ,有
gλ≡1 mod n.
所以
gλ≡1+kn mod n2gmλ≡(1+kn)m≡1+knm mod n2.
那么
L(gλ mod n2)=ngλ−1=kL(gmλ mod n2)=ngmλ−1=km.
因此
L(gλ mod n2)L(gmλ mod n2)≡kkm≡m mod n.
这样就证明了 Paillier 算法的正确性。
看到这里我们可以说:Paillier 本质是利用了计算某些离散对数很容易的问题。随机数 r 是用来遮蔽明文的,但如果有私钥 λ ,就可以将 r 消除掉,然后计算离散对数得到 m 。
Paillier 原文采用的是另一种角度证明,先证明了加密函数是双射的,然后可以得到一些结论。此外原文还说用中国剩余定理可以加速解密过程,这里就不多说了。
四、Paillier 算法的同态操作
Paillier 的同态操作原理还是比较简单的,基本上自己都能推出来。
让密文相乘就可以使两个加密数相加:
c1=gm1r1nc2=gm2r2nc1c2=gm1+m2(r1r2)n.
对 c1c2 解密就可以得到 m1+m2 。
对密文做 a 次方就可以使一个加密数乘上 a :
c=gmrnca=gamran.
解密就得到 am 。
由此可以看出 Paillier 算法不需要公钥就可以实现同态操作。
五、后记
学这个算法的过程也算比较坎坷,因为网络上没啥证明的教程。有一篇文章居然说为了方便起见,选 g=1+n ,证明倒是方便了,但我觉得不合适。所幸有一片知乎文章写得很清楚,加上算法本身不算难,最后也是搞懂了。希望这篇文章能让后来者学得更轻松一些。
参考文章:
知乎教程,作者“民科局长”:https://zhuanlan.zhihu.com/p/106340045?utm_source=weibo
一篇英文教程,但是没有证明:https://blog.openmined.org/the-paillier-cryptosystem/
论文原文:https://www.cs.tau.ac.il/~fiat/crypt07/papers/Pai99pai.pdf