如今不少人都据说过ZK-SNARKs协议,这是零知识证实技术的通用性说法,使用它的案例从可验证的计算到私人保护的数字货币。也许你不知道,ZK-SNARKs协议有更新的版本,ZK-STARKs。其中改变的字母T表明的是“透明”,ZK-STARKs解决ZK-SNARKs的其中一个弱势,它依赖于一种“可信任的配置”。并且ZK-STARKs也有更加简单的加密假设,从而避免椭圆曲线,配对以及指数假设的知识,而是仅仅依赖于哈希和信息的理论;这也就意味着他们对于量子计算机的攻击来讲,是安全的。算法
可是,这也会有代价:证实的存储大小也从288字节增长到几百千兆字节。有时候这个代价并不值得,可是有时候,特别是在讨论公链应用的时候,须要的最小信任很是高,事情就极可能这样。而且若是椭圆曲线打破或者量子计算机真地出现,这事情就确定会发生。安全
因此这种零知识证实是如何工做呢?首先,让咱们来看看通用的ZKP协议是作什么的。假设你如今有一个公开函数f,一个私密的输入x以及一个公开的输出y。你想要证实你知道一个x,从而获得f(x) = y,而不用泄露x是什么。而且,为了保证这个协议足够简单,你想要它的验证比计算f自己还要快。函数
让咱们来举个例子:工具
f 是一个须要在普通计算机上运行2周的计算,可是在数据中心只须要2小时。你给数据中心发送了这个计算(也就是说,运行f的代码),而后数据中心就会运行,而且经过证实反馈了答案y。你在几毫秒以内,就验证了这个证实,而且相信y其实就是答案。区块链
你有一个加密的交易,表格中的X1是我以前的余额。X2是你以前的余额。X3是我新的余额。X4是你新的余额。你想要建立一个证实,其中这个交易是有效的(特别指出,以前和如今的余额都是正的,并且我余额的减小抵消了你余额的增长)。x能够是秘钥对,而且f能够是一个函数,其中包含了内置公开输入的交易,并且做为输入秘钥,解密了交易,完成了检验,若是经过就返回1,若是失败就返回0。y 固然会是1。编码
你有个相似以太坊的区块链,并且你下载了最近的区块。你想要一个证实,表示这个区块是有效的,并且这个区块是在链的顶端,其中链上任何区块都是有效的。你想让一个现存的全节点来提供这样的验证。x是整个区块链,f是区块处理的函数,验证有效性而且输出最后区块的哈希,并且y就是你以前下载区块的哈希。加密
因此这些问题的困难点在哪呢?就像它表现出来的,须要很容易为零知识证实(也就是,隐私性)提出保证;如今有不少种方法来将任何计算转换为例如三色图表问题的状况,其中图表的三种颜色都对应原始问题的解决方案,而后使用传统的零知识证实协议来证实,你即便不揭露它的信息,也能够得到有效的图表颜色。设计
更困难的地方在于提供简洁性。直观地来讲,证实关于计算简洁性是困难的,由于计算是难以置信地脆弱。若是你有个很长很复杂的计算,那么你须要有能力在计算过程当中的任何地方,从0跳到1,而后再不少状况下,甚至很小的失误都会致使计算结果彻底不一样。所以,很难知道你如何才能作出例如对计算过程地随机取样,才能保证正确性。由于,很容易就会错过“很小部分的计算”。可是,经过一些厉害的数学方法,你就能够作到。开发
总体的感受是,和这些联合在一块儿的协议,都在使用纠偏编码的数学方式,这种方式一般用来让数据能够容错。若是你有项目数据,那么你能够将这些数据做为行代码,而后你能够在这行中选出四个点。其中任何两个点都足够来从新构造这条线,所以也给你另外两个点。而且,若是你甚至对数据进行了很小的改变,那么它至少保证了你四个点中的三个。你也能够将数据编码成1,000,000维度的多项式,而且从中选出2,000,000个点;这些点中的任意1,000,001个都会得到初始数据,所以其余点,以及数据的任何偏离都会至少改变1,000,000个点。这里的算法将会这样利用多项式,从而使得偏差放大。get
原始数据更改1个点,对于多项式都会有很大的改变
简单举例
假设你想要证实,你有个多项目P,从而对于x从1到100万,P(x)是0 <= P(x) <= 9之间的整数。这就是“范围检查”的简单举例;也许你会假设这类检查能够用来进行验证,例如在进行转帐后,帐户余额仍然是正数。若是1 <= P(x) <= 9成立,那么这多是检查这些值造成正确的数独解决方案的一部分。
“传统”的方式是证实这会显示全部1,000,000个点,而且经过检查这些数值来验证。可是,咱们想要看到是否咱们可以作出证据,能够在少于1,000,000个步骤的时候就被验证。简单随机检查P的估值不会这样作;总会有欺诈者出现,来证实P是知足999,999个位置,可是不能知足最后一个,并且随机取样就几个数字,一般老是会错过那个。那么咱们能够怎么作呢?
让咱们从数学方式来转化这个问题。假设C(x)是多项式检验;若是0 <= x <= 9,那么C(x) = 0,不然,C(x)就是非零数字。有一种很简单的方法,就能够构建C(x):x * (x-1) * (x-2) * … * (x-9)(咱们会假设,全部咱们的多项式和其余数字都会使用常数,全部咱们不须要担忧之间的数字)。
如今,问题变成了:证实你知道P,而后对于全部的x从1到1,000,000,C(P(x)) = 0。让Z(x) = (x-1) * (x-2) * … (x-1000000)。很基本的数学事实是,对于x从1到1,000,000,任何等于零的多项式都是Z(x)的乘积。所以,问题再次转变成了:证实你知道P和D,而后对于全部的x,C(P(x)) = Z(x) * D(x)(须要注意到,若是你知道一个合适的C(P(x)),那么用Z(x)除以计算D(x)不是太困难;你可使用长多项式除法或者基于FFT算法来进行更快地运算)。如今,咱们将最初的问题转换成了数学问题,而且看起来能够顺利解决。
那么如何证实这个问题呢?咱们能够假设,证实过程是证实者和验证者之间的三步沟通:证实者发出了一些信息,而后验证者发出一些需求,以后证实者发出更多的信息。首先,证实者认可(也就是说,建立一个Merkle树,而且给验证者发去根哈希)对于1到10亿之间x的全部P(x) 和 D(x)的估值。这就包含了0 <= P(x) <= 9之间的100万个点,以及剩下的9.99亿个点。
假设验证者已经知道Z(x)在这些点的估值;那么Z(x)就像一个“公共的验证秘钥”,从而每一个人都必须提早知道(没有地方存储Z(x)的客户端,能够简单地将它存储在Z(x)的Merkle树根部,并且须要证实者也为每一个Z(x)的数值提供验证者须要的分支;或者,有些数字字段,对于x和Z(x)都很容易计算)。在得到这个承认(也就是说,Merkle树的根部),验证者而后会在1和10亿之间选择随机的16x数值,并且让证实者来提供P(x)和D(x)的Merkle树分支。证实者提供了这些数值,并且验证者会检查(i)这些分支和以前提供的Merkle树根部符合(ii)C(P(x))其实等于Z(x) * D(x)。
咱们知道这个证实有很好的完整性,若是你其实知道一个合适的P(x),那么你能够计算D(x)而且构建正确的证实,来经过16个检查点。可是稳定性又如何呢?也就是说,若是欺诈的证实者提供了个错误的P(x),他们被抓的最小可能性是多少?咱们能够进行以下分析。由于C(P(x))是由1,000,000维度多项式组成的10维度多项式。总体来讲,咱们知道这两个不一样的多项式最多在N个点符合;所以,10,000,000维度的多项式和任何等于Z(x) * D(x)的多项式都不会相等。对于x来讲,至少在990,000,000个点都不会赞成。所以,对于很差的P(x),在一轮被抓住的几率已是99%;经过16轮检查,被抓住的几率是1 – 10-32 ,也就是说,这个机制不可能存在欺诈。
那么,咱们刚刚作了什么?咱们使用多项式来推进任何不良解决方案的错误,以致于对于初始问题的任何错误解决方案,都须要100万个检查才能发现,最终致使验证协议的解决方案,能够99%的几率发现错误。
咱们能够将这三步的机制转换成一个非交互式的证实,这能够经过单个的证实者来广播,而后被任何人使用菲亚特-夏米尔启发式算法来进行验证,证实者首先构建P(x) 和 D(x)数值的Merkle树,而后计算树的根哈希。这个根部自己被用于做为熵的来源,用来决定证实者须要提升这个树的哪些分支。证实者而后就会广播Merkle树的根部,分支还有证实。计算所有会在提供方完成;从数据计算Merkle树根部的过程,而后是使用这些来选择通过审计的分支,有消息地完成了交互性验证者的需求。
欺诈者在不须要有效的P(x)前提下,惟一能作的事情,就是尝试进行有效验证,直到最终他们特别幸运,选择到了正确的Merkle树分支,可是几率只有1 – 10-32 (也就是说,至少有1 – 10-32 的几率,虚假的证实不会经过检查),欺诈者须要花费几十亿年,才能获得能够经过的证实。
前景展望
为了说明这项技术的能力,咱们来作些看起来不是很重要的事情:证实你知道第100万个斐波纳契数。为了完成这个,咱们会证实你对多项式有了解,P(x)表明第x个斐波纳契数。多项式检验就会从3个维度进行:C(x1, x2, x3) = x3-x2-x1(须要注意,若是对全部x来讲,C(P(x), P(x+1), P(x+2)) = 0,那么P(x)久表明斐波纳契数)。
因此问题就变成了:证实你知道有个P和D,而后C(P(x), P(x+1), P(x+2)) = Z(x) * D(x)。对于其中的16个因子,证实者须要为P(x), P(x+1), P(x+2) and D(x)提供Merkle树的分支。证实者并且还须要保证所提供的Merkle树的分支能够保证,P(0) = P(1) = 1。不然,整个流程就是同样的。
如今,为了完成这个,还须要解决2个问题。第一个是,若是咱们尝试进行列举数字的方法来解决这个问题,效率就会很低,由于这些数字一般都会很大。例如,第100万个斐波纳契数有208988个数字。若是咱们其实想要得到简单性,与其使用常规数字进行列举,咱们须要使用有限的数字系统,始终符合咱们了解的规则,例如a * (b+c) = (ab) + (ac) and (a^2 – b^2) = (a-b) * (a+b),可是每一个数字都会占据必定空间的数据。证实关于斐波纳契数数字的问题,须要更加复杂的设计。最简单的模式,就是将每一个a + b用a + b的N进制数来代替,对减法和乘法也是一样地方法,对于除法,使用模块逆转(例如,若是N=7,那么3 + 4 = 0, 2 + 6 = 1, 3 * 4 = 5, 4 / 2 = 2并且5 / 2 = 6)。
其次,你也许注意到了,在上面的证实中,我忽略了一种攻击:若是攻击者不是经过看似真实的P(x),而是使用了并不在这些多项式的数据?那么,无效的C(P(x))必需要和有效的C(P(x))在至少9.9亿个点上相同,就不会应用了,并且会很是不一样,并且更有效的攻击是有可能发生的。例如 ,一个攻击者会保证任何x都有一个随机数p,那么计算d = C(p) / Z(x),而且将这些数字都放入P(x)和D(x)。这些数字不会在任何低维度的多项式,可是它们会经过检测。
这就证实了这种可能性会颇有效地抵抗攻击,虽然作这些的工具相对复杂,并且你能够说它们组成了STARKs协议中的数学创新。同时,这个解决方案有个限制:你能够清除这些数据,可是你不能清除和你的多项式存在一个或两个变量差异的多项式。所以,这些工具会提供接近性证实,证实大多数在P和D的点上,都会表明正确的多项式。
因此最终证实,这已经足够来打造证实,尽管会有两个小问题。首先,验证者须要检查更多的指数来弥补错误占据的有限空间。其次,若是咱们正在打造边界检测,那么咱们须要将接近性证实扩大到不止是证实大多数点是在同个多项式,并且证实这两个特别的点是在那个多项式上。
内容来源:巴比特 原文做者:Vitalik Buterin
Blockathon|48小时极客竞赛,区块链马拉松等你挑战(成都)
时间:2018年9月14-16日
地点:成都高新区天府五街200号菁蓉国际广场2号楼A座12楼中韩互联网+新技术孵化器
招募50名开发者(识别下图二维码或点击“阅读原文”便可报名)
报名费100元为参赛押金,参赛者我的缘由不能到场参加活动概不退款;参赛者全程参与活动,待活动结束后现场退还。9月14日18:00开始第一次签到,9月15日和16日天天早上都要记得签到哦。
主办方免费提供2天的食物、饮料,并为每一位参会者准备一件文化衫