AlexiaChen / AlexiaChen.github.io

My Blog https://github.com/AlexiaChen/AlexiaChen.github.io/issues
87 stars 11 forks source link

DoraHack搞了一期零知识证明的文本讲座资料整理 #75

Open AlexiaChen opened 4 years ago

AlexiaChen commented 4 years ago

前言

近三个月一致在入门ZKP,算是半只脚迈入门槛吧,也同时在写一篇ZKP的博客文章 #3 (还没写完,两个月前开始的),顺带听了昨晚的讲座。

资料正文

我不会摘录我已经理解的科普级别的原理了,主要发Github的链接,或者其他的我关注的文本片段。下面主要是郭宇博士的文本语录:

零知识证明在学术界静悄悄地研究了30多年,在区块链领域一下子得到了广泛的应用。区块链中的TPS等性能问题,直接或者间接地都可以通过零知识证明解决。

以太坊上最近有一个名词特别火,叫做zkRollup, V神称为准二层协议,它是通过智能合约来构造一个虚拟的区块链,然后链下的一个服务节点处理业务,当然这个业务处理是需要经过零知识证明的,然后服务节点定期把证明和业务状态提交到智能合约,形成一个区块链的结构。

由于零知识证明有压缩计算的功效,这样可以把链下的许多业务处理过程压缩成一个很小的证明,然后智能合约只需要通过检查证明就能保证服务节点没有办法作弊。

这样就相当于实现了一个高性能的去中心化应用,经过这种方式,在现有以太坊架构上,实现几千TPS并不困难。

https://github.com/matter-labs/rollup 这是zkRollup的一个Rust语言的实现,有兴趣可以看看代码,清晰易懂。

以太坊上有一个Aztec协议,它可以实现erc20 token的隐私保护,之前我们一直喊:上链,上链!似乎上链数据就可信了,其实数据上链了也就泄露了。

数据不上链就没有信任,但是上了链就泄露,那就上零知识证明啊。采用ZKP技术可以同时做到看似两个矛盾的地方融合:数据上链校验和隐私保护。

Aztec Protocol代码在这里 https://github.com/AztecProtocol/AZTEC

最近还有一个特别火的项目叫做Coda,它可以通过零知识证明技术来压缩区块。现在以太坊全节点磁盘占用已经奔着4TB走了,感觉区块的增长速度要大于硬盘降价速度。特别是ETH 2.0部署之后,全网数据量还会加速增长。通过零知识证明可以有效压缩区块,降低新加入的全节点的同步难度。

手机节点怎么办,有一个项目叫做Celo,它通过零知识证明技术来实现区块链轻节点,而且并不丧失安全性。

最后介绍下,路印团队开发的去中心化交易所协议---Loopring v3。想必大家对中心化的交易所的问题都清楚,暗箱操作,黑客盗币,甚至跑路。如果未来的数字资产普及开来,这里肯定会出现大问题。

路印协议可以做到,万一交易所跑路,用户的数字资产安然无恙,可以从容提币,基本可以说,100%保证用户的数字资产安全。

路印协议是基于zkRollup的思想,现在初步性能已经可以做到6000 TPS,这已经千倍于之前的DEX协议,这都归功于零知识证明这个强大的工具。

当然为了实现交易的撮合,链下的所有业务逻辑为了做零知识证明,都是由电路逻辑来编写,我们团队前后花了三个多月来检验这个交易所业务逻辑的可靠性,工程非常浩大,期待Loopring早日上线,彻底解决交易的安全问题。

loopring的协议代码: https://github.com/Loopring/protocols

现工业界的阶段,零知识证明,需要先把需要做零知识证明的程序转换成电路(数学概念的电路),然后证明的时候是自动的,验证证明也是自动的。

我们在网上看到的大多数科普文章是关于QAP-based zkSNARK零知识证明方案。ZCash使用了这个方案,并且也是由于ZCash加速了这个技术走出密码学小圈子,让更广大的极客人群接触到了这个黑科技。

我接下来比较浅显的方式给大家描述一个大致的流程,用一个非常简单的例子:

摄像我知道一个数字'w', 然后它的Hash值正好落在10^5和10^6之间。然后我要零知识地证明我知道这样一个数字'w'。

第一步,首先写一个校验程序,判断Hash值的区间:

prog(int x) bool
{
    if x < 10^5 then
        return false

    if x > 10^6 then
        return false

    return true;
}

然后我把这段代码编译到一种特殊的目标语言: 算术电路。

这个思想来源于硬件电路,但是和硬件几乎没什么关系。这里的电路是一个数学概念,可是为什么是电路呢?而不是其他东西。

因为电路的可满足性问题是一个NP完全问题。

所谓的算术电路是由许多的二输入加法门和二输入乘法门组成的。门和门之间用线连起来,最左边是输入端,最右是输出端。如果电路最右边输出1,那么就说明输入的数字满足要求,否则说明数字不满足要求。

第二步,我们通过算术电路来构造一个逻辑约束,这个约束是把所有门的输入输出关系AND(逻辑and)起来,得到一个巨大的约束‘C’。

一个加法门的约束就是in1 + in2 = out; 乘法门的约束就是in1*in2 = out; in,out这些都是所有电路门之间的连线。

我们把这些看成是一组电线变量‘X’。

第三步: 我们把这个秘密且珍贵的'w'输入到电路中,当然电路的输出应该是返回1.同时这个电路在运行过程中,我们得到了电路中所有连线上的数值,不仅仅是输入和输出,这等于我们对变量集合‘X’进行了完全赋值,如果所有变量都能被赋值,并且满足巨大的约束'C',那么我们输入的秘密数字‘w’满足要求。

第四步, 如果通过电路执行的算法无误,那么这个巨大的约束应该是可以满足的,即逻辑表达式为true。

这个电路满足性问题是NP问题,如果不老老实实把'w'放进来运行,是很难找到另一组不同的变量赋值,也能满足第二步产生的巨大约束‘C’。

第五步,把这个约束‘C’,还有变量的集合的赋值‘X’都放到椭圆曲线上,这样所有的变量值都被加密了。同时采用一些办法,使得这个巨大的约束可以在加了密的情况下仍然可以检验(同态性)。

这样做的目的是为了保证变量赋值不泄露给校验者(Verifier),保证零知识。

第六步,Verifier通过随机挑战一些值,对一小部分加了密的‘C’和‘X’进行验证,从而使得证明者(Prover)的作弊概率降低到一个很小的值。

第七步,运用一些密码学技术,比如Fiat-shamir变换,把互交过程折叠起来,变成非互交式。

第八步,把产生的最终零知识证明公布出来,让大家检验。

这大致的流程就表明了这就是一个零知识的可验证计算协议。这也是构造通用零知识证明技术的一般思路。

有很多零知识证明的技术,比如zkSNARK(QAP-based zkSNARK),最新版本是Groth 16,还有BulletProof,zkSTARK。此外还有一些冷门的,Marlin,Plonk,Soni等等。

现在零知识证明技术成熟可用了吗?

有关于零知识证明的项目从2018年下半年区块链行业遇冷后,反而开始逐步壮大,可能是大家终于可以静心下来做些有深度的研究。(个人觉得,类似于文艺复兴才有催生了科学)。

我想从两个方面来探讨零知识证明技术,理论上和工程上。

理论上,目前各种不同的ZKP技术正在不断涌现,而且也有一些可以显著提高性能的密码学技巧在不断革新。可以说,在区块链行业发展的大背景下,ZKP的理论发展过程被加速了。理论上很难说已经达到了一个成熟的阶段,我感觉可能是刚刚开始。

另一方面,工程上,ZKP可以说远远不成熟,这个领域到处是空白,许多理论还只是停留在纸面上,或者缺少优化版本的库,还需要社区一起努力。

目前达到产品级应用的库主要是libsnark和bellman,后者是用Rust开发的库,仅支持Groth16方案,这也是QAP-based zkSNARK方案中最流行的分支。

对于技术人员来说,再也没有比动手写写代码感受来得直观。推荐大家试试snark.js https://github.com/iden3/snarkjs, js写的,性能固然差点,但是可以上手,实际感受零知识证明编程,本来就是教程向的东西。要性能,可以用libsnark写几个电路。