ZKAttest的主要目的是解决 WebAuthn attestion中的隐私问题,使其可成为CAPTCHA: Using Hard AI Problems for Security 的替代方案。
前序博客有:
- ZKAttest: Ring and Group Signatures for existing ECDSA keys 学习笔记
代码为:
- https://github.com/cloudflare/zkp-ecdsa(TypeScript)
详细的测试用例见test
目录。
可参看:基于Sigma protocol实现的零知识证明protocol集锦 第2.1节内容。
针对的场景为:
- public info: C 1 = g x h r 1 , C 2 = g y h r 2 , g , h C_1=g^xh^{r_1},C_2=g^yh^{r_2},g,h C1=gxhr1,C2=gyhr2,g,h
- witness: x , y , r 1 , r 2 x,y,r_1,r_2 x,y,r1,r2
- relation: x = y x=y x=y
证明过程为:
- Prover:选择随机数 k , s 1 , s 2 k,s_1,s_2 k,s1,s2,构建 A 1 = g k h s 1 , A 2 = g k h s 2 A_1=g^kh^{s_1},A_2=g^kh^{s_2} A1=gkhs1,A2=gkhs2,将 A 1 , A 2 A_1,A_2 A1,A2发送给Verifier。
- Verifier:发送challenge c c c。
- Prover:计算 t x = k − c x , t r 1 = s 1 − c r 1 , t r 2 = s 2 − c r 2 t_x=k-cx,t_{r1}=s_1-cr_1,t_{r2}=s_2-cr_2 tx=k−cx,tr1=s1−cr1,tr2=s2−cr2,将 t x , t r 1 , t r 2 t_x,t_{r1},t_{r2} tx,tr1,tr2发送给Verifier。
- Verifier:验证 g t x h t s 1 = A 1 − C 1 c g^{t_x}h^{t_{s1}}=A_1-C_1^{c} gtxhts1=A1−C1c 且 g t x h t s 2 = A 2 − C 2 x g^{t_{x}}h^{t_{s2}}=A_2-C_2^{x} gtxhts2=A2−C2x 均成立,则可说明 x = y x=y x=y。
详细代码实现参见proveEquality
和verifyEquality
。
可参看:基于Sigma protocol实现的零知识证明protocol集锦 第2.9节内容。
参见博客 Hyrax: Doubly-efficient zkSNARKs without trusted setup学习笔记 Wahby 等人2018年论文《Hyrax: Doubly-efficient zkSNARKs without trusted setup》中Figure 5。
Witness: x , y , z , r x , r y , r z ∈ Z p x,y,z,r_x,r_y,r_z\in\mathbb{Z}_p x,y,z,rx,ry,rz∈Zp Instance: C x , C y , C z , g , h ∈ G C_x,C_y,C_z,g,h\in\mathbb{G} Cx,Cy,Cz,g,h∈G Relation: x y = z ∧ C x = g x h r x ∧ C y = g y h r y ∧ C z = g z h r z xy=z\wedge C_x=g^xh^{r_x}\wedge C_y=g^yh^{r_y}\wedge C_z=g^{z}h^{r_z} xy=z∧Cx=gxhrx∧Cy=gyhry∧Cz=gzhrz
具体实现为:【实际代码中的证明过程如下,不如Wahby 等人2018年论文《Hyrax: Doubly-efficient zkSNARKs without trusted setup》中Figure 5的算法。Wahby中的算法更简洁,proof size更小。】
- Prover:计算 C 4 = C y x , r 4 = r y x C_4=C_y^{x}, r_4=r_yx C4=Cyx,r4=ryx。生成随机数 k x , k y , k z ∈ R Z p k_x,k_y,k_z\in_R\mathbb{Z}_p kx,ky,kz∈RZp,,计算commitment A x = g k x h s x , A y = g k y h s y , A z = g k z h s z , A 4 1 = g k z h s 4 , A 4 2 = C y k x A_x=g^{k_x}h^{s_{x}},A_y=g^{k_y}h^{s_{y}},A_z=g^{k_z}h^{s_{z}},A4_1=g^{kz}h^{s_{4}}, A4_2=C_y^{k_x} Ax=gkxhsx,Ay=gkyhsy,Az=gkzhsz,A41=gkzhs4,A42=Cykx,将 C 4 , A x , A y , A z , A 4 1 , A 4 2 ∈ G C_4,A_x,A_y,A_z,A4_1,A4_2\in\mathbb{G} C4,Ax,Ay,Az,A41,A42∈G发送给Verifier。
- Verifier:给Prover 发送 random challenge c ∈ R Z p c\in_R\mathbb{Z}_p c∈RZp。
- Prover:计算 t x = k x − c x , t y = k y − c y , t z = k z − c z , t r x = s x − c r x , t r y = s y − c r y , t r z = s z − c r z , t r 4 = s 4 − c r 4 t_x=k_x-cx,t_y=k_y-cy,t_z=k_z-cz,t_{rx}=s_x-cr_x,t_{ry}=s_y-cr_y,t_{rz}=s_z-cr_z,t_{r4}=s_4-cr_4 tx=kx−cx,ty=ky−cy,tz=kz−cz,trx=sx−crx,try=sy−cry,trz=sz−crz,tr4=s4−cr4,将 t x , t y , t z , t r x , t r y , t r z , t r 4 ∈ Z p t_x,t_y,t_z,t_{rx},t_{ry},t_{rz},t_{r4}\in\mathbb{Z}_p tx,ty,tz,trx,try,trz,tr4∈Zp发送给Verifier。
- Verifier:验证 g t x h t r x = A x − c C x , g t y h t r y = A y − c C y , g t z h t r z = A z − c C z , g t z h t r 4 = A 4 1 − c C 4 , C y t x = A 4 2 − c C 4 g^{t_x}h^{t_{rx}}=A_x-cC_x,g^{t_y}h^{t_{ry}}=A_y-cC_y,g^{t_z}h^{t_{rz}}=A_z-cC_z,g^{t_z}h^{t_{r4}}=A4_1-cC_4,C_y^{t_x}=A4_2-cC_4 gtxhtrx=Ax−cCx,gtyhtry=Ay−cCy,gtzhtrz=Az−cCz,gtzhtr4=A41−cC4,Cytx=A42−cC4 成立即可。
详细代码实现参见proveMult
和verifyMult
。
实际代码实现中,provePointAdd
必需限制
P
≠
Q
P\neq Q
P=Q以及
P
=
−
Q
P=-Q
P=−Q这两种场景。
详细算法参见:ZKAttest: Ring and Group Signatures for existing ECDSA keys 学习笔记 中第2节。
2.4 Proof of Scalar Multiplication & Proof of ECDSA Signature详细算法参见:ZKAttest: Ring and Group Signatures for existing ECDSA keys 学习笔记 中第3节。
具体实现参见proveExp
和verifyExp
。实际代码实现结合 Agrawal等人2018年论文《Non-interactive zero-knowledge proofs for composite statements》第14页Figure 2中算法来看更直观,只是在该算法的基础上,Verifier增加了验证
z
1
g
+
z
2
h
+
C
1
=
a
1
z_1g+z_2h+C_1=a_1
z1g+z2h+C1=a1:
let T1 = paramsNIST.g.mul(resp.z)
const relA = new Relation(paramsNIST.c)
relA.insertM(
[T1, Clambda, pi[i].A.neg(), paramsNIST.h],
[
paramsNIST.c.newScalar(BigInt(1)),
paramsNIST.c.newScalar(BigInt(1)),
paramsNIST.c.newScalar(BigInt(1)),
resp.z2,
]
)
relA.drain(multiN)
当用于Proof of ECDSA signature,可引申为:【增加了一个可配置参数 Q Q Q】
sigProof = await proveExp(paramsSigExp, params.ProofGroup, s1, comS1, pkPoint, pkX, pkY, params.SecLevel, Q),
2.5 Proof of Membership
详细算法参见:ZKAttest: Ring and Group Signatures for existing ECDSA keys 学习笔记 中第6节。
具体代码实现见proveMembership
和verifyMembership
。
Proof of Ring Signature 可拆分为2部分:
- Proof of Scalar Multiplication;
- Proof of Membership。
具体代码实现见proveSignatureList
和verifySignatureList
。