零知识证明(zero-Knowledge)是一个很杀的二进制,却一直笼罩着一层神秘的面纱。他的广告听起来很梦幻,在不透露任何资讯的表现下,要让别人百分百相信我的话真的这么神,去作电话诈骗会不会赚得比较快

零知识证明(zero-Knowledge)到底可以保护什么隐私资料怎么保护的了解这个基本的问题,才能知道他到底能作到什么,又有什么不能作的。

只看零知识证明很难,但很容易就可以证明。但文章要满到都是点诡异的数字符号,往往眼前一阵花,心下却一片茫然。自己零知识呀〜

其实要了解零知识证明的长像,最好的方式还是模仿,拿区块链的实际需求模仿。

没有秘密的区块链

区块链是个一切都都摊在阳光下的世界,所有的交易,其交易的双方,金额,一切的一切,都清清楚楚。一个典型的(但简化了的)交易长得像这样:

ps。0x0001的余额是1,500

会需要这么清楚,是为了让任何人(尤其是矿工)都能轻松验证这笔交易的正确性。我们会需要验证Bob(0x0001)至少拥有1000元才能送钱给Alice(0x0002)。目的,我们至少要知道

鲍勃(0x0001)目前的余额(1,500元) 这笔交易的金额(1,000元)

这样任何人(尤其是矿工),只要执行isValid函式就能确认这笔交易合法

但如此一来,一切的秘密就摊在阳光下了。每个人都知道0x0001的金流状况。区块链对0x0001的唯一保障只建立在你不知道0x0001就是鲍勃的这点上。

零知证的区块链

零知识证明想要解决这件事,它希望交易看起来是这样子的

ps。0x0001的余额是xxx

这里的,xxx是hash过的数字,分别代表1,000,1,500

问题是,你手上只有xxx和,要怎么确定xxx≥

这里就是零知识证明上场的地方了。我们不需要知道这些金额的实际数字(零知识),只需要知道isValid这个函式会传回真就可以了。

让我们重新一下这个函式

余额,金额是秘密,xxx,是hash过后的值。我们希望任何人在不知道balance,amount的状况下,可以相信这个函式会传回真。我们给这个函式一个代号C

现在来看一下zk的大致流程

阶段会产生二把钥匙,想要产生证明或验证证明的人,就会用到相应的钥匙

再介绍一下登场人物

C:上面介绍过的验证函式 P(prover):拥有某秘密,想要不揭露该秘密而证明某事的人。以本例来说是0x0001,他不想透露余额及金额,但希望矿工们相信C为真 V(验证者):验证人(矿工) w(witness):可以满足C的一组解(里面含有不能透露的秘密)。以本例来说w =(1500,1000,xxx,) x(public input):可以公开取得的资料,以本例来说x =(xxx,) π(证明):对证人作转换,将其中的秘密删除后就是证明 pk / vk:提供者密钥/验证者密钥,要产生或验证证明所用的密钥

证明阶段是这样的。Bob是送钱的人,他知道所有的资讯w =(1500,1000,xxx,)。其中一些是会公开在链上的,也就是x =(xxx, )。他用w,x和pk,产生一个证明,这个证明不会包含秘密(1500,1000)。但验证人(矿工)却可以用这个证明,搭配上已经在链上公开的x ,确认这个证明满足C的要求

以上就是zk的大致样貌了。瞧瞧,符号虽然多了些。但不过就是变数名称嘛

下一步…

但接下来的才是漫漫长路,有二个研究方向你可能要知道

首先,一切的重点似乎都在C。不同类型的证明,会需要不同的C。另一种类型的秘密,似乎也是写个相应的C就好了。

但是,C不是用JavaScript写的,也不是用C写的(喔喔,好巧)。事实上,C并不是程式语言,至少不是一个图灵完备的程式语言。有个工具叫ZoKrates可以提供一个迷你语言帮助您产生这组约束,但还不完完备,要写出实用的C目前只能透过一个c / c ++的库libsnark

第二个方向是,为什么验证人可以相信proof可以让C为真C需要秘密才能计算,但证明不包含秘密不是吗zk能把事情搞成这样,跟椭圆曲线pairing的一些性质有关。所以了解一下pairing也是不错的

同场加映…ethereum上的零知识证明

ethereum在大都会这个版本后,也号称支持了zk,但我怎么没瞧见呀每笔交易还是坦坦荡荡一清二楚的呀

那是留给smart contract去实践的。简言之,如果我想创造一个秘密的令牌,那我就必须自己实作合同来处理证明的验证。注意喔,smart contract只是拿来验证证明的。何以故因为完整的w只有用户(客户端)才会知道,如果要用合同来作证,那不是得把w送上链昭告天下

虽然验证合同要你自己写,但验证证明这件事牵涉到非常大量的计算,举个例子,每一次配对都有一个这样的计算

Math.pow(someBigNumber,12092909088188237225393433017559174875623137613219078327682045681675023350320878590139619158941453632724570634378148379186020109423506557278061404249513976103803771139954000579995199902828634263992330574392218791796266323480026479977659504287064359209036331389750395884727865805793574046154686347934603866375769645860851559671200189106819576945533990794197558448169154800495832790107673176422796675256499746815795625450299074794144048526198146639914021389804755241528331708078456200260597013666698340612446162656471808349941941036242500801205678881620332591272087635015318077794473705628671572713897714140224506269671672327501746902155512482220944778556374239955378577691861316356789180373125486706142640931817968722234080019888921817141837856053156323850750365255047978587780912486395587404967932864588640269696396456375831408999624015664858331115319294937654521467886227817728683577577618500683880562054279134724944160)

有时验证证明看起来很复杂,但实际上最主要的就是应用了三个椭圆曲线的计算(加,乘,pairing-check)。所以ethereum把这三个计算作成预编译合同,帮你省省气。

以上就是零知识证明的大致样貌了。符号多了些,但实际上观念还蛮简单的。希望对你有所帮助。