参考链接:zk-SNARK深入理解
什么是zk-SNARK
零知识证明解决了区块链应用中所有信息透明化的问题,区块链的应用价值是去中心化共识,但是用在其他领域可能透明的方式就不再适用。
零知识证明解决的就是:以不透露一个论断(statement)的任何信息为前提,向你证明这个论断是对的。
zk-SNARK是“zero knowledge Succinct Non-interactive ARgument of Knowledge”的缩写。
修饰主体名词的定语由三部分组成,分别代表了此技术要解决的三个问题,分别是:
1. zero knowledge:零知识,即在证明的过程中不透露任何内情,如上文的例子所示;
2. succinct:简洁的,主要是指验证过程不涉及大量数据传输以及验证算法简单;
3. non-interactive:无交互。上文中举的两个例子虽然实现了零知识证明,但Prover和Verifier之间需要经过多次交互才能取得满意的可靠性,而此技术试图彻底避免这些交互。
zk-SNARK的实际应用: ZCash
ZCash的核心概念是从比特币传承下来的。
1. 一个比特币交易(Transaction)接受若干输入(Transaction Input, TI),同时产生若干输出(Transaction Output, TO);
2. TI和TO是相对一个特定交易而言的,因为一个交易的TO可能成为另一个交易的TI,这是一个将挣来的钱再花出去的过程;在还没花出去前,这些钱就是“Unspent”的,因此此刻尚未成为下一个交易TI的TO称为“UXTO(Unspent Transaction Output)”。UXTO是比特币交易的基本单元;
3. 交易的付款方需证明自己有权使用这些UTXO,方法是提供私钥进行验证,因为每个交易TO会指定收款人的公钥,保证只有收款人才能接着花它。
ZCash继承了比特币的交易模型,不过UTXO被衍生出的新概念“note”所代替,后者是ZCash的基本交易单元。每张note上都标注了(即所有者)。一个交易的输入和输出都是若干note。将note记为“note=(PK, v, r)”,其中,PK是所有者的公钥(地址),v是金额,而r是可以唯一区分该note的序列号;
不同的是: ZCash交易分成两类: 透明地址,隐藏地址。透明地址交易的输入、输出直接是可见的note信息。
-
ZCash交易的例子
-
而对于隐藏地址交易,输入和/或输出的地址和金额是隐藏的
-
透明地址和隐藏地址混用
在隐藏地址的交易中,输入、输出不再是明文的note,而分别是note的废止通知和签发通知:
-
签发通知(note commitment):作为交易的输出,表示一张新note被签发。一个有效的commitment是一张note存在的证明,然而从它包含的信息中并不知道是哪张note,也就无法知道所有者是谁,金额多少。为满足这一点,最简单的方法是对note的描述信息取哈希,因此note对应的commitment可以简单描述为“HASH(note)”;
-
废止通知(note nullifier):作为交易的输入,表示一张老支票将作废(因为马上要被兑现、花掉了)。同比特币一样,一个交易的输入一定是另一个交易的输出,因此nullifier对应唯一一个commitment(结合commitment的定义,也就唯一对应一张note),但从它包含的信息并不能推导出是哪个commitment(如果可以的话,ZCash交易便可被追踪,因而丧失隐私性了)。为构造满足要求的nullifier,取哈希依然是个好办法,因此序号为r的note,对应的nullifier可描述为“HASH(r)”。
-
通过引入nullifier和commitment,交易之间路人皆知的关联变成了付款人和收款人的心照不宣
-
ZCash区块链共识的所有参与者(节点)各自维护一个nullifer和commitment的集合,随着新交易的产生,这两个集合的内容会不断变化。下面介绍一下这个过程。假设当前已存世3张支票:note1=(PK1,v1,r1),note2=(PK2,v2,r2),note3=(PK3,v3,r3),其中note1属于Anna,note2已经被花掉了。此时各节点维护的nullifier和commitment集合内容如表1所示.
Commitment Set | Nullifier Set |
---|---|
C1 = HASH(note1) | NF1 = HASH(r2) |
C2 = HASH(note2) | |
C3 = HASH(note3) |
表1 支付前的commitment和nullifier集合
- james决定将金额为v1的note1转给wade,他的公钥/地址是PK4,将这么操作:
- 随机挑选一个序列号r4,并以此产生note4 = (PK4, v1, r4);
- 秘密地将note4发给wade;
- 将note1的nullifier,即nf2 = HASH(r1),以及新产生的note4的commitment,即其哈希值HASH(note4)广播给所有节点。
收到james广播的节点,会检查nf2是否已存在于nullifier集合中;若没有,说明对应的支票没有重复兑现,节点会将HASH(note4)和NF2分别加入到所维护的commitment和nullifier队列中,如表2所示。nullifier所起的作用就是防止数字货币被“重复支付”的基础问题.
Commitment Set | Nullifier Set |
---|---|
C1 = HASH(note1) | NF1 = HASH(r2) |
C2 = HASH(note2) | NF2 = HASH(r1) |
C3 = HASH(note3) | |
C4 = HASH(note4) |
表2 支付后的commitment和nullifier集合
如何判断james给的NF2的有效性
- 零知识证明这时就能排上用场:james会同时提供一份凭证 π。π足以证明提供人(这里值james)知道能满足以下条件的PK1,sk1(PK1对应的私钥)和r1的值
- PK1、r1复原的note数据结构,其哈希值存在于commitment集合中 → 用以支付的note是有效的;
- sk1是PK1的私钥 → james有权使用这张note;
- HASH(r1) = NF2 → nullifier与commitment一致。
- 其他节点在验证π有效后才承认此次交易合法。同时,它们无法从π推断出有关PK1、sk1和r1的任何信息。
零知识证明,zk-SNARK的基本了解和ZCash对零知识证明的应用 -Conquer_Dwyane
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。
如果你觉得本文海星,不妨请我喝杯咖啡