<aside> 💡 V神的新论文讲了什么?

https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4563364

https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4563364

</aside>

背景

  1. V神一作的论文比较少。Link
  2. Tornado Cash被制裁,创始人接连被捕,面临审判。Link
  3. 既要隐私又要合规,或成为隐私未来发展的一个最大问题。

Tornado Cash

  1. 分不同单笔额度的资金池,每个资金池允许用户从一个地址Deposit,然后往另一个地址Withdraw

    https://ipfs.io/ipns/tornadocash.eth/

    https://ipfs.io/ipns/tornadocash.eth/

    https://hackmd.io/@chenyanlong/tornadoCash

    https://hackmd.io/@chenyanlong/tornadoCash

  2. Deposit:生成CommitmentHash并发布,保留私钥

    1. 用户随机生成Nullifier和Secret

      https://betterprogramming.pub/understanding-zero-knowledge-proofs-through-the-source-code-of-tornado-cash-41d335c5475f

      https://betterprogramming.pub/understanding-zero-knowledge-proofs-through-the-source-code-of-tornado-cash-41d335c5475f

    2. 用户计算CommitmentHash = Hash(Nullifier, Secret)

    3. 用户打钱到链上合约,同时发布CommitmentHash,记录进Commitment Merkle tree

      https://github.com/tornadocash/tornado-core

      https://github.com/tornadocash/tornado-core

  3. Withdraw:证明知道某个CommitmentHash的私钥,并发布对应的NullifierHash让其失效

    1. 用户计算NullifierHash = Hash(Nullifier)

    2. 用户计算zero-knowledge proof

      1. private inputs: Nullifier、Secret、CommitmentHash、Commitment Merkle path

      2. public inputs: NullifierHash、Commitment Merkle root

      3. 满足约束

        1. CommitmentHash = Hash(Nullifier, Secret)
        2. NullifierHash = Hash(Nullifier)
        3. CommitmentHash属于Commitment Merkle tree
      4. source code(circom)

        template Withdraw(levels) {
            signal input root;
            signal input nullifierHash;
            ...
            signal private input nullifier;
            signal private input secret;
            signal private input pathElements[levels];
            signal private input pathIndices[levels];
        
            component hasher = CommitmentHasher();  // 约束1
            hasher.nullifier <== nullifier;
            hasher.secret <== secret;
            hasher.nullifierHash === nullifierHash;  // 约束2
        
            component tree = MerkleTreeChecker(levels);  // 约束3
            tree.leaf <== hasher.commitment;
            tree.root <== root;
            for (var i = 0; i < levels; i++) {
                tree.pathElements[i] <== pathElements[i];
                tree.pathIndices[i] <== pathIndices[i];
            }
            
            ...
        }
        
    3. 用户发布public inputs和proof到链上合约,合约验证,然后打钱给用户

      1. 验证NullifierHash未发布过并记录(即这个Deposit没被Withdraw过)

      2. 验证Commitment Merkle root历史上存在

      3. 结合public inputs验证proof

      4. source code(solidity)

        function withdraw(
            bytes calldata _proof,
            bytes32 _root,
            bytes32 _nullifierHash,
            address payable _recipient,
            address payable _relayer,
            uint256 _fee,
            uint256 _refund
          ) external payable nonReentrant {
            ...
            require(!nullifierHashes[_nullifierHash], "...");  // 验证1
            require(isKnownRoot(_root), "...");  // 验证2
            require(
              verifier.verifyProof(
                _proof,
                [uint256(_root), uint256(_nullifierHash), uint256(_recipient), uint256(_relayer), _fee, _refund]
              ),
              "Invalid withdraw proof"
            );  // 验证3
        
            nullifierHashes[_nullifierHash] = true;
            _processWithdraw(_recipient, _relayer, _fee, _refund);
            emit Withdrawal(_recipient, _nullifierHash, _relayer, _fee);
          }
        

    Privacy Pools

    1. 证明Withdraw来自于历史Deposit的全集 => 子集(称作Association Set)

      https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4563364

      https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4563364

    2. Association Set Providers(ASPs)中心化地发布Association Sets,用户选择一个包含自己Deposit的进行证明

      1. 可以定期把子集的root发布到链上,链上要求只能提交子集的proof
      2. 也可以链上证全集,链下证子集并发给审查方
    3. Association Set的可以采用包含好的和去除坏的等表示方式

      https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4563364

      https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4563364

    4. Association Set选取Deposit可以有多种方式

      1. Deposit 7天没问题则加入(用户Deposit后7天才能从Privacy Pool中Withdraw)
      2. 用户每月Deposit总额度低于阈值则加入(认为小额安全)
      3. AI打分等

总结

  1. 混淆的过程排除了坏的Deposit,降低了混淆范围,从而让坏的Deposit可被追踪,有利于Regulatory Compliance
  2. 链上默认提交对于Association Set的proof话,涉及到Association Set的Oracle和坏Deposit发现延迟的问题待实现和解决
  3. 链下主动提交的话,则无法强制用户生成并发布Association Set的proof,则应用仍无法做到完全的Regulatory Compliance