0%

十分钟开发零知识证明之混币--原理篇

零知识证明很多人听过,但不明白它是干什么的?其实零知识证明可以用一句话来概括:“证明者(Alice)在不透露秘密的情况下,说服验证者(Bob)相信证明者(Alice)知道这个秘密”。为了更直观解释,接下来会用混币的例子来说明。

什么是混币?

混币的目的是切断加密货币交易中发送方与接受方的联系,提高加密货币的隐私性和匿名性,使第三方更难追踪加密货币的用途以及它属于谁。

举个生活中的例子: 游客向庙里功德箱中仍香火钱,所有的游客仍的都是同一个年份的一元硬币,这时有一个第三方在一旁观察,他可以知道谁在什么时间扔进去多少个硬币。但是当小沙弥从功德箱中取钱的时候,他无法分别取出的硬币是由谁扔进去的。

这里功德箱就起到一个混币的功能,游客使用功德箱可以快速高效地将自己的资金与其他的资金进行混合,这里功德箱有个缺陷,游客仍进去的币其实谁都可以取出没有限制,所以我们需要在提款人与混币后的加密货币之间创建随机的联系,我们将使用零知识证明来解决在不暴露相关信息的情况下,证明加密货币所有权的问题。

为什么需要混币/隐私币

最主要的原因是混币帮我们解决了匿名与隐私以及货币可互换性的问题。

匿名

目前公链(比特币)的匿名只起到假名的作用,例如现实生活中的人可以生成任意多的公私钥对,用这些公钥在链上发送或接受每笔交易,这些公钥就充当他们的假名。如果外界不知道你和公钥的关系,他们就无法把你和你的交易历史关联起来,只要有人能把你跟公钥联系起来,就可以顺藤摸瓜找到你过去的交易历史。目前不没有办法阻止第三方将我们和我们的公钥联系起来。

为了直观理解上面的文字,举一个例子来说明: 作家一般都会用一个假名与读者互动,比如,《哈利波特》的作者 乔安妮·罗琳 总是以“J.K.罗琳”的名义出版作品。她为什么这样做?很可能是因为她想过正常人的生活,不让别人发现她是一个知名作家。不幸的是,一旦你被曝光,假名就变得毫无意义。就好像一旦我知道 乔安妮·罗琳 就是 J.K.罗琳,我会立即把她与她写过的每一件作品联系起来,并且意识到她一年的版税可能都比我一辈子赚的钱还要多。

到这里我们回答了需要隐私币的第一个理由:隐私币可以能实现完全匿名且不可追踪。

货币可互换性

流通性使货币具有了内在可互换性,可互换性意味着商品/物品/货币可以完全互换。如果说1BTC如论如何都价值1BTC,无论它来自何处或之前被用于什么其他用途。但是加密货币具有极度透明性,我们可以追踪到与某一特定货币的所有相关历史交易,这样一来,人们一旦发现某个货币是“污点”货币(俗称“黑钱”)就可以拒绝接受这种货币。如果这种情况大规模发生,加密货币将不再是可互换的因为“干净”的货币比“污点”货币具有更大价值。

不可互换的货币会给用户带来额外的负担,用户为了避免不小心买入“污点”货币,那么用户就会被迫检查他们购买的每笔货币的交易历史。

到这里我们回答了需要隐私币的第二个理由:由于隐私币无法查看货币的交易记录,所以减少了货币不可互换性的问题。

用零知识证明解决隐私

为了在提款人与混币后的加密货币之间创建随机的联系,需要使用零知识证明来解决在不暴露相关信息的情况下,证明加密货币所有权的问题。那什么是零知识证明,为什么零知识证明可以在不揭露敏感信息的情况下也可以证明你知道某个秘密呢?

零知识证明

接下来只从使用零知识证明的角度来讲解,让大家能从一个宏观的视角看零知识证明是如何被使用的,至于零知识证明的细节,如果大家感兴趣可以持续关注我的公众号,在之后的文章中我会用通俗的方法来分享零知识证明 ^_^

img

上图是使用零知识证明的一般过程,这里我们将circuit看作是一个黑盒,在circuit中会执行一些约束,这些约束是与要解决的问题是相关的,比如x+y=5。接下来从Prover向circuit中传入两个值:Private input(值:2),public input (值:3),接下来circuit会进行一系列的运算并检查约束是否满足(2+3=5),然后输出一个proof。Prover将proof以及public input发送给Verifier,Verifier使用proof,public input 进行运算来验证proof是否正确,如果正确则返回true,错误则返回false。

这里Private input是不对外揭露的,只有prover自己知道这个值。public input是prover与Verifier之间共享的一个值。所以上面的过程可以总结为,prover 在不揭露Private input 的情况下向Verifier证明自己知道一个值能满足(x+3=5)。

基于circuit的零知识证明被称为通用零知识证明,通用零知识证明会将一个计算问题转化成circuit,接下以zk-Snark为例来说明,下图是zk-Snark流程图:

img

首先,zk-SNARK不能直接用于解决任何计算问题,我们必须先把问题转换成正确的“形式”来处理,这种形式叫做 "quadratic arithmetic problem"(QAP),在进行QAP 转换的同时,我们可以用Private input ,public input创建一个对应的解,称为QAP的witness。只有prover用这个witness来生成proof。

如上图所示:

  1. 首先得有一个计算问题,这个问题一般是NP问题
  2. 然后将计算问题做一个等价转换变成QAP,步骤如下:
    • 将计算问题拍平变成circuit
    • 接下来我们要把circuit转化成 R1CS(rank-1 constraint system,一阶约束系统)。R1CS 是一个由三向量组 (a,b,c) 组成的序列,R1CS 有个解向量 s,s 必须满足符号表示向量的内积运算 a.s * b.s - c.s = 0,这里的解向量s就是witness
    • 接下来我们要做的是将 R1CS 转化成 QAP 形式,这两者的区别是 QAP 使用多项式来代替点积运算,他们所实现的逻辑完全相同。
  3. 接下的是比较重要的一步trusted setup,trusted setup会生成两个值PK,VK,truseted setup的目的是实现零交互验证,它生成的PK,VK相当于是一个“上帝”由它来帮我们做一些挑战,来验证prover。
  4. prover会用PK已经witness生成一个proof交给Verifier
  5. Verifier拿到这个proof会用VK做一些校验,这一步发生在链上,有链上的节点或智能合约来做校验。

到这里,你已经基本掌握了zk-Snark的运作原理,虽然还有些细节不明白不过没关系,这并不影响你利用zk-snark来做项目,有关zk-snark的细节我将在之后的文章中有介绍。

总结

混币的目的是切断加密货币交易中发送方与接受方的联系,发送方利用混币系统将自己的钱与其他人的钱进行混合,接受方利用零知识证明来证明有某一个混币的所有全,从而进行转账交易。

现在已经将实现一个混币所需要的原理都已经全部说完了,在下一个篇中将开始进入实操阶段,动手实现一个混币。