Skip to content

Tornado Cash Classicのコントラクト

コントラクト構成

コントラクト 説明
Tornado.sol プールを管理する抽象コントラクト。入出金の共通処理とインターフェースを定めている。
ETHTornado.sol Ether用プールのコントラクト。Tornadoを継承。
ERC20Tornado.sol ERC20用プールのコントラクト。Tornadoを継承。
cTornado.sol CompoundのcToken用プールのコントラクト。ERC20Tornadoを継承し、Tornado CashガバナンスコントラクトへCOMPトークンを送金するために特殊化。
MerkleTreeWithHistory.sol MiMC Merkleツリーのコントラクト。
Verifier.sol ゼロ知識証明の検証を行うコントラクト。ペアリングライブラリも定義。

Pairingライブラリ

Ethereumにはペアリングのためのプリコンパイル済みコントラクトがあります。プリコンパイル済みコントラクトはSTATICCALLオペコードを利用することを想定していますが、毎回Solidityでstaticcallメンバを使うのは面倒であるため、プリコンパイル済みコントラクトのラッパー関数とよく使う処理一緒をまとめたPairingライブラリが作られています。

PRIME_Q: 21888242871839275222246405745257275088696311157297823662689037894645226208583

G1PointG2Pointの2つの構造体が定義されています。

  struct G1Point {
    uint256 X;
    uint256 Y;
  }
  struct G2Point {
    uint256[2] X;
    uint256[2] Y;
  }

関数一覧:

関数シグネチャ(引数名含む) 戻り型 説明
negate(G1Point memory p) G1Point memory
plus(G1Point memory p1, G1Point memory p2) G1Point memory
scalar_mul(G1Point memory p, uint256 s) G1Point memory
pairing(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2, G1Point memory c1, G2Point memory c2, G1Point memory d1, G2Point memory d2) bool ペアリングのチェックを行う

plus, scalar_mul, pairingは楕円曲線alt_bn128上の計算をするプリコンパイル済みコントラクトを使用しています。これらは、以下において追加されたものです。

ガスコストはEIP-1108: Reduce alt_bn128 precompile gas costsでアップデートされています。

名前* アドレス 消費ガス 入力 出力 説明
alt_bn128_add 0x06 150 x1,y1,x2,y2 x,y
alt_bn128_mul 0x07 6000 x1,y1,s x,y
alt_bn128_pairing_check 0x08 34000 * k + 45000 x1,y1,x3,x2,y3,y2 success

pairing関数では、e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1のチェックを行います。例えば、pairing([P1(), P1().negate()], [P2(), P2()])trueです。ここで、P1,P2は次のような点です。

    function P1() internal returns (G1Point) {
        return G1Point(1, 2);
    }
    function P2() internal returns (G2Point) {
        return G2Point(
            [11559732032986387107991004021392285783925812861821192530917403151452391805634,
             10857046999023057135944570762232829481370756359578518086990519993285655852781],
            [4082367875863433681332203403145435568316851327593401208105741076214120093531,
             8495653923123431417604973247489272438418190587263600148770280649306958101930]
        );
    }

Verifierコントラクト

関数一覧:

関数シグネチャ(引数名含む) 戻り型 説明
verifyingKey() VerifyingKey memory コントラクトに埋め込みされた検証鍵を返すpure関数である。
verifyProof(bytes memory proof, uint256[6] memory input) bool 証明を検証する。