Tornado.Cash ZK过程深入解析

Tornado.Cash ZK过程深入解析,第1张

 Tornado的现金池,以DAI池子为例,每个Coin为100DAI。

目前有三个Coin:C1, C2, C3。

C1,C2,C3 在池子里,即300DAI,另外还有2个nullifier在合约里存储。

nullifier是为了防止双花的数据结构,存储的是花出去的note对应的nullifier。

C1,C2,C3 被保存在一个Merkle树中,这些Coin对外是公开的。

H1, H2是哈希函数。

接下来是deposit过程,比如Alice转100DAI到Tornado合约中,她需要提供:

  • C4 = H1(k, r) k 和 r 是随机选取的随机数
  • MerkleProof(4) 为C4生成一个默克尔树证明

智能合约验证MerkleProof(4) 是否合法,并用C4更新合约的merkle树,同时更新state。

Alice会保存(k,r) 作为note,一个note对应一个Coin,这里的note就是Tornado生成的txt文件。

这里,外部观察者可以对应到C4和Alice地址的关系。

Bob手中有:

  • note = (k’, r’)
  • nf = H2(k’)

Bob需要证明:

  • 该note对应默克尔树中的一个Coin,而且其对应的nullifier为 nf

Bob构建证明Π

  • 公开信息:x = (root, nf, A)
    • root 是默克尔树树根
    • nf 是其提供的nf值,nf = H2(k’)
    • A 是提现地址
  • 私有witness = (k’, r’, C3, MerkleProof(3))

电路 Circuit(x,w)=0,需要满足:

  • MerkleProof(C3)是正确的,也就是C3确实在合约中保存的默克尔树中
  • C3 = H1(k’, r’),C3确实为note的哈希
  • nf = H2(k’),nf是k’的哈希

注意,这里A没有在电路中,但是也包含在公开陈述中,是为了防止被矿工修改为其他值。

提现过程:

  • Bob提供nf,proof,Anf,proof,A
  • 合约检查ProofProof是否和(root, nf, A)匹配
  • nf是否不在合约的nullifiers中(防止该note双花)

隐私性分析:

  • nfnf和证明Π 没有泄露提现过程中是哪个Coin被花出去
  • 并且Coin3不会被双花,因为nf = H2(k’) 现在被登记在了nullifiers中

提现的时候,gas fee谁来支付?——答案是relayer来支付。

为了防止用户提现的时候,将提现地址和支付fee的地址关联起来,这时候需要一个relayer代替用户和合约进行交互,并且在提现金额中把对应的fee进行扣除返回给用户。

三、总结

用户存入资金的时候,只需要提供把note的哈希和插入Merkle树的相关Proof提供给合约。这时候,Coin和该用户是关联起来的。

用户提现的时候,只需要提供note对应的Merkle证明,证明该note对应的Coin存在于Merkle树中。

在合约的角度上,合约不知道究竟是哪个Coin被花费了,也不知道花费这个Coin的用户究竟是哪一个存币的用户,也就是说无法知道支取和存入的关系。

外部看来,只能知道合约默克尔树中保存Coin的人是谁,无法知道这个Coin是否被花费,更不知道支取和存入的关系了。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/722308.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)

保存