Sigma protocols,又称为 3 phase protocols,用于证明knowledge of values in some relation,但是又不泄露values的具体值。
如用于证明knowledge of discrete log:given g g g and y y y,prove knowledge of x x x 满足 g x = y g^x=y gx=y without revealing x x x。
本文将介绍如何构建Sigma protocols来证明各种关系,如:
同时提供了Python 代码示例,用于说明在elliptic curves 上如何实现相应的构建。
以proof of knowledge of discrete log 为例:( y = g x y=g^x y=gx)
Witness: x x x
Instance: y y y和 g g g
Sigma protocol可分三步描述:
1)Commitment:
The prover generates a random number, creates a commitment to that randomness and sends the commitment to the verifier.
2)Challenge:
After getting the commitment, the verifier generates a random number as a challenge and sends it to the prover. It is important that the verifier does not send the challenge before getting the commitment or else the prover can cheat.
3)Response:
The prover takes the challenge and creates a response using the random number chosen in step 1), the challenge and the witness. The prover will then send the response to the verifier who will do some computation and will or will not be convinced of the knowledge of the witness.
以上描述的Sigma protocol为interactive protocol,要求Prover和Verifier必须同时在线,且能相互发送消息来完成整个流程。利用Fiat-Shamir heuristic,可将其转化为non-interactive:即不需要Verifier在第2步中发送challenge,Prover自己模拟一个challenge(by using a hash function to hash something specific to this protocol execution. 该hash函数的输入可为:如第1步中生成的commitment以及其它instance数据。)在non-interactive protocol中,Prover可以创建proof,而任意的Verifier都可以verify the proof。
仍以proof of knowledge of discrete log 为例:( y = g x y=g^x y=gx)【该协议也可称为Schnorr identification protocol或Schnorr protocol。】
1)Commitment:
Prover选择随机数 r r r,创建commitment t = g r t=g^r t=gr,将 t t t值发送给Verifier。
2)Challenge:
Verifier存储 t t t值,生成随机challenge c c c,将 c c c值发送给Prover。
3)Response:
Prover根据收到的challenge c c c值,创建response s = r + x ∗ c s=r+x*c s=r+x∗c,将 s s s值发送给Verifier。
Verifier只需要验证 g s = y c ∗ t g^s=y^c*t gs=yc∗t成立,即可相信Prover确实知道相应的 x x x使得 y = g x y=g^x y=gx成立。
每次生成proof时,Prover都应选择不同的新的随机数 r r r,否则会造成 x x x泄露。
具体为:
1.1)Prover:选择随机数 r r r,计算 t = g r t=g^r t=gr,将 t t t发送给Verifier;
1.2)Verifier:存储 t t t,发送challenge c 1 c_1 c1给Prover;
1.3)Prover:根据 r r r和 c 1 c_1 c1,计算response s 1 = r + c 1 ∗ x s_1=r+c_1*x s1=r+c1∗x,将 s 1 s_1 s1发送给Verifier。
2.1)Prover:仍然选择相同的随机数 r r r,计算 t = g r t=g^r t=gr,将 t t t发送给Verifier;
2.2)Verifier:存储 t t t,发送challenge c 2 c_2 c2给Prover;
2.3)Prover:根据 r r r和 c 1 c_1 c1,计算response s 2 = r + c 2 ∗ x s_2=r+c_2*x s2=r+c2∗x,将 s 1 s_1 s1发送给Verifier。
若Prover采用了相同的随机数 r r r,则Verifier根据收到的 s 1 s_1 s1和 s 2 s_2 s2,可计算出 x = ( s 1 − s 2 ) / ( c 1 − c 2 ) x=(s_1-s_2)/(c_1-c_2) x=(s1−s2)/(c1−c2),从而造成 witness x x x 的泄露。
Prover应无法预测challenge c c c,否则Prover可在不知道witness x x x的情况下,伪造证明使Verifier信服。
正常情况下,若Prover应无法预测challenge c c c,Verifier根据其收到的 s ( = r + c ∗ x ) s(=r+c*x) s(=r+c∗x),验证 g s = y c ∗ t g^s=y^c*t gs=yc∗t成立,则可认为Prover确实知道witness x x x 使得 y = g x y=g^x y=gx成立。
但是,若Prover可预测到challenge c c c值,则其在构建 t t t时不再是基于随机数 r r r,而是可以直接计算 t = y − c ∗ g s t=y^{-c}*g^s t=y−c∗gs(不需要 x x x参与计算),使得 g s = y c ∗ t g^s=y^c*t gs=yc∗t恒成立。
利用Fiat-Shamir heuristic,Prover使用hash function Hash
来生成相应的challenge c c c(应保证Prover无法预测Hash
函数的输出,否则如1.2.2节所示Prover可以作弊。)。
non-interactive protocol可让Verifier不再需要生成随机数 c c c,使得Verifier的实现更简单。
non-interactive的详细实现为:
Verifier根据收到的 t t t和instance g , y g,y g,y,利用相同的Hash函数计算 c = H a s h ( g , y , t ) c=Hash(g,y,t) c=Hash(g,y,t),再结合收到的 s s s,验证 g s = y c ∗ t g^s=y^c*t gs=yc∗t是否成立即可。
实际实现时, t t t的size可能要远远大于 c c c和 s s s的size(注意: t t t为group element, c 和 s c和s c和s 为field element)。为了降低传输压力,Prover发送 ( t , s ) (t,s) (t,s)可改为发送 ( c , s ) (c,s) (c,s)。调整为:
Verifier根据收到的 ( c , s ) (c,s) (c,s),假设 g s = y c ∗ t g^s=y^c*t gs=yc∗t成立,计算 t ( = g s ∗ y − c ) t(=g^s*y^{-c}) t(=gs∗y−c),利用 t , g , y t,g,y t,g,y作为相同hash函数的输入,计算 c ’ = h a s h ( g , y , t ) c’=hash(g,y,t) c’=hash(g,y,t),验证 c = c ’ c=c’ c=c’是否成立即可。
以上non-interactive protocol即是Schnorr signatures的核心思想。可将Schnorr signature看作是proof of knowledge of secret key corresponding to a public key ( x x x in g x g^x gx),而被签名的消息 m m m增加作为hash函数的输入,以此来生成challenge。(the message being signed is just hashed in the challenge in addition to other stuff we saw above.)
(可参见博客 Schnorr signature (Schnorr 签名)数学原理)
以下罗列了一些基于Sigma protocol实现的基础关系证明,主要针对的是non-interactive场景。
证明Prover知道witness x x x,使得 g x = y 且 h x = z g^x=y且h^x=z gx=y且hx=z。
Witness: x x x
Instance: g , h , y , z g,h,y,z g,h,y,z
Relation: g x = y g^x=y gx=y且 h x = z h^x=z hx=z
具体实现可为:
1)Prover:
2)Verifier:
证明Prover知道witness a , b a,b a,b,使得 g a = P 且 h b = Q g^a=P且h^b=Q ga=P且hb=Q。
Witness: a , b a,b a,b
Instance: g , h , P , Q g,h,P,Q g,h,P,Q
Relation: g a = P 且 h b = Q g^a=P且h^b=Q ga=P且hb=Q
具体实现可为:【相当于并行执行2个 ”knowledge of discrete log” protocol】
1)Prover:
2)Verifier:
证明Prover知道witness a a a使得 g a = P g^a=P ga=P,或者,知道witness b b b使得 h b = Q h^b=Q hb=Q,但是,无法同时知道 a , b a,b a,b使得 g a = P 且 h b = Q g^a=P且h^b=Q ga=P且hb=Q同时成立。
不能暴露Prover到底知道的是 a a a还是 b b b。
假设Prover仅知道 a a a使得 g a = P g^a=P ga=P【<1>,可诚信证明】,而不知道 b b b使得 h b = Q h^b=Q hb=Q【<2>,需伪造证明】,具体实现可为:
1)Prover:
2)Verifier:
可同时验证 g s 1 = P c 1 ∗ t 1 g^{s_1}=P^{c_1}*t_1 gs1=Pc1∗t1和 h s 2 = Q c 2 ∗ t 2 h^{s_2}=Q^{c_2}*t_2 hs2=Qc2∗t2均成功,由于Verifier 可计算 c = H a s h ( g , h , P , Q , t 1 , t 2 ) c=Hash(g,h,P,Q,t_1,t_2) c=Hash(g,h,P,Q,t1,t2),其收到的 c 1 , c 2 c_1,c_2 c1,c2满足 c 1 + c 2 = c c_1+c_2=c c1+c2=c,相比于2.2节的AND proof,Verifier可确信Prover确实知道 a a a OR b b b。
Jan Camenisc等人1997年论文《Proof Systems for General Statements about Discrete Logarithms》中,也有一些证明方案(参见博客 密码学中的sigma-protocol 第2节中提到的OR证明。),其中的OR证明【repsonse格式改为 s = r − c ∗ x s=r-c*x s=r−c∗x格式】,Prover发送给Verifier的内容调整为了 ( c 1 , c 2 , s 1 , s 2 ) (c_1,c_2,s_1,s_2) (c1,c2,s1,s2);Verifier计算 t 1 = g s 1 P c 1 , t 2 = h s 2 Q c 2 t_1=g^{s_1}P^{c_1},t_2=h^{s_2}Q^{c_2} t1=gs1Pc1,t2=hs2Qc2,同时验证 c 1 + c 2 = H ( g , h , P , Q , t 1 , t 2 ) c_1+c_2=H(g,h,P,Q,t_1,t_2) c1+c2=H(g,h,P,Q,t1,t2)是否成立即可。具体为:
1)Prover:
2)Verifier:
计算 t 1 = g s 1 P c 1 , t 2 = h s 2 Q c 2 t_1=g^{s_1}P^{c_1},t_2=h^{s_2}Q^{c_2} t1=gs1Pc1,t2=hs2Qc2,同时验证 c 1 + c 2 = H ( g , h , P , Q , t 1 , t 2 ) c_1+c_2=H(g,h,P,Q,t_1,t_2) c1+c2=H(g,h,P,Q,t1,t2)是否成立即可。相比于2.2节的AND proof,Verifier可确信Prover确实知道 a a a OR b b b。
Pedersen commitment: P = C o m ( m ; r ) = g m h r P=Com(m;r)=g^mh^r P=Com(m;r)=gmhr,其中 ( m , r ) (m,r) (m,r)称为the opening of the commitment。
证明Prover知道witness ( m , r ) (m,r) (m,r),使得 P = g m ∗ h r P=g^m*h^r P=gm∗hr。
Witness: m , r m,r m,r
Instance: g , h , P g,h,P g,h,P
Relation: P = g m ∗ h r P=g^m*h^r P=gm∗hr
具体实现可为:
1)Prover:
2)Verifier:
若将上述流程用于证明vector Pedersen commitment P = g 1 m 1 ∗ g 2 m 2 ∗ ⋯ ∗ g n m n ∗ h r P=g_1^{m_1}*g_2^{m_2}*\cdots *g_n^{m_n}*h^r P=g1m1∗g2m2∗⋯∗gnmn∗hr,则相应Prover发送给Verifier的内容长度为 Θ ( n ) \Theta(n) Θ(n)—— ( t , s 1 , s 2 , ⋯ , s n , s n + 1 ) (t,s_1,s_2,\cdots,s_n,s_{n+1}) (t,s1,s2,⋯,sn,sn+1)。
证明Prover知道witness ( a , b ) (a,b) (a,b),使得 P = g 1 a ∗ h 1 b 且 Q = g 2 a ∗ h 2 b P=g_1^a*h_1^b且Q=g_2^a*h_2^b P=g1a∗h1b且Q=g2a∗h2b。
Witness: a , b a,b a,b
Instance: g 1 , h 1 , g 2 , h 2 , P , Q g_1,h_1,g_2,h_2,P,Q g1,h1,g2,h2,P,Q
Relation: P = g 1 a ∗ h 1 b 且 Q = g 2 a ∗ h 2 b P=g_1^a*h_1^b且Q=g_2^a*h_2^b P=g1a∗h1b且Q=g2a∗h2b
具体实现可为:
1)Prover:
2)Verifier:
(?没想明白,咋用于vector Pedersen commitment或more than 2 Pedersen commitments呢??)
证明Prover知道witness ( a , b , d ) (a,b,d) (a,b,d),使得 P = g 1 a ∗ h 1 b 且 Q = g 2 a ∗ h 2 d P=g_1^a*h_1^b且Q=g_2^a*h_2^d P=g1a∗h1b且Q=g2a∗h2d。
Witness: a , b , d a,b,d a,b,d
Instance: g 1 , h 1 , g 2 , h 2 , P , Q g_1,h_1,g_2,h_2,P,Q g1,h1,g2,h2,P,Q
Relation: P = g 1 a ∗ h 1 b 且 Q = g 2 a ∗ h 2 d P=g_1^a*h_1^b且Q=g_2^a*h_2^d P=g1a∗h1b且Q=g2a∗h2d
具体实现可为:
1)Prover:
2)Verifier:
注意:whenever we prove some witness values are the same across different relations, the same random value is used in their corresponding commitments。如上,P和Q的 a a a相同,则构建的commitment t 1 和 t 2 t_1和t_2 t1和t2中的 r 1 r_1 r1应相同。
可参看博客 Hyrax: Doubly-efficient zkSNARKs without trusted setup学习笔记 3.3节中的“proof of commitment to the same value”,所构建的证明算法proof size更小:
该协议首次在Jan Camenisch和Victor Shoup 2003年论文《Practical Verifiable Encryption and Decryption of Discrete Logarithms∗》中第6节提及。
证明Prover知道witness ( a ) (a) (a),使得 P = g a , Q = h b , 且 a ≠ b P=g^a,Q=h^b,且a\neq b P=ga,Q=hb,且a=b。
Witness: a a a
Instance: g , h , P , Q g,h,P,Q g,h,P,Q
Relation: P = g a , Q = h b , 且 a ≠ b P=g^a,Q=h^b,且a\neq b P=ga,Q=hb,且a=b
具体实现可为:
1)Prover:
2)Verifier:
在示例代码 中,采用的Elliptic curve,其中 1 1 1对应的是the identity element (the point at infinity) on the curve。
def verify_discrete_log_inequality(g, h, P, Q, C, t1s1, t2s2):
if C.is_identity:
return False
# iden is the identity element so adding or subtracting it from something makes no difference
iden = C - C
return verify_knowledge_and_eq_of_opening_of_pedersen_commitments(g, P, h, Q, iden, C, t1s1, t2s2)
Dan Boneh 的视频解说 Discrete Log based Zero-Knowledge Proofs 中提到,可将Sigma protocol看成是prove knowledge of a homomorphism pre-image (其中 p r e − i m a g e pre-image pre−image为函数输入, i m a g e image image为函数输出)。
homomorphism同态性,如 g a + b = g a ∗ g b g^{a+b}=g^a*g_b ga+b=ga∗gb可认为具有加法同态性。
homomorphism可定义为a function f f f,where f ( a ) = g a f(a)=g^a f(a)=ga. To prove the knowledge of a a a, given common input f ( a ) f(a) f(a)(如 g a g^a ga),则具体的protocol可描述为:
1)Prover:生成随机数 r r r,发送 f ( r ) = g r f(r)=g^r f(r)=gr给Verifier;
2)Verifier:发送challenge c c c给Prover;
3)Prover:发送response s = r + c ∗ a s=r+c*a s=r+c∗a;
4)Verifier:计算 f ( s ) = g s f(s)=g^s f(s)=gs,验证 f ( s ) = f ( r ) ∗ f ( a ) c f(s)=f(r)*f(a)^c f(s)=f(r)∗f(a)c是否成立即可。
定义homomorphism函数为 f ( a ) = ( g a , h a ) f(a)=(g^a,h^a) f(a)=(ga,ha)。
证明Prover知道witness x x x,使得 g x = y 且 h x = z g^x=y且h^x=z gx=y且hx=z。
Witness: x x x
Instance: g , h , y , z g,h,y,z g,h,y,z
Relation: g x = y g^x=y gx=y且 h x = z h^x=z hx=z
具体实现可为:
1)Prover:生成随机数 r r r,发送 f ( r ) = ( g r , h r ) f(r)=(g^r,h^r) f(r)=(gr,hr) 给Verifier;
2)Verifier:发送challenge c c c给Prover;
3)Prover:发送response s = r + c ∗ a s=r+c*a s=r+c∗a;
4)Verifier:计算 f ( s ) = ( g s , h s ) f(s)=(g^s,h^s) f(s)=(gs,hs),验证 f ( s ) = f ( r ) ∗ f ( a ) c f(s)=f(r)*f(a)^c f(s)=f(r)∗f(a)c是否成立即可。
定义homomorphism函数为 f ( a , b ) = ( g a , h b ) f(a,b)=(g^a,h^b) f(a,b)=(ga,hb)。
证明Prover知道witness a , b a,b a,b,使得 g a = P 且 h b = Q g^a=P且h^b=Q ga=P且hb=Q。
Witness: a , b a,b a,b
Instance: g , h , P , Q g,h,P,Q g,h,P,Q
Relation: g a = P 且 h b = Q g^a=P且h^b=Q ga=P且hb=Q
具体实现可为:【相当于并行执行2个 ”knowledge of discrete log” protocol】
1)Prover:生成2个随机数 r 1 , r 2 r_1,r_2 r1,r2,发送 f ( r 1 , r 2 ) = ( g r 1 , h r 2 ) f(r_1,r_2)=(g^{r_1},h^{r_2}) f(r1,r2)=(gr1,hr2)给Verifier;
2)Verifier:发送challenge c c c给Prover;
3)Prover:发送response ( s 1 , s 2 ) (s_1,s_2) (s1,s2),其中 s 1 = r 1 + c ∗ a , s 2 = r 2 + c ∗ b s_1=r_1+c*a,s_2=r_2+c*b s1=r1+c∗a,s2=r2+c∗b;
4)Verifier:计算 f ( s 1 , s 2 ) = ( g s 1 , h s 2 ) f(s_1,s_2)=(g^{s_1},h^{s_2}) f(s1,s2)=(gs1,hs2),验证 f ( s 1 , s 2 ) = f ( r 1 , r 2 ) ∗ f ( a , b ) c f(s_1,s_2)=f(r_1,r_2)*f(a,b)^c f(s1,s2)=f(r1,r2)∗f(a,b)c是否成立即可。
定义homomorphism函数为 f ( m , r ) = g m ∗ h r f(m,r)=g^m*h^r f(m,r)=gm∗hr。
证明Prover知道witness ( m , r ) (m,r) (m,r),使得 P = g m ∗ h r P=g^m*h^r P=gm∗hr。
Witness: m , r m,r m,r
Instance: g , h , P g,h,P g,h,P
Relation: P = g m ∗ h r P=g^m*h^r P=gm∗hr
具体实现可为:
1)Prover:生成2个随机数 r 1 , r 2 r1,r_2 r1,r2,发送 f ( r 1 , r 2 ) = g r 1 ∗ h r 2 f(r_1,r_2)=g^{r_1}*h^{r_2} f(r1,r2)=gr1∗hr2给Verifier;
2)Verifier:发送challenge c c c给Prover;
3)Prover:发送response ( s 1 , s 2 ) (s_1,s_2) (s1,s2),其中 s 1 = r 1 + c ∗ m , s 2 = r 2 + c ∗ r s_1=r_1+c*m,s_2=r_2+c*r s1=r1+c∗m,s2=r2+c∗r;
4)Verifier:计算 f ( s 1 , s 2 ) = g s 1 ∗ h s 2 f(s_1,s_2)=g^{s_1}*h^{s_2} f(s1,s2)=gs1∗hs2,验证 f ( s 1 , s 2 ) = f ( r 1 , r 2 ) ∗ f ( m , r ) c f(s_1,s_2)=f(r_1,r_2)*f(m,r)^c f(s1,s2)=f(r1,r2)∗f(m,r)c是否成立即可。
Dan Boneh 在2019年 2nd ZKProof Workshop 上的视频解说 Discrete Log based Zero-Knowledge Proofs
[1] Lovesh Harchandani 在medium的博客Zero Knowledge Proofs with Sigma Protocols
[2] Dan Boneh 的视频解说 Discrete Log based Zero-Knowledge Proofs