1. 引言
前序博客:
Zama公司的使命为:
- 对FHE的进化(evolution)
- 对FHE的革命(revolution)
当前,开源的FHE库有:【也可参看Awesome Homomorphic Encryption】
- 1)Microsoft SEAL:开源代码见https://github.com/Microsoft/SEAL(C++ & C#),目前更新活跃。由微软主导的广为使用的开源库。
- 支持BFV和CKKS方案——即走leveled schemes分支。
- 2)OpenFHE:开源代码实现见https://github.com/openfheorg/openfhe-development(C++),目前更新活跃。由NumFocus FHE开发者联盟 主导的广泛使用的开源库。
- 支持所有主流FHE方案,如BFV、CKKS、BGV、FHEW、TFHE、LMKCDEY等,
- 同时支持FHE的multiparty扩展,如BGV、BFV、CKKS的threshold FHE,Threshold CKKS的interactive bootstrapping,以及BGV、BFV、CKKS的proxy re-encryption等。
- 3)PALISADE:当前PALISADE社区已将PALISADE项目合并到OpenFHE项目中了。
- 4)HElib:开源代码见https://github.com/shaih/HElib(C++),已有半年多未更新了。由IBM主导的早期广为使用的库。
- 支持BGV和CKKS方案,以及bootstrapping,并做了大量优化。
- 5)FHEW/TFHE:开源代码 https://github.com/lducas/FHEW(C++)已不更新,最后一次更新时间为7年前。开源代码 https://github.com/tfhe/tfhe(C++ & C),更新不活跃,上次更新为1年前。
- 6)HEAAN:开源代码见https://github.com/kimandrik/HEAAN(C++),已不更新,最后一次更新为5年前。
- 所实现的CKKS方案,原生支持fixed point approximate arithmetic。
- 7)Λ ○ λ (pronounced “L O L”):开源代码见https://github.com/cpeikert/Lol(Haskell),已不更新,最后一次更新为3年前。
- 为支持FHE的ring-based lattice密码学库。
- 8)NFLib:开源代码见https://github.com/quarkslab/NFLlib(C++ & 汇编),为NTT-based Fast Lattice,已不更新,最后一次更新为5年前。该库为欧洲HEAT项目的产物,该项目旨在探索使用底层处理器原语的高性能同态加密。
- https://github.com/bristolcrypto/HEAT(C++):专注于集成FV-NFLlib 和 HElib 同态加密库的API库。已不更新,最后一次更新为7年前。
- https://github.com/KULeuven-COSIC/HEAT/(C & Objective-C & Verilog):使用FPGA等对FV-NFLlib库进行硬件加速实现。已不更新,最后一次更新为4年前。
- 9)cuHE:开源代码见https://github.com/vernamlab/cuHE(CUDA & C++),已不更新,最后一次更新为7年前。为GPU加速FHE库。
- 10)Lattigo:开源代码见https://github.com/tuneinsight/lattigo(Go),更新活跃。为以Go语言实现的lattice-based多方同态加密库。
- 针对power-of-two cyclotomic rings运算进行优化
- 提供了RLWE-based原语、key-generation及其multiparty版本。
- 实现了BFV/BGV和CKKS方案及其multiparty版本。
- 支持RGSW、external product 和 LMKCDEY blind rotations。
- 纯Go语言实现,支持跨平台编译,如为浏览器客户端做WASM编译,其性能与C++库相当。
- 11)Concrete:开源代码实现见https://github.com/zama-ai/concrete(C++ & MLIR),更新活跃。由Zama主导。
- 该库支持TFHE方案定制变种。
- Concrete定位为:TFHE Compiler that converts python programs into FHE equivalent。
- 12)EVA:开源代码见https://github.com/microsoft/EVA(C++),已不更新,最后一次更新为3年前。为微软主导的,面向Microsoft SEAL的compiler。
以上这些FHE开源库:
- 具有不同的可用性和完成度
- 适用于单线程CPU、多线程CPU、GPU或FPGA
- 每个都有其自身的FHE方案实现
- 每个都有特定的API接口
其中:
- Concrete:开源代码实现见https://github.com/zama-ai/concrete(C++ & MLIR),更新活跃。由Zama主导。
- 专为精通技术的开发者设计。而不需要是密码学专家,无需关注底层的密码学细节。
- 为Rust compiler for TFHE
- 有一个 python wrapper,可将python程序转换为FHE等价程序。
- 底层使用Zama版本的TFHE——为开源、生产级工具:https://github.com/zama-ai/tfhe-rs(Rust)
- 支持programmable bootstrapping
2. Zama Concrete
Zama Concrete中支持的加密类型有:【详细技术细节见附录】
- 1)LWE加密:其中明文为某bit、某modular integer、或,某区间内的某实数。
- 2)RLWE加密:其中明文为
N
N
N个实数集合。即对某多项式加密,该多项式系数为不同的实数值。
Concrete中对明文 x x x的编码方式为:
- 将 x x x按bit展开(或做affine encoding),
- 然后添加噪声,噪声位于最低有效位
- 最终编码后的明文长度为32 bits或64 bits。
随着密文计算,噪声会累加。最低有效位的噪声叠加,会导致进位。随着计算的执行,噪声累加导致的进位,会向高位移动(即左移)。
噪声管理方式为:
- 随着噪声的累加,会做bootstrapping。通过bootstrapping,可实现降噪(即右移),即增加有效信息的位数。
Concrete中的同态计算:
- 可为精确的
- 也可为近似的
- 具体由用户来配置
LWE密文:
- 1)很容易做加法运算,具有加法同态性:
- 2)很容易做与整数的乘法运算:
- 3)可key-switched:需要提供public evaluation key
p
k
e
v
a
l
pk_{eval}
pkeval作为key-switching key,做完keyswitch之后,会将由私钥
s
k
1
sk_1
sk1加密
x
x
x的密文,转换为,由私钥
s
k
2
sk_2
sk2加密
x
x
x的密文。同时,噪声也会增加。即key-switched,会改变相同明文的加密密钥,但噪声会增加。
- 4)可bootstrapped:需要提供public evaluation key
p
k
e
v
a
l
pk_{eval}
pkeval作为 bootstrapping key,做完bootstrap之后,会将由私钥
s
k
1
sk_1
sk1加密
x
x
x的密文,转换为,由私钥
s
k
2
sk_2
sk2加密
x
x
x的密文。但与key-switched不同之处在于,噪声不增加,反而是减少。即bootstrapped有降噪作用。
ZAMA所采用的TFHE变种方案,其bootstrap是可编程的,即,,即,在bootstrap的同时,可同时且几乎不增加额外开销地,做明文的
f
(
⋅
)
f(\cdot)
f(⋅)运算,其中
f
(
⋅
)
f(\cdot)
f(⋅)为任意有真实价值的(单变量)函数,该函数可为非线性函数。由于bootstrap有key switch的功能,可再次切换回第一次的key。若只是想保持key的一致性,key-switched操作,实际上要远快于bootstrap操作。不过实际应用时,问题不大,key-switched操作为毫秒级,bootstrap操作为数十毫秒级。
如有需要,还可对bootstrap结果再做keyswitch。keyswitch要比PBS(Programmable Bootstrapping)快得多。
所谓programmable bootstrapping,是指:
- 将具有真实价值的单变量函数 f ( ⋅ ) f(\cdot) f(⋅),拆分为 N N N个值列表化表示。可调整N参数值来调整精度。
- PBS对应为homomorphic table lookup。
PBS非常强大,如:
- 1)伪原生乘法运算
x
⋅
y
x\cdot y
x⋅y可表示为:
x ⋅ y = ( x + y ) 2 4 − ( x − y ) 2 4 x\cdot y =\frac{(x+y)^2}{4}-\frac{(x-y)^2}{4} x⋅y=4(x+y)2−4(x−y)2
- 2)伪原生除法运算
x
/
y
x/y
x/y可表示为:
x / y = x ⋅ y − 1 x/y=x\cdot y^{-1} x/y=x⋅y−1
- 3)伪原生euclidean distance运算
∣
∣
(
x
,
y
)
∣
∣
2
||(x,y)||_2
∣∣(x,y)∣∣2可表示为:
∣ ∣ ( x , y ) ∣ ∣ 2 = x 2 + y 2 ||(x,y)||_2=\sqrt{x^2+y^2} ∣∣(x,y)∣∣2=x2+y2
- 4)伪原生求最大值运算
max
(
x
,
y
)
\max(x,y)
max(x,y)可表示为:
max ( x , y ) = max ( 0 , x − y ) + y \max(x,y)=\max(0,x-y)+y max(x,y)=max(0,x−y)+y
对于更通用的多变量函数
f
(
x
1
,
⋯
,
x
n
)
f(x_1,\cdots,x_n)
f(x1,⋯,xn),可将其分解为单变量函数。在真实分析和近似理论中,根据1957年的Kolmogorov Superposition Theorem(KST),对于每个多变量连续函数
f
:
[
0
,
1
]
n
→
R
f:[0,1]^n\rightarrow \mathbb{R}
f:[0,1]n→R,可表示为单变量连续函数的two-argument addition,即有:
f
(
x
)
=
f
(
x
1
,
⋯
,
x
n
)
=
∑
i
=
1
2
n
+
1
g
i
(
∑
j
=
1
n
f
i
j
(
x
j
)
)
f(\mathbf{x})=f(x_1,\cdots,x_n)=\sum_{i=1}^{2n+1}g_i(\sum_{j=1}^{n}f_{ij}(x_j))
f(x)=f(x1,⋯,xn)=∑i=12n+1gi(∑j=1nfij(xj))
其中
f
i
j
:
[
0
,
1
]
→
R
f_{ij}:[0,1]\rightarrow \mathbb{R}
fij:[0,1]→R为单变量函数,且,
g
i
:
R
→
R
g_i:\mathbb{R}\rightarrow\mathbb{R}
gi:R→R也为单变量函数。
Zama中,使用 Ridge decomposition,将
f
i
j
(
x
j
)
f_{ij}(x_j)
fij(xj)单变量函数进一步近似为:
f
i
j
(
x
j
)
=
a
i
j
⋅
x
j
f_{ij}(x_j)=a_{ij}\cdot x_j
fij(xj)=aij⋅xj,其中
a
i
j
∈
Z
a_{ij}\in \mathbb{Z}
aij∈Z。
从而将更通用的多变量函数
f
(
x
1
,
⋯
,
x
n
)
f(x_1,\cdots,x_n)
f(x1,⋯,xn)近似为:
f
(
x
)
=
f
(
x
1
,
⋯
,
x
n
)
=
∑
i
=
1
2
n
+
1
g
i
(
∑
j
=
1
n
a
i
j
⋅
x
j
)
f(\mathbf{x})=f(x_1,\cdots,x_n)=\sum_{i=1}^{2n+1}g_i(\sum_{j=1}^{n}a_{ij}\cdot x_j)
f(x)=f(x1,⋯,xn)=∑i=12n+1gi(∑j=1naij⋅xj)
这就意味着对于更通用的多变量计算,Zama中仅需要:
- 加法
- 以及 PBS
从而,可:
- 将复杂计算,表示为,单变量函数电路——即为,由单变量函数,及其线性组合,而混合组成的graph。
3. Zama Concrete应用:同态机器学习
以上神经网络示意图中:
- x 1 , ⋯ , x n x_1,\cdots,x_n x1,⋯,xn为一组值
- w 1 , ⋯ , w n w_1,\cdots,w_n w1,⋯,wn为一组权重
- b b b为bias
- 对以上值、权重、bias做线性组合后,获得 y = ∑ i = 1 n w i x i + b y=\sum_{i=1}^{n}w_ix_i+b y=∑i=1nwixi+b
- 对 y y y值应用激活函数 f f f——为 y y y的非线性组合。
- 神经网络只不过是神经元和其他成分的组合。有些操作不包括神经元,但神经网络的基本处理单元是这个和激活函数。
- 通常会更复杂,且更频繁,且非线性的。
2016年发表的CryptoNets论文,本质是将激活函数替换为平方函数:
- 其采用第二代FHE方案,其复杂度取决于电路中乘法运算的深度。(见FHE全同态加密介绍——小白版)
- 为降低乘法运算在电路中的深度,将激活函数替换为平方函数。
- 尽管用低degree多项式近似,会更好,但那样的话,会导致不能扩展。对于深度神经网络来说,会导致深度过大。
深度神经网络 明文 vs. 密文同态运算 性能精度对比为:
Zama为: - 针对同态AI推理的全栈解决方案
- 包含:
- (2020年)密码学库( 硬件加速):CPU/FPGA/GPU/ASIC
- (2021年)同态AI框架:Compiler以及Runtime
- (2022年)推理即服务(Inference as a Service): On-premises software(内部部署软件)和 SaaS(Software as a Service,软件运营服务)
参考资料
[1] Zama团队Pascal Paillier 2020年11月11日分享视频 001 Introduction to Homomorphic Encryption w/ Pascal Paillier(对应slide见:Introduction to Fully Homomorphic Encryption)
[2] Homomorphic Encryption Standardization: An Open Industry / Government / Academic Consortium to Advance Secure Computation
[3] https://fhe.org/resources/
附录A:LWE加密
LWE加密中有:
- 私钥: s = ( s 1 , s 2 , ⋯ , s n ) s=(s_1,s_2,\cdots,s_n) s=(s1,s2,⋯,sn),其中每个 s i s_i si为bit。
- 对明文 μ ∈ [ 0 , 1 ] \mu\in[0,1] μ∈[0,1]加密为:取均匀随机值 a 1 , a 2 , ⋯ , a n a_1,a_2,\cdots,a_n a1,a2,⋯,an,加密计算对应为: E s ( μ ) = ( a 1 , a 2 , ⋯ , a n , [ ∑ i a i s i + μ + ϵ ] 1 ) E_s(\mu)=(a_1,a_2,\cdots,a_n,[\sum_i a_is_i+\mu+\epsilon]_1) Es(μ)=(a1,a2,⋯,an,[∑iaisi+μ+ϵ]1),其中 ϵ \epsilon ϵ为加密过程所引入的随机噪声,分布于 ϵ ∈ N ( 0 , σ 2 ) \epsilon\in\mathcal{N}(0,\sigma^2) ϵ∈N(0,σ2)。
- 参考LWE Estimator,其安全性为:
λ
=
f
u
n
c
(
n
,
σ
)
\lambda=func(n,\sigma)
λ=func(n,σ)。
当明文 μ \mu μ为bit时,即为 0 0 0或 1 1 1值时,分别有:
- 基于私钥 s s s和均匀随机值 a 1 , a 2 , ⋯ , a n a_1,a_2,\cdots,a_n a1,a2,⋯,an,对 0 0 0值做LWE加密,有: E s ( 0 ) = ( a 1 , a 2 , ⋯ , a n , [ ∑ i a i s i + 0 + ϵ ] 1 ) E_s(0)=(a_1,a_2,\cdots,a_n,[\sum_i a_is_i+0+\epsilon]_1) Es(0)=(a1,a2,⋯,an,[∑iaisi+0+ϵ]1)
- 基于私钥 s s s和均匀随机值 a 1 , a 2 , ⋯ , a n a_1,a_2,\cdots,a_n a1,a2,⋯,an,对 0 0 0值做LWE加密,有: E s ( 1 ) = ( a 1 , a 2 , ⋯ , a n , [ ∑ i a i s i + 1 2 + ϵ ] 1 ) E_s(1)=(a_1,a_2,\cdots,a_n,[\sum_i a_is_i+\frac{1}{2}+\epsilon]_1) Es(1)=(a1,a2,⋯,an,[∑iaisi+21+ϵ]1)
当有密文 E s ( m ) = ( a 1 , a 2 , ⋯ , a n , b ) E_s(m)=(a_1,a_2,\cdots,a_n,b) Es(m)=(a1,a2,⋯,an,b),基于私钥 s s s对其解密:
- 当 m = 0 m=0 m=0时,有 [ b − ∑ i a i s i ] 1 ≈ 0 [b-\sum_i a_is_i]_1\approx 0 [b−∑iaisi]1≈0。
- 当 m = 1 m=1 m=1时,有 [ b − ∑ i a i s i ] 1 ≈ 1 2 [b-\sum_i a_is_i]_1\approx \frac{1}{2} [b−∑iaisi]1≈21。
同时其满足加法同态属性:
-
[
E
s
(
m
1
)
+
E
s
(
m
2
)
]
1
=
E
s
(
m
1
⊕
m
2
)
[E_s(m_1)+E_s(m_2)]_1=E_s(m_1\oplus m_2)
[Es(m1)+Es(m2)]1=Es(m1⊕m2)。
当明文 m m m为modular integers时,即 m ∈ Z q m\in\mathbb{Z}_q m∈Zq,其LWE加密为:
- 先将其编码为 μ = m q \mu=\frac{m}{q} μ=qm。
- 然后使用上面bits方法来加密。
- 也具有加法同态属性:
[
E
s
(
m
1
)
+
E
s
(
m
2
)
]
1
=
E
s
(
[
m
1
⊕
m
2
]
q
)
[E_s(m_1)+E_s(m_2)]_1=E_s([m_1\oplus m_2]_q)
[Es(m1)+Es(m2)]1=Es([m1⊕m2]q)。
当明文 x x x为实数时,即 x ∈ ( x m i n , x m a x ) x\in(x_{min},x_{max}) x∈(xmin,xmax),其LWE加密为:
- 先将其编码为 μ = margin + ( 1 − 2 margin ) ( x − x m i n x m a x − x m i n ) \mu=\text{margin}+(1-2\text{ margin})(\frac{x-x_{min}}{x_{max}-x_{min}}) μ=margin+(1−2 margin)(xmax−xminx−xmin)
- 然后使用上面bits方法来加密。
附录B:RLWE加密
所谓polynomial ring ( R / Z ) [ X ] / ( X N + 1 ) (\mathbb{R}/\mathbb{Z})[X]/(X^N+1) (R/Z)[X]/(XN+1),是指:
- [ ⋅ ] 1 [\cdot]_1 [⋅]1中,对应为多项式 a ( X ) = a 0 + a 1 X + a 2 X 2 + ⋯ + a N − 1 X N − 1 a(X)=a_0+a_1X+a_2X^2+\cdots+a_{N-1}X^{N-1} a(X)=a0+a1X+a2X2+⋯+aN−1XN−1,其中 N = 2 d N=2^d N=2d
- 然后整个多项式运算做模 ( X N + 1 , 1 ) (X^N+1, 1) (XN+1,1)
- 具有Negacyclic(负循环属性):
对某明文 μ ( X ) ∈ ( R / Z ) [ X ] / ( X N + 1 ) \mu(X)\in (\mathbb{R}/\mathbb{Z})[X]/(X^N+1) μ(X)∈(R/Z)[X]/(XN+1)的RLWE加密为:
- 对应私钥也为多项式,系数为二进制系数: s ( X ) = ( s 1 ( X ) , s 2 ( X ) , ⋯ , s k ( X ) ) s(X)=(s_1(X), s_2(X),\cdots,s_k(X)) s(X)=(s1(X),s2(X),⋯,sk(X))
- 采用的随机值以及噪声也为多项式表示。
- 等价为
k
N
kN
kN维度的LWE。
FHE系列博客
- 技术探秘:在RISC Zero中验证FHE——由隐藏到证明:FHE验证的ZK路径(1)
- 基于[Discretized] Torus的全同态加密指引(1)
- 基于[Discretized] Torus的全同态加密指引(2)
- TFHE——基于[Discretized] Torus的全同态加密 代码解析
- 技术探秘:在RISC Zero中验证FHE——RISC Zero应用的DevOps(2)
- FHE简介
- Zama TFHE-rs
- Zama TFHE-rs白皮书(1)
- Zama TFHE-rs白皮书(2)
- ZK系统内隐私 VS. FHE系统内隐私
- ZK vs FHE
- FHE全同态加密简介
- FHE与TEEs区别:Downfall攻击
- Greco:使用ZKP来证明FHE参与方的RLWE密文格式正确
- FHE入门
- Verifieable FHE(VFHE):使用Plonky2来证明Zama TFHE的“Bootstrapping的正确执行”
- FHE全同态加密介绍——小白版