紹介:
最近、Vitalikといくつかの学者が共同で新しい論文を発表し、Tornado Cashがどのように反マネーロンダリング機構を実装しているかに触れました(基本的には、引き出し者が自分の預金履歴が汚染された資金を含まないセットに属していることを証明できるようにします)。しかし、その論文にはTornado Cashのビジネスロジックや原則の入念な説明が欠けており、一部の読者は表面的な理解しか得られませんでした。
Worth noting is that projects like Tornado, which represent privacy ventures, genuinely utilize the zero-knowledge aspect of the ZK-SNARK algorithm. Meanwhile, most solutions brandishing the ZK banner, such as Rollups, merely harness the succinctness of ZK-SNARK. Often, people tend to conflate Validity Proof with ZK, and Tornado serves as an excellent example to clarify the real-world application of ZK.
この記事の著者は、2022年にWeb3Caff ResearchのためにTornadoの原則について記事を執筆していました。 今日、その元の作品の一部を抜粋し、拡大してTornado Cashの体系的な理解を提供しています。
元の記事リンク:https://research.web3caff.com/zh/archives/2663?ref=157
Tornado Cashは、そのミキシングプロトコルとしてゼロ知識証明を利用しています。古いバージョンは2019年に発売されましたが、更新されたモデルのベータ版は2021年末にリリースされました。Tornadoの以前のバージョンは、オンチェーンの契約がオープンソースであり、マルチシグネチャの制御から解放されているため、かなりの分散化レベルを達成しました。さらに、フロントエンドコードはオープンソースであり、IPFSネットワークでバックアップされています。古いTornadoバージョンのシンプルさから、この記事ではそれを説明することに焦点を当てています。
トルネードの主要なアプローチは、多数の入金と出金のアクションを一緒に混ぜることです。トルネードにトークンを預けた後、預け入れ者は前回の預入を検証するZKプルーフを提出し、新しいアドレスを使用して引き出します。これにより、預入と引き出しのアドレスの関連性が断ち切られます。
より簡潔に言えば、竜巻をガラス箱に例えると、多くの個人が預けたコイン(Coins)で満たされています。コインを預けた人はわかりますが、これらのコインは非常に均質です。もし誰かが知らない人が箱からコインを取ったら、最初にそのコインを入れた人を追跡するのは難しいでしょう。
(画像ソース:rareskills)
そのようなシナリオは日常的に見られます。UniswapのプールからいくつかのETHをSWAPすると、Uniswapには多数の流動性提供者がいるため、受け取ったETHが誰のものかを特定することは不可能です。ただし、違いはプロセスにあります。Uniswapでは、トークンを交換するには同等価値の他のトークンが必要であり、資金は「プライベート」に転送することはできません。一方、ミキサーは単に引き出し者が入金証明書を提示することを要求します。
入金と引き出しのアクションを均一に見せるために、Tornadoプールは入金と引き出しの金額に一貫性を保ちます。たとえば、プールに100人の入金者と100人の引き出し者がいる場合、アクションは公に見えても、それらの間にはつながりがないように見えます。誰もが同じ金額を入金し、引き出すため、資金の動きを追跡するのは難しくなります。明らかに、これはマネーロンダリングに対する固有の利点を提供します。
重要な問題は次のようになります:引き出し時に、前もっての入金をどのように証明すればよいのでしょうか?引き出しをイニシエートするアドレスは、いかなる入金アドレスともリンクされていませんので、引き出しの権利をどのように確認すればよいのでしょうか?最も直接的な方法は、引き出しを行う人が自分の入金記録を明らかにすることですが、それにより自分の身元が露呈されてしまいます。これがゼロ知識証明が活躍する場面です。
ZKプルーフを使用すると、引き出し者はトルネード契約に預金記録があること、そしてこの預金がまだ引き出されていないことを確認できます。ゼロ知識証明の美しいところは、プライバシーが保護されることです。一般の人は引き出し者が実際に預金をしたことを知ることはできますが、その具体的な身元を特定することはできません。
「「トルネードプールに入金したことを証明する」ということは、「私の入金記録はトルネード契約にあります」と訳されます。 Cnが入金記録を示す場合、トルネードの入金記録が{C1、C2、…C100…}として設定されているとします。ボブは、自分のプライベートキーを使用してこのセット内のレコードを生成したことを証明する必要がありますが、具体的にどのCnであるかを明らかにせずに行う必要があります。これには、Merkle Proofの固有の特性が利用されています。
Tornadoのすべての預入れ記録は、オンチェーンで構築されたMerkle Treeに集約されます。これらの葉の大部分(約2^20、100万以上)は空白のまま(初期値付き)。新しい預入れごとに対応するコミットメント葉が更新され、その後木のルートが更新されます。
例えば、Bobの入金がTornadoの歴史で10000番目だった場合、関連する値Cnはその木の10000番目の葉、つまり、C10000 = Cnとなります。その後、契約は自動的に新しいRootを計算します。
(画像出典:RareSkills)
Merkle Proof自体は簡潔で効率的です。トランザクションTDがMerkle Tree内に存在することを証明するには、関連するMerkle Proofを提供するだけで十分であり、Merkle Treeが広大であってもコンパクトなままです。
トランザクションH3が実際にMerkle Treeに含まれていることを検証するには、H3とMerkle Treeからの他のデータを使用してRootを生成できることを証明する必要があります。このデータ(Tdを含む)はMerkle Proofを構成します。Bobが引き出しを行いたいとき、彼は2つのことを検証する必要があります:
·Cnは、Tornadoによってオンチェーン上に構築されたMerkle Treeに存在し、Cnを含むMerkle Proofを構築することができます;
·Cnはボブの入金伝票に関連しています。
Tornadoのユーザーインターフェースのフロントエンドコードでは、多くの機能が事前に実装されています。預金者がTornado Cashのウェブページを開き、預金ボタンをクリックすると、添付のフロントエンドコードが2つのランダムな数値Kとrをローカルで生成します。その後、Cn=Hash(K, r)の値を計算し、Cn(以下の図でコミットメントと呼ばれます)をTornado契約に渡してそのMerkle Treeに組み込まれます。要するに、Kとrはプライベートキーのように機能します。これらは重要であり、ユーザーはそれらを安全に保管するようにアドバイスされています。なぜなら、これらは引き出しプロセス中に再度必要とされるからです。
「encryptedNote」は、ユーザーが資格情報Kとrを秘密鍵で暗号化してチェーン上に保存し、忘れるのを防ぐためのオプション機能です。
上記のすべての操作はオフチェーンで行われるため、Tornado契約または外部の観察者はKとrに気づいていません。Kとrが露出されると、ウォレットの秘密鍵が盗まれたのと同じです。
ユーザーの入金および計算されたCn=Hash(K, r)を受け取ると、Tornado契約はCnをMerkle Treeの基本レベルに配置し、新しい葉ノードに変換し、その後ルートの値を更新します。ただし、このMerkle Treeの葉は契約のステータスに記録されず、過去のブロックのイベントパラメータとしてのみ記録されています。Tornado契約はMerkle rootのみをログに記録します。引き出し時、ユーザーはMerkle Proofを介して、入金記録が現在のMerkle rootに対応していることを証明できます。これは、軽量クライアントのクロスチェーンブリッジ引き出しにやや似た概念です。この設計により、Tornadoはガスコストを節約しようとしています。完全なMerkle treeは契約のステータスに記録されず、そのルートのみが記録されます。木の葉は単に歴史的なブロックレコードに記録され、これはRollupのガス節約原則にやや似たメカニズムです(詳細は異なります)。
出金プロセス中、出金者はフロントエンドのウェブページに入金時に生成された資格情報/プライベートキー(ランダムな数字Kとr)を入力します。Tornado Cashフロントエンドコードは、Kとr、Cn=Hash(K, r)、およびCnに対応するMerkle Proofを利用してZK Proofを生成し、これにより、CnがMerkle Tree上の入金記録に対応していること、そしてKとrがCnの有効な資格情報であることが確認されます。このステップは、実質的にMerkle Tree上の入金記録のキーの知識を証明します。ZK ProofがTornado契約に提出されると、4つのパラメータが隠され、Tornado契約自体を含む第三者が気づかないようになり、ユーザーのプライバシーが保護されます。
興味深いのは、預金取引が1つのランダムな数字ではなく、Kとrという2つのランダムな数字を使用してCnを生成することです。1つのランダムな数字だけでは安全でない可能性があり、総当たり攻撃にさらされる可能性があるためです。
この図の記号「A」に関して、それは引き出しを受け取るアドレスを表し、引き出し者によって提供されます。一方、「nf」はリプレイ攻撃を防ぐために設定された識別子であり、その値はnf=Hash(K)と決定されます。ここでKは入金時に使用される2つのランダムな数値(Kとr)の1つであり、Cnを生成するために使用されます。したがって、それぞれのCnに対応するnfがあり、その2つは一意にリンクされています。
リプレイ攻撃を防ぐ必要があるのはなぜですか?ミキサーの設計上の特徴により、引き出し時には、Merkle Tree内のどの預金が引き出された資金に対応しているかが不明です。預金者と引き出された金額の間の接続が不明瞭なままであるため、悪意のあるユーザーはこれを悪用し、ミキサーから繰り返し引き出しを行い、トークンのプールを枯渇させる可能性があります。
ここでは、nf識別子は、イーサリアムアドレスごとに固有のトランザクションカウンター「nonce」と同様の機能を果たし、トランザクションのリプレイを防ぐために設定されています。引き出しリクエスト時には、ユーザーはnfを提出する必要があります。システムはこのnfが以前に使用されたかどうかをチェックし、使用済みの場合は引き出しが無効になります。未使用の場合は引き出しが進行し、nfが記録され、その後の使用は無効化されることが保証されます。
Some might wonder: Can someone fabricate an nf that the contract hasn’t recorded? That’s unlikely. During the generation of ZK Proof, it’s essential to ensure nf=Hash(K), and the random number K is linked to the deposit record Cn. If someone arbitrarily creates an nf, it won’t match any of the recorded deposits, rendering the generation of a valid ZK Proof impossible, subsequently stalling the withdrawal process.
他の人々は疑問に思うかもしれません: nfを使用せずに回避する方法はあるのでしょうか?引き出しを行う者は特定のCnへの接続を証明するZK証明を提出しなければならないため、対応するZK証明がすでにオンチェーンに記録されているかどうかをチェックすれば十分ではないでしょうか?ただし、Tornado Cash契約に関連するコストは過大であり、以前に提出されたZK証明を永続的に保存してストレージの浪費を回避することはありません。新しいZK証明を既存のものと比較して一貫性を確認することは、単にnfのようなコンパクトな識別子を記録するよりもはるかにリソースを消費する作業です。
出金機能のコード例によると、必要なパラメータとビジネスロジックは次のとおりです:ユーザーはZKプルーフ、nf(NullifierHash)= Hash(K)、および出金のための受取人アドレスを提出します。ZKプルーフは、Cn、K、およびrの値を隠蔽し、外部世界がユーザーのアイデンティティを特定できないようにします。通常、受取人は個人情報を明かさないためにクリーンで新しいアドレスを指定します。
しかし、小さな課題が発生します。ユーザーが引き出しを行う際、追跡不可能性のために、頻繁に新しく生成されたアドレスを使用して引き出しトランザクションを開始します。そのような場合、これらの新しいアドレスにはガス手数料をカバーするETHが不足しています。したがって、引き出し時には、アドレスは明示的にリレーアを宣言してガス手数料をカバーする必要があります。その後、ミキサー契約は、ユーザーの引き出しから一部を差し引いて、リレーアを補償します。
結論として、Tornado Cashは預金者と引き出し者の間の接続を曖昧にすることができます。ユーザーベースが大規模な場合、これは犯罪者がにぎやかな群衆に紛れ込むのに似ており、当局が追跡するのが難しい状況と言えます。引き出しプロセスでは、ZK-SNARKを採用しており、隠された「証人」部分には引き出し者に関する重要な情報が含まれています。これはおそらくミキサーの最も重要な機能と言えるでしょう。現時点では、TornadoはZKに関連した最も賢いアプリケーションの1つかもしれません。
Пригласить больше голосов
Содержание
紹介:
最近、Vitalikといくつかの学者が共同で新しい論文を発表し、Tornado Cashがどのように反マネーロンダリング機構を実装しているかに触れました(基本的には、引き出し者が自分の預金履歴が汚染された資金を含まないセットに属していることを証明できるようにします)。しかし、その論文にはTornado Cashのビジネスロジックや原則の入念な説明が欠けており、一部の読者は表面的な理解しか得られませんでした。
Worth noting is that projects like Tornado, which represent privacy ventures, genuinely utilize the zero-knowledge aspect of the ZK-SNARK algorithm. Meanwhile, most solutions brandishing the ZK banner, such as Rollups, merely harness the succinctness of ZK-SNARK. Often, people tend to conflate Validity Proof with ZK, and Tornado serves as an excellent example to clarify the real-world application of ZK.
この記事の著者は、2022年にWeb3Caff ResearchのためにTornadoの原則について記事を執筆していました。 今日、その元の作品の一部を抜粋し、拡大してTornado Cashの体系的な理解を提供しています。
元の記事リンク:https://research.web3caff.com/zh/archives/2663?ref=157
Tornado Cashは、そのミキシングプロトコルとしてゼロ知識証明を利用しています。古いバージョンは2019年に発売されましたが、更新されたモデルのベータ版は2021年末にリリースされました。Tornadoの以前のバージョンは、オンチェーンの契約がオープンソースであり、マルチシグネチャの制御から解放されているため、かなりの分散化レベルを達成しました。さらに、フロントエンドコードはオープンソースであり、IPFSネットワークでバックアップされています。古いTornadoバージョンのシンプルさから、この記事ではそれを説明することに焦点を当てています。
トルネードの主要なアプローチは、多数の入金と出金のアクションを一緒に混ぜることです。トルネードにトークンを預けた後、預け入れ者は前回の預入を検証するZKプルーフを提出し、新しいアドレスを使用して引き出します。これにより、預入と引き出しのアドレスの関連性が断ち切られます。
より簡潔に言えば、竜巻をガラス箱に例えると、多くの個人が預けたコイン(Coins)で満たされています。コインを預けた人はわかりますが、これらのコインは非常に均質です。もし誰かが知らない人が箱からコインを取ったら、最初にそのコインを入れた人を追跡するのは難しいでしょう。
(画像ソース:rareskills)
そのようなシナリオは日常的に見られます。UniswapのプールからいくつかのETHをSWAPすると、Uniswapには多数の流動性提供者がいるため、受け取ったETHが誰のものかを特定することは不可能です。ただし、違いはプロセスにあります。Uniswapでは、トークンを交換するには同等価値の他のトークンが必要であり、資金は「プライベート」に転送することはできません。一方、ミキサーは単に引き出し者が入金証明書を提示することを要求します。
入金と引き出しのアクションを均一に見せるために、Tornadoプールは入金と引き出しの金額に一貫性を保ちます。たとえば、プールに100人の入金者と100人の引き出し者がいる場合、アクションは公に見えても、それらの間にはつながりがないように見えます。誰もが同じ金額を入金し、引き出すため、資金の動きを追跡するのは難しくなります。明らかに、これはマネーロンダリングに対する固有の利点を提供します。
重要な問題は次のようになります:引き出し時に、前もっての入金をどのように証明すればよいのでしょうか?引き出しをイニシエートするアドレスは、いかなる入金アドレスともリンクされていませんので、引き出しの権利をどのように確認すればよいのでしょうか?最も直接的な方法は、引き出しを行う人が自分の入金記録を明らかにすることですが、それにより自分の身元が露呈されてしまいます。これがゼロ知識証明が活躍する場面です。
ZKプルーフを使用すると、引き出し者はトルネード契約に預金記録があること、そしてこの預金がまだ引き出されていないことを確認できます。ゼロ知識証明の美しいところは、プライバシーが保護されることです。一般の人は引き出し者が実際に預金をしたことを知ることはできますが、その具体的な身元を特定することはできません。
「「トルネードプールに入金したことを証明する」ということは、「私の入金記録はトルネード契約にあります」と訳されます。 Cnが入金記録を示す場合、トルネードの入金記録が{C1、C2、…C100…}として設定されているとします。ボブは、自分のプライベートキーを使用してこのセット内のレコードを生成したことを証明する必要がありますが、具体的にどのCnであるかを明らかにせずに行う必要があります。これには、Merkle Proofの固有の特性が利用されています。
Tornadoのすべての預入れ記録は、オンチェーンで構築されたMerkle Treeに集約されます。これらの葉の大部分(約2^20、100万以上)は空白のまま(初期値付き)。新しい預入れごとに対応するコミットメント葉が更新され、その後木のルートが更新されます。
例えば、Bobの入金がTornadoの歴史で10000番目だった場合、関連する値Cnはその木の10000番目の葉、つまり、C10000 = Cnとなります。その後、契約は自動的に新しいRootを計算します。
(画像出典:RareSkills)
Merkle Proof自体は簡潔で効率的です。トランザクションTDがMerkle Tree内に存在することを証明するには、関連するMerkle Proofを提供するだけで十分であり、Merkle Treeが広大であってもコンパクトなままです。
トランザクションH3が実際にMerkle Treeに含まれていることを検証するには、H3とMerkle Treeからの他のデータを使用してRootを生成できることを証明する必要があります。このデータ(Tdを含む)はMerkle Proofを構成します。Bobが引き出しを行いたいとき、彼は2つのことを検証する必要があります:
·Cnは、Tornadoによってオンチェーン上に構築されたMerkle Treeに存在し、Cnを含むMerkle Proofを構築することができます;
·Cnはボブの入金伝票に関連しています。
Tornadoのユーザーインターフェースのフロントエンドコードでは、多くの機能が事前に実装されています。預金者がTornado Cashのウェブページを開き、預金ボタンをクリックすると、添付のフロントエンドコードが2つのランダムな数値Kとrをローカルで生成します。その後、Cn=Hash(K, r)の値を計算し、Cn(以下の図でコミットメントと呼ばれます)をTornado契約に渡してそのMerkle Treeに組み込まれます。要するに、Kとrはプライベートキーのように機能します。これらは重要であり、ユーザーはそれらを安全に保管するようにアドバイスされています。なぜなら、これらは引き出しプロセス中に再度必要とされるからです。
「encryptedNote」は、ユーザーが資格情報Kとrを秘密鍵で暗号化してチェーン上に保存し、忘れるのを防ぐためのオプション機能です。
上記のすべての操作はオフチェーンで行われるため、Tornado契約または外部の観察者はKとrに気づいていません。Kとrが露出されると、ウォレットの秘密鍵が盗まれたのと同じです。
ユーザーの入金および計算されたCn=Hash(K, r)を受け取ると、Tornado契約はCnをMerkle Treeの基本レベルに配置し、新しい葉ノードに変換し、その後ルートの値を更新します。ただし、このMerkle Treeの葉は契約のステータスに記録されず、過去のブロックのイベントパラメータとしてのみ記録されています。Tornado契約はMerkle rootのみをログに記録します。引き出し時、ユーザーはMerkle Proofを介して、入金記録が現在のMerkle rootに対応していることを証明できます。これは、軽量クライアントのクロスチェーンブリッジ引き出しにやや似た概念です。この設計により、Tornadoはガスコストを節約しようとしています。完全なMerkle treeは契約のステータスに記録されず、そのルートのみが記録されます。木の葉は単に歴史的なブロックレコードに記録され、これはRollupのガス節約原則にやや似たメカニズムです(詳細は異なります)。
出金プロセス中、出金者はフロントエンドのウェブページに入金時に生成された資格情報/プライベートキー(ランダムな数字Kとr)を入力します。Tornado Cashフロントエンドコードは、Kとr、Cn=Hash(K, r)、およびCnに対応するMerkle Proofを利用してZK Proofを生成し、これにより、CnがMerkle Tree上の入金記録に対応していること、そしてKとrがCnの有効な資格情報であることが確認されます。このステップは、実質的にMerkle Tree上の入金記録のキーの知識を証明します。ZK ProofがTornado契約に提出されると、4つのパラメータが隠され、Tornado契約自体を含む第三者が気づかないようになり、ユーザーのプライバシーが保護されます。
興味深いのは、預金取引が1つのランダムな数字ではなく、Kとrという2つのランダムな数字を使用してCnを生成することです。1つのランダムな数字だけでは安全でない可能性があり、総当たり攻撃にさらされる可能性があるためです。
この図の記号「A」に関して、それは引き出しを受け取るアドレスを表し、引き出し者によって提供されます。一方、「nf」はリプレイ攻撃を防ぐために設定された識別子であり、その値はnf=Hash(K)と決定されます。ここでKは入金時に使用される2つのランダムな数値(Kとr)の1つであり、Cnを生成するために使用されます。したがって、それぞれのCnに対応するnfがあり、その2つは一意にリンクされています。
リプレイ攻撃を防ぐ必要があるのはなぜですか?ミキサーの設計上の特徴により、引き出し時には、Merkle Tree内のどの預金が引き出された資金に対応しているかが不明です。預金者と引き出された金額の間の接続が不明瞭なままであるため、悪意のあるユーザーはこれを悪用し、ミキサーから繰り返し引き出しを行い、トークンのプールを枯渇させる可能性があります。
ここでは、nf識別子は、イーサリアムアドレスごとに固有のトランザクションカウンター「nonce」と同様の機能を果たし、トランザクションのリプレイを防ぐために設定されています。引き出しリクエスト時には、ユーザーはnfを提出する必要があります。システムはこのnfが以前に使用されたかどうかをチェックし、使用済みの場合は引き出しが無効になります。未使用の場合は引き出しが進行し、nfが記録され、その後の使用は無効化されることが保証されます。
Some might wonder: Can someone fabricate an nf that the contract hasn’t recorded? That’s unlikely. During the generation of ZK Proof, it’s essential to ensure nf=Hash(K), and the random number K is linked to the deposit record Cn. If someone arbitrarily creates an nf, it won’t match any of the recorded deposits, rendering the generation of a valid ZK Proof impossible, subsequently stalling the withdrawal process.
他の人々は疑問に思うかもしれません: nfを使用せずに回避する方法はあるのでしょうか?引き出しを行う者は特定のCnへの接続を証明するZK証明を提出しなければならないため、対応するZK証明がすでにオンチェーンに記録されているかどうかをチェックすれば十分ではないでしょうか?ただし、Tornado Cash契約に関連するコストは過大であり、以前に提出されたZK証明を永続的に保存してストレージの浪費を回避することはありません。新しいZK証明を既存のものと比較して一貫性を確認することは、単にnfのようなコンパクトな識別子を記録するよりもはるかにリソースを消費する作業です。
出金機能のコード例によると、必要なパラメータとビジネスロジックは次のとおりです:ユーザーはZKプルーフ、nf(NullifierHash)= Hash(K)、および出金のための受取人アドレスを提出します。ZKプルーフは、Cn、K、およびrの値を隠蔽し、外部世界がユーザーのアイデンティティを特定できないようにします。通常、受取人は個人情報を明かさないためにクリーンで新しいアドレスを指定します。
しかし、小さな課題が発生します。ユーザーが引き出しを行う際、追跡不可能性のために、頻繁に新しく生成されたアドレスを使用して引き出しトランザクションを開始します。そのような場合、これらの新しいアドレスにはガス手数料をカバーするETHが不足しています。したがって、引き出し時には、アドレスは明示的にリレーアを宣言してガス手数料をカバーする必要があります。その後、ミキサー契約は、ユーザーの引き出しから一部を差し引いて、リレーアを補償します。
結論として、Tornado Cashは預金者と引き出し者の間の接続を曖昧にすることができます。ユーザーベースが大規模な場合、これは犯罪者がにぎやかな群衆に紛れ込むのに似ており、当局が追跡するのが難しい状況と言えます。引き出しプロセスでは、ZK-SNARKを採用しており、隠された「証人」部分には引き出し者に関する重要な情報が含まれています。これはおそらくミキサーの最も重要な機能と言えるでしょう。現時点では、TornadoはZKに関連した最も賢いアプリケーションの1つかもしれません。