在part-1中,我们梳理了去中心纸牌游戏所面临的挑战,也介绍了一种改进的Barnett-Smart协议,part-2将深入了解该协议背后涉及的算法。
Discrete-log VTMF
VTMFs包含4部分:key generation, mask, remask and unmask,这些算法主要通过El Gamal加密算法来实现的。可验证性是通过零知识证明来实现的,主要用于证明加密和解密操作的正确性。
key generation
玩家i 随机选取私钥 x i ← Z q x_i \leftarrow Z_q xi←Zq , 计算相应公钥 H i = x i ⋅ G H_i = x_i \cdot G Hi=xi⋅G并公开(为抵抗rogue key attacks,要求每个玩家提供一个零知识证明,可以使用schnorr身份证明协议)
一旦所以玩家公开他们的公钥之后,我们可以计算一个聚合公钥 H H H,其中 l l l代表参与玩家总数
H = ∑ i l H i = ∑ i = 1 l x i G H= \sum_i^{l}H_i = \sum_{i=1}^{l}x_iG H=i∑lHi=i=1∑lxiG
Mask
用 ζ H \zeta_H ζH表示掩码函数, H H H表示聚合公钥, M ∈ G M \in G M∈G表示卡牌映射在群G上的元素,对 M M M进行mask得到密文 C ∈ G × G C\in G \times G C∈G×G, 其过程如下:
C = ζ H ( M , r ) = ( C a C b ) = ( r G M + r H ) C = \zeta_H(M,r) = \left( \begin{matrix} C_a \\ C_b \end{matrix} \right) = \left( \begin{matrix} rG \\ M + rH \end{matrix} \right) C=ζH(M,r)=(CaCb)=(rGM+rH)
这里 r ∈ Z q r \in Z_q r∈Zq被称为masking factor。通过计算 C b − r H C_b - rH Cb−rH 可以恢复卡牌, 所以r必须保密不可泄漏。
Remask
用 ζ H ′ \zeta_H' ζH′表示掩码函数, H H H表示聚合公钥,玩家随机选择 r ′ ← Z q r' \leftarrow Z_q r′←Zq,对掩码卡牌 C = ( C a C b ) C=\left( \begin{matrix} C_a \\ C_b \end{matrix} \right) C=(CaCb)进行重掩码:
C ′ = ζ H ′ ( C , r ′ ) = C + ( r ′ G r ′ H ) = ( C a + r ′ G C b + r ′ H ) C' = \zeta_H'(C,r') = C + \left( \begin{matrix} r' G \\ r' H \end{matrix} \right) = \left( \begin{matrix} C_a+r' G \\ C_b+r' H \end{matrix} \right) C′=ζH′(C,r′)=C+(r′Gr′H)=(Ca+r′GCb+r′H)
例如一局游戏有Alice、Bob和Charlie三个玩家,这三个玩家先后其对卡牌进行掩码和重掩码的过程如下:Alice首先用 α \alpha α去随机化卡牌M得到 C 1 C_1 C1,然后Bob用 β \beta β对 C 1 C_1 C1进行重掩码得到 C 2 C_2 C2,最后Charlie用 γ \gamma γ对 C 2 C_2 C2进行重掩码得到 C 3 C_3 C3。
C 1 = ζ H ( M , α ) = ( α G M + α H ) C 2 = ζ H ′ ( C 1 , β ) = C 1 + ( β G β H ) = ( ( α + β ) G M + ( α + β ) H ) C 3 = ζ H ′ ( C 2 , γ ) = C 2 + ( γ G γ H ) = ( ( α + β + γ ) G M + ( α + β + γ ) H ) \begin{align} & C_1 = \zeta_H(M,\alpha) = \left( \begin{matrix} \alpha G \\ M + \alpha H \end{matrix} \right) \\ & C_2 = \zeta_H' (C_1,\beta) =C_1 + \left( \begin{matrix} \beta G \\ \beta H \end{matrix} \right) = \left( \begin{matrix} (\alpha+\beta) G \\ M + (\alpha+\beta) H \end{matrix} \right) \\ & C_3 = \zeta_H' (C_2,\gamma) =C_2 + \left( \begin{matrix} \gamma G \\ \gamma H \end{matrix} \right) = \left( \begin{matrix} (\alpha+\beta +\gamma ) G \\ M + (\alpha+\beta+\gamma ) H \end{matrix} \right) \\ \end{align} C1=ζH(M,α)=(αGM+αH)C2=ζH′(C1,β)=C1+(βGβH)=((α+β)GM+(α+β)H)C3=ζH′(C2,γ)=C2+(γGγH)=((α+β+γ)GM+(α+β+γ)H)
在所有玩家完成上述掩码或重掩码过程后,实际上我们得到在masking factor为 α + β + ζ \alpha+\beta+\zeta α+β+ζ下的掩码卡牌,因此要恢复卡牌,需要每个玩家提供其所拥有的masking factor,还有另外一种方法不需要提供masking factor,见下面unmask过程。
Unmask
给定掩码卡牌 C = ( C a C b ) C=\left( \begin{matrix} C_a \\ C_b \end{matrix} \right) C=(CaCb),玩家i使用私钥计算 D i = x i C a D_i = x_iC_a Di=xiCa并公开,等待所有玩家公开之后,可以计算
M = C b − ∑ i = 1 l D i M = C_b - \sum_{i=1}^l D_i M=Cb−i=1∑lDi
Verifiability
上述操作(不包括密钥生成)的可验证性可以通过Chaum-Pedersen离散对数相等性证明来实现。在经典的sigma协议中, 给定 α G \alpha G αG和 β H \beta H βH, 证明者可以通过zero knowledge证明他知道 α \alpha α的值且 α = β \alpha = \beta α=β 。对于mask操作而言,需要证明和验证的是 c a c_a ca和 c b − M c_b -M cb−M对应 α = r \alpha =r α=r , 对于remask操作而言,需要证明和验证的是 c a ′ − c a c_a' -c_a ca′−ca和 c b ′ − c b c_b' -c_b cb′−cb对应 α = r ′ \alpha =r' α=r′ , 对于unmask操作来说,需要证明和验证的是 H i H_i Hi和 D i D_i Di对应 α = x i \alpha = x_i α=xi ,
ZK Shuffle
为了便于理解ZK Shuffle,假设存在一组群中元素 P 1 , P 2 , . . . , P N P_1,P_2,...,P_N P1,P2,...,PN ,这些元素经过置换再加上盲化因子 Δ i \Delta_i Δi后输出为:
P i ′ = P π ( i ) + Δ i P_i' = P_{\pi(i)} + \Delta_i Pi′=Pπ(i)+Δi
其中 π \pi π为置换函数,下面这张图展示了6个元素的置换过程:
为了有效地生成论证(argument),我们使用多项式等式来表示洗牌过程。然后,我们从domain上选择一个随机点,在该点打开多项式,并通过比较在该点的值是否相等来验证等式是否成立。其中一个多项式由验证者使用公开数据来计算,另外一个多项式由证明者使用秘密数据来计算。由于证明者不可信,还必须设计额外的arguments来确保证明者的多项式是正确计算的。
Shuffle as a Polynomial Equality
argument的核心是下面这个验证等式,给定一个挑战 z c ← Z q \ { 0 , 1 } z_c \leftarrow Z_q \backslash \{0,1\} zc←Zq\{0,1},验证者验证:
∑ i = 1 N z c i P i = ∑ i = 1 N z c π ( i ) ( P i ′ − Δ i ) \sum_{i=1}^{N}z_c^iP_i = \sum_{i=1}^{N}z_c^{\pi(i)}(P_{i}'-\Delta_i) i=1∑NzciPi=i=1∑Nzcπ(i)(Pi′−Δi)
等式左边可使用公开数据(shuffle的输入)和挑战计算,因此这部分验证者可以计算;而等式右边只能由证明者计算,因此它涉及到秘密置换 π \pi π和盲化因子 Δ i \Delta_i Δi。
注意到上述等式同两个多项式在点 z c z_c zc处打开的过程非常相似。我们可以用变量乘以生成元的形式来表示上述等式中的元素:
- 令 s i ∈ Z q s_i \in Z_q si∈Zq,则 P i = s i G P_i = s_iG Pi=siG
- 令 s i ′ ∈ Z q s_i ' \in Z_q si′∈Zq,则 P i ′ = s i ′ G P_i' = s_i'G Pi′=si′G
- 令 δ i ∈ Z q \delta_i \in Z_q δi∈Zq,则 Δ i = δ i G \Delta_i = \delta_iG Δi=δiG
用这些新的形式替换上面等式,得到:
( ∑ i = 1 N z c i s i ) G = ( ∑ i = 1 N z c π ( i ) ( s i ′ − δ i ) ) G (\sum_{i=1}^Nz_c^is_i)G = (\sum_{i=1}^Nz_c^{\pi(i)}(s_i'-\delta_i))G (i=1∑Nzcisi)G=(i=1∑Nzcπ(i)(si′−δi))G
考虑下面的多项式 f f f和 g g g,这两个多项式在 z c z_c zc处的打开值再乘以群的生成元就可以得到上面的等式:
f ( z ) = ∑ i = 1 N z i s i , g ( z ) = ∑ i = 1 N z π ( i ) ( s i ′ − δ i ) f(z) = \sum_{i=1}^Nz^is_i , g(z) = \sum_{i=1}^Nz^{\pi(i)}(s_i' - \delta^i) f(z)=i=1∑Nzisi,g(z)=i=1∑Nzπ(i)(si′−δi)
鉴于累加的顺序是可以交换的,则 f f f可以写成 f ( z ) = ∑ i = 1 N z π ( i ) s π ( i ) f(z) = \sum_{i=1}^Nz^{\pi(i)}s_{\pi(i)} f(z)=∑i=1Nzπ(i)sπ(i),实际上只是通过置换改变求和中每项的顺序,所以最后累加的结果不变。
f ( z ) = g ( z ) ⟺ ∑ i = 1 N z π ( i ) s π ( i ) = ∑ i = 1 N z π ( i ) ( s i ′ − δ i ) ⟺ ∀ i ∈ { 1 , 2 , . . . , N } , s π ( i ) = s i ′ − δ i ⟺ ∀ i ∈ { 1 , 2 , . . . , N } , P π ( i ) = P i ′ − Δ i f(z) =g(z) \Longleftrightarrow \sum_{i=1}^Nz^{\pi(i)}s_{\pi(i)} = \sum_{i=1}^Nz^{\pi(i)}(s_i' - \delta^i) \\ \Longleftrightarrow \forall i\in \{1,2,...,N\},s_{\pi(i)} = s_i' -\delta_i \\ \Longleftrightarrow \forall i\in \{1,2,...,N\},P_{\pi(i)} = P_i' -\Delta_i f(z)=g(z)⟺i=1∑Nzπ(i)sπ(i)=i=1∑Nzπ(i)(si′−δi)⟺∀i∈{1,2,...,N},sπ(i)=si′−δi⟺∀i∈{1,2,...,N},Pπ(i)=Pi′−Δi
很明显z不能等于 0 或 1,当且仅当shuffle过程是有效的,多项式 f f f和 g g g相等
Checking the Polynomial Equality
为了检查多项式相等,我们计算这两个多项式在点 z c ← Z q \ { 0 , 1 } z_c \leftarrow Z_q \backslash \{0,1\} zc←Zq\{0,1}处的打开值,然后检查 f ( z c ) = g ( z c ) f(z_c) =g(z_c) f(zc)=g(zc),然而这不能保证这两个多项式完全相等,Schwartz-Zippel 定理告诉我们大概以 1 − N Z q 1-\frac{N}{Z_q} 1−ZqN的概率趋于相等,其中 ∣ Z q ∣ > > N |Z_q|>>N ∣Zq∣>>N.
其次,我们也不能直接计算这两个多项式,因为我们不可能获取到 s π ( i ) 、 s i ′ , δ i s_{\pi(i)}、s_i',\delta_i sπ(i)、si′,δi这些秘密值,所以只能通过计算下面这个等式来验证:
∑ i = 1 N z c i P i = ∑ i = 1 N z c π ( i ) ( P i ′ − Δ i ) \sum_{i=1}^{N}z_c^iP_i = \sum_{i=1}^{N}z_c^{\pi(i)}(P_{i}'-\Delta_i) i=1∑NzciPi=i=1∑Nzcπ(i)(Pi′−Δi)
Ensuring the Prover Behaves Honestly
如前面所说,等式右边( ∑ i = 1 N z c π ( i ) ( P i ′ − Δ i ) \sum_{i=1}^{N}z_c^{\pi(i)}(P_{i}'-\Delta_i) ∑i=1Nzcπ(i)(Pi′−Δi))只能由不受信任的证明者进行计算,且不泄露任何隐私信息。我们通过承诺(commitments)和零知识证明(zero-knowledge arguments)来满足这些属性。
首先,证明者会对置换进行承诺,并通过zero knowledge证明他们按照已承诺的置换对挑战 z c z_c zc的幂进行了置换,最后验证者可以得到承 C z , π C_{z,\pi} Cz,π,其是对向量 [ z c π ( 1 ) , z c π ( 2 ) , . . . , z c π ( N ) ] [z_c^{\pi(1)},z_c^{\pi(2)},...,z_c^{\pi(N)}] [zcπ(1),zcπ(2),...,zcπ(N)]的承诺,这个向量可用于内积证明(inner-product argument),以生成可证明的期望值: ∑ i = 1 N z c π ( i ) ( P i ′ − Δ i ) \sum_{i=1}^N z_c^{\pi(i)}(P_{i}'-\Delta_i) ∑i=1Nzcπ(i)(Pi′−Δi)
这些arguments并不是平凡的(trivial),可能需要单独的文章来提供数学方面的理解。此外在《Efficient Zero-knowledge Argument for Correctness of a Shuffle》中提到的 inner-product argument和permutation argument后来也分别被Bulletproofs和PlonK采用和改进。
From Shuffling Group Elements to Shuffling Cards
请注意,以上讨论仅涉及对单个群元素进行洗牌,而不是对一个掩码卡牌(由两个群元素组成的密文)进行洗牌。然而,我们可以将上述过程扩展到掩码卡牌,这里推荐两种方式:
- 证明者分别在两组群元素上执行argument,同时要求证明对这两组元素使用相同的置换。这对于现有的argument structure是可行的,因为证明者已经承诺了一个置换并且证明了它的正确性。
- 将每张掩码卡牌视为群 H = G × G \mathbb{H} = G \times G H=G×G中的一个元素,并定义群 H \mathbb{H} H的操作。