<>一、什么是零知识证明

“零知识证明”的定义是:证明者能够在不向验证者提供任何有用的信息的情况下,使验证者相信某个论断是正确的。
举个简单的例子:
A要向B证明自己拥有某个房间的钥匙,假设该房间只能用钥匙打开锁,而其他任何方法都打不开。这时有2个方法:
  (一)A把钥匙出示给B,B用这把钥匙打开该房间的锁,从而证明A拥有该房间的正确的钥匙。
  (二)B确定该房间内有某一物体,A用自己拥有的钥匙打开该房间的门,然后把物体拿出来出示给B,从而证明自己确实拥有该房间的钥匙。
  后面这个方法属于零知识证明。好处在于在整个证明的过程中,B始终不能看到钥匙的样子,从而避免了钥匙的泄露。

零知识证明过程有两个参与方,一方叫证明者,一方叫验证者。证明者掌握着某个秘密,他想让验证者相信他掌握着秘密,但是又不想泄漏这个秘密给验证者。

双方按照一个协议,通过一系列交互,最终验证者会得出一个明确的结论,证明者是或不是掌握这个秘密。

零知识证明是一种更加安全的信息验证或者身份验证机制。安全性和隐私性就是零知识证明的价值所在。

<>二、零知识证明的三个基本特性

(1)完备性。如果证明方和验证方都是诚实的,并遵循证明过程的每一步,进行正确的计算,那么这个证明一定是成功的,验证方一定能够接受证明方。
(2)合理性。没有人能够假冒证明方,使这个证明成功。
(3)零知识性。证明过程执行完之后,验证方只获得了“证明方拥有这个知识”这条信息,而没有获得关于这个知识本身的任何一点信息。

<>测试方式及内容


上节提出了验收测试的解决方案。接下来讨论测试的方式。稍有常识就可以知道,测试不能完全由证明者给出。毕竟不能让一个人既当运动员又当裁判。通常这种情况下会采用**
cut and choose**的策略。这个策略最简单的例子就是两人分粥。无论谁来分粥,都会给自己分的多,解决方法就是一个人分,另外一个人先挑。

虽然验证者有瞎蒙的可能,但是多轮交互下来,这种可能会越来越小。这样的证明是一种交互的证明方式。双方需要实时交互,交流信息。对于比特币隐私转帐来说,这种证明方式就不太好了。

一个问题是,交互方式是一对一的,发交易的人要向所有矿工证明交易是合法的,一个一个证明效率太低了。


另外一个问题是,既然需要交互,就要求证明过程中双方都在线,这个也会给用户代码很大的不便。最好是有一种非交互式的证明方式,只要证明者给出了证明,后续就不再需要交互,任何人都可以验证这个证明是否正确。但是这明显跟我们一开始说的不能完全由证明者给出矛盾。

一个解决方案就是用公共参考串 Common Reference String。

证明者给出的证明里面虽然不像 cut and choose
策略一样,由验证者挑选问题来决定。但是也不是完全由证明者自己来决定,而是根据事先定好的一个种子产生的随机序列决定的。这样就相当于有一个中立的第三方来出题目,同样也能达到效果。当然前提是这个第三方确实是中立的。

就像分粥的例子,一个人先分,但不是另外一个人先挑,而是中立第三方产生一个随机数来决定谁拿哪碗粥。同样可以保证结果尽量公平。

**zcash **系统也是采用了这样的方案。

测试题目的难度要有区分度。
一定要让真正掌握秘密的证明者通过的难度不大,而假的证明者无论有多强大的算力也无法蒙混过关。
在计算机领域,一般做法是把原始问题映射到NP问题。验证者只要验证证明者给出的NP问题的解即可,这个计算量需求不大。
如果某人掌握秘密,能解原始问题,那么转换一下就可以解对应的NP问题。如果不掌握秘密,绕过原始问题,直接暴力求解NP问题,一般可以认为是不可能的。

<>三、零知识证明的典范Zcash


在比特币网络中,用户需要将交易明文广播给所有矿工,由他们来校验交易的合法性。但是有些情况下,基于隐私的考虑,又不想把交易的具体内容公布出来。这就形成了一对矛盾。解决这个矛盾的关键思路是:
校验一个事件正确与否,并不需要验证者重现整个事件。
对于比特币的例子,一笔转帐交易合法与否,其实只要证明三件事:
1.发送的钱属于发送交易的人
2.发送者发送的金额等于接收者收到金额
3.发送者的钱确实被销毁了
整个证明过程中,矿工其实并不关心具体花掉了多少钱,发送者具体是谁,接受者具体是谁。矿工只关心系统的钱是不是守恒的。

zcash 就是用这个思路实现了隐私交易。


与比特币简单粗暴的“直接撕毁”不同,ZCash采用“备注作废”的手段,达到同样的效果。怎么理解呢?就是在不对原先“支票”作任何处理的前提下,新建一个作废文件列表,录入需要作废的“发票代号”。原先的Alice持有的支票仍旧存在,并没有消失,只是这张支票已经被记入“作废列表”。在确定资产所有权时要同时读取两个列表的信息,能确定Bob拥有资产所有权的判断方法是:作废列表中不存在Bob所持“支票”的代号。
在交易过程中运用 “零知识证明”。

对比一下,Alice要向Bob转一个单位的数字货币(BTC/ZEC),即Alice要向Bob转移一个单位的资产所有权。这时有以下两个方法:

(一)比特币中的做法:Alice拥有一张1BTC的支票,要转账给Bob时,先给Bob新建一张1BTC的支票,同时当着Bob的面将自己原先的支票撕毁。


(二)ZCash中的做法:Alice拥有一张1ZEC的支票,要转账给Bob时,先给Bob新建一张1ZEC的支票,然后在一张约定有效的作废列表中,记录下Alice的发票的代号,证明Alice的支票已经失效。

ZCash的方法属于零知识证明。整个交易过程中,Bob并没有见过Alice的支票,但是还是实现了资产所有权的转移
。在ZCash的整个交易系统中,在全网中存在的“支票”其实信息都是被加密的,可以通过拥有者的私钥解密,发票代号也是加密的,Alice和Bob的交易还有其他见证者,即负责记录交易信息的矿工。同样道理,矿工也不必看到Alice的支票,只要能确定代号为r1的支票已经作废了就行。
矿工们能获取的信息相当有限,但是这并不影响对矿工对交易有效性的判断。

判断的逻辑相当简单:矿工拿到Alice给的支票代号r1,去作废列表中检索,假如作废列表中已经存在r1,则证明r1所对应的的支票早已失效;若作废列表中并不存在r1,则证明r1对应的支票仍旧有效,此时矿工把r1录入作废列表中,把新生成的支票录入支票列表中。所以记账的过程就是对原有支票登记失效,并存入现有支票票的过程。

在这个过程中,我们不难发现,每笔交易矿工能接收到的东西只有一个发票代号,和一张新的发票,而且这两样东西都是被加密的。所以矿工并不知道转账双方是谁,也不知道转账金额是多少。

<>四、零知识证明的优缺点

首先,要实现匿名性,其所需要的证明信息所花费的计算资源就非常多,带来了大量的资源浪费,也导致了其可扩展性面临巨大挑战。

另外,匿名性会带来大量的额外监管问题,一旦有不法份子利用其用户黄、赌、毒等违法领域,将会给追踪与监管带来非常大的挑战,造成一系列社会问题。

尽管技术实现难度最高,但在保护在以太坊网络的隐私性和安全性上,其效果最佳。Vitalik还认为,零知识证明能够被应用于以太坊区块链上几乎所有的场景。

参考:
区块链学堂 | 深入浅出零知识证明 <https://www.jianshu.com/p/0905ce4d4f79>
(宁志伟)白话零知识证明 <https://www.jianshu.com/p/77b44709ca37>
不是程序员也能看懂的ZCash零知识证明 <https://zhuanlan.zhihu.com/p/24440530>(较详细)
Vitalik Buterin:以太坊余下四分之一的隐私问题,要用这四种方案解决
<https://www.leiphone.com/news/201712/BI4q1XS0itxMSuk1.html>
Zcash核心:零知识证明(一) <https://zhuanlan.zhihu.com/p/29909734>