密码协议学习笔记(8.15):知识证据详解

在开始前,先回顾以下的知识点:

离散对数问题(Discrete logarithm Problem,DLP)难解性猜想:

给定以大素数p为阶的循环群G,g,hG是两个生成元(在素数阶群上等价于非恒等元),求解t,使得ht=g在计算上是不可行的.

Diffie-Hellman的计算难解性(Computational Diffie-Hellman,CDH)猜想:

已知a,bZp但不知道其具体值,给定以大素数p为阶的循环群G,g是其生成元,只知道ga,gb的情况下,计算gab在计算上是不可行的.

Diffie-Hellman的判定难解性(Decisional Diffie-Hellman,DDH)猜想

已知a,b,cZp,但不知道其具体值,给定以大素数p为阶的循环群G,g是其生成元,对于如下两个四元组

(g,ga,gb,gc)

(g,ga,gb,gab)

以不可忽略的正确概率进行区分,在计算上是不可行的.

考虑如下的问题:

在以大素数p为阶的循环群G上,生成元g是公开信息,Alice的手中持有私钥s,现在Alice向Bob发送d1=gs,Alice要如何在不透露s具体是多少的前提下,证明d1就是以g为底,以s为指数的值呢?

思路:如果G的另一个生成元h是公开的(但没人知道g?=h),Bob持有另外一个值d2,并且Bob相信d2=hs,那么Alice可以使用以下的方法证明二者的指数相等(即loggd1=loghd2)

该方案需要使用一个Hash函数,记为H:{0,1}[0,p1],记||为字符串拼接操作(博主有时候在多个字符串拼接起来作为函数输入的情况下,会混用拼接符号与逗号,如f(||)f(,))

  1. 选取一个随机数ω[0,p1]
  2. 计算a=gω b=hω
  3. 计算c=H(d1||d2||a||b)
  4. 计算r=ωsc
  5. PROOF=(c,r)作为知识证据发送

Bob在收到知识证据后,计算

a=grd1c

b=hrd2c

c=H(d1||d2||a||b)

然后判断c=c是否成立,若成立,则认可d1有效(或者说,认可loggd1=loghd2)

实际上

a=grd1c=gωsc(gs)c=gω=a

b=hrd2c=hωsc(hs)c=hω=b

那么显然有

c=H(d1||d2||a||b)=H(d1||d2||a||b)=c

注意,两个生成元g,h之间的对数t=loghg不可公开(或者干脆随机生成g,h,我自己也不知道t是多少,嘿嘿).否则,如果有人知道了t,使得ht=g,那么它就可以在仅知道d2=hs的情况下,计算出(d2)t=(hs)t=hts=gs=d1

问题来了,如何让Bob在不知道s的情况下,相信自己手中的d2=hs呢?借助可信第三方TTP不失为一个办法,然而既然有了TTP,干嘛还需要知识证据呢?

下面看一个知识证据在PVSS(回顾密码协议学习笔记(8.1):秘密分享 - Isakovsky - 博客园 (cnblogs.com))里的应用:

在此方案中,验证者只需要认可加密的函数值(即Yi=yip(x))正确地来自于加密的系数(即Cj=gαj)构成的函数即可.

给定大质数分发者Deliver做如下工作,以加密的秘密碎片形式分发秘密碎片:

  1. 选取形如p(x)=α0+α1x+α2x2++αt1xt1的随机多项式,其中αi[1,p1]
  2. 计算出p(1),p(2),p(n)
  3. 计算s1,s2,,sn,其中si=hp(i)
  4. 使用参与者的公钥y1,y2,,yn计算并公开加密的秘密碎片Y1,Y2,,Yn,其中Yi=(yi)p(i)

为了达到加密的秘密碎片的公开可验证,Deliver需要进行以下操作:

  1. 计算并公开多项式p(x)的每个系数α0,α1,,αt1分别对应的公共承诺C0,C1,,Ct1,其中Cj=gαj
  2. 通过公共承诺计算出对每个成员P1,P2,,Pn私人承诺X1,X2,,Xn,其中Xi=Πj=0t1(Cj)(ij)=Πj=0t1(gαj)(ij)=gα0gα1igα2i2gαt1it1=gα0+α1i+α2i2++αt1it1=gp(i) 但私人承诺可以不必直接公开,实际上,公共承诺与私人承诺是等价的,因为任何人都可以通过公开的公共承诺,计算对某个成员的私人承诺.
  3. 选取随机数ω1,ω2,,ωn[0,p1]
  4. 计算a1,a2,,an,其中ai=gωi
  5. 计算b1,b2,,bn,其中bi=yiωi
  6. 计算公共质询值c=H(X1,X2,,Xn,Y1,Y2,,Yn,a1,a2,,an,b1,b2,,bn)
  7. 计算对成员P1,P2,,Pn应答r1,r2,,rn,其中ri=ωip(i)c
  8. PROOFD=(c,r1,r2,,rn)作为知识证据公开

获得Deliver的公开信息后,任何人想验证加密的秘密碎片Y1,Y2,,Yn的有效性,需要进行以下步骤:

在既不知道p(x)的表达式中的系数αj,也不知道任何一个p(i)的情况下,通过PROOFD,来确认Yi=yip(x)的确来自于Cj=gαj构成的函数

  1. 使用公共承诺自行计算出所有的私人承诺Xi=Πj=0t1(Cj)(ij)=gp(i)
  2. 观察Xi=gp(i),Yi=yip(i),因为Xi,Yi的底数g,yi均是已知的,只需要比较它们的指数是否相同,但由于离散对数问题的难解性,进行这样的比较需要借助知识证据PROOFD,并且绕几个弯:
    1. 计算所有的

      ai=gri(Xi)c=griXic=gωip(i)c(gp(i))c=gωi=ai

      bi=yiriYic=yiriYic=yiωip(i)c(yip(i))c=yiωi=bi

    2. 然后计算

      c=H(X1,X2,,Xn,Y1,Y2,,Yn,a1,a2,,an,b1,b2,,bn)

      如果c=c,则接受Deliver的所有输出为有效.

      不考虑哈希碰撞,显然c=c当且仅当Deliver正确运行了协议.

如此,验证者便对所有的Y1,Y2,,Yn建立了信任.

Yi不仅可以表示为Yi=yip(i),在参与者提交了Si之后,还可以表示为Yi=Sixi

而实际上,yi=hxi,h是公开的.

之后其他参与者Pi可用开头的方案将验证者对Yi的信任传递,,以让验证者确信,提交Si的自己确实掌握着xi

posted @   Isakovsky  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示