4

保姆级教程:如何在 JavaScript 项目中使用 zk - SNARK - 碳链价值

 1 year ago
source link: https://www.ccvalue.cn/article/1408180.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

保姆级教程:如何在 JavaScript 项目中使用 zk-SNARK

 •  9 小时前
在 JavaScript 中使用 zk-SNARK 的简易教程请拿好。

原文标题:《Zero-Knowledge Proofs Using SnarkJS and Circom

撰文:Laszlo Fazekas

编译:ChinaDeFi

零知识证明技术,尤其是 zk-SNARK 技术是加密领域最令人兴奋的技术之一,因为:

  • 我们可以在不泄漏具体信息的同时证明该信息。
  • 证明很小,很容易在区块链上进行验证,所以可以 Rollup。

Rollup 是一种区块链扩展解决方案,其计算是在链下完成的,在给定数量的交易后,状态将同步回区块链,这种解决方案可以为我们提供区块链的安全性和更低的 gas 费,所以我们说 zk-Rollup 是区块链的理想扩展解决方案。

在本文中,作者会向我们展示如何在 JavaScript 项目中使用 zk-SNARK。

众所周知,我们需要一个电路来生成零知识证明。电路是系统用来计算输出和证明的数学表达式。零知识证明本身就是我们已经成功完成计算的证明。

电路可能会非常复杂,但好在有电路编程语言和库可以让我们比较轻松的编写自己的电路。在本文中我们会使用 Circom。Circom 是用 Rust 编写的。可以使用以下命令来安装 Rust 环境。

curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh'=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

安装完 Rust 后,克隆 Circom 存储库并构建编译器:

git clone https://github.com/iden3/circom.gitclone https://github.com/iden3/circom.gitcd circomcargo build --releasecargo install --path circom

如果这过程中没有差池,那么我们已经安装好了 Circom 编译器。

现在还需要解决 Circomlib,Circomlib 是一个包含许多有用的预定义电路的编程库。因此,创建一个空项目,并使用以下代码安装 Circomlib:

npm initinitnpm i circomlib

现在,我们已经为创建电路做好了准备,下面是它应该看起来的样子:

pragma circom 2.0.0;2.0.0;include "node_modules/circomlib/circuits/poseidon.circom";template PoseidonHasher() {signal input in;signal output out;component poseidon = Poseidon(1);poseidon.inputs[0] <== in;out <== poseidon.out;}component main = PoseidonHasher();

这个简单的电路,有一个专用输入和一个输出信号。我们正在使用 Circomlib 中的 poseidon 哈希计算器来生成输入 hash。使用此电路,可以证明我们已经知道给定的原始数据 hash,但不需要透露它。

在第一步中,可以通过 Circom 编译器来编译电路,该编译器将生成一个 wasm 和 rlcs 文件。

circom poseidon_hasher.circom --wasm --r1cs -o ./build

生成的 wasm 和 rlcs 文件在构建文件夹中可用。要生成证明,我们需要一个证明密钥文件,而要生成这个文件,我们就需要一个 ptau 文件。该 ptau 文件可以由 snarkjs 生成。或者也可以下载一个预生成的文件(可以在 snarkjs 存储库中找到链接)。关于测试,生成的文件对我们有些好处,但在我们生产应用程序中,建议生成自己的 ptau。

wget https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_12.ptau

现在可以使用电路和 ptau 文件生成证明密钥(zkey 文件):

npx snarkjs groth16 setup build/poseidon_hasher.r1cs powersOfTau28_hez_final_12.ptau circuit_0000.zkey

不建议将此 zkey 文件用于生产,但对于测试,它对我们有帮助。

现在,我们已经准备好生成证明了。这其中会用到 snarkjs,所以用下面的命令进行安装:

npm i snarkjs

证明生成如下所示:

const { proof, publicSignals } = await snarkjs.groth16.fullProve({ in: 10 },"build/poseidon_hasher_js/poseidon_hasher.wasm","circuit_0000.zkey");console.log(publicSignals);console.log(proof);

输入信号在函数的第一个参数中传递 fullProve。第二个参数是编译电路,最后一个参数是生成的证明密钥。该函数反馈电路的输出和证明。

现在我们需要一个可以从证明密钥生成的验证密钥来验证证明。获取方法如下:

npx snarkjs zkey export verificationkey circuit_0000.zkey verification_key.jsonexport verificationkey circuit_0000.zkey verification_key.json 验证码如下:const vKey = JSON.parse(fs.readFileSync("verification_key.json"));const res = await snarkjs.groth16.verify(vKey, publicSignals, proof);if (res === true) {console.log("Verification OK");} else {console.log("Invalid proof");}

验证密钥是 verify 函数的第一个参数,输出和证明是第二和第三个参数。该函数的结果是一个简单的布尔值。

在此例子中,我们使用电路来计算 hash,但这并不总是可行的,因为 hash 可以使部分结果,或者我们的电路看起来像如下所示:

pragma circom 2.0.0;2.0.0;include "node_modules/circomlib/circuits/poseidon.circom";template PoseidonHasher() {signal input in;signal input hash;component poseidon = Poseidon(1);poseidon.inputs[0] <== in;hash === poseidon.out;}component main {public [hash]} = PoseidonHasher();

这个电路没有输出,只有两个输入。第一个输入是数据,第二个输入是数据的哈希。在模板的最后一行,我们检查 hash。只有给定的 hash 是给定数据的 poseidon hash,电路才会成功运行。但是要如何在 JS 中计算 poseidon hash 呢?

Circomlib 有一个可以用于此的 JS 实现。需要我们安装它:

npm i circomlibjs

现在我们可以用下面的代码来进行计算:

const poseidon = await circomlibjs.buildPoseidon();const poseidon = await circomlibjs.buildPoseidon();const hash = poseidon.F.toString(poseidon([10]));console.log(hash);

该 poseidon 函数结果是 Buffer,我们需要将其转换为数字。在 zk-SNARK 中,每次计算都是在有限域中完成的,所以我们必须使用 poseidon.F.toString 进行转换。

Circomlibjs 和 snarkjs 在 Node.js 和浏览器中运行良好,所以我们可以在客户端生成或验证证明,还可以生成用于验证的智能合约。这样我们就可以在 Solidity 代码中使用它来验证证明。

Circomlibjs 也有智能合约生成器。

这是在 JavaScript 中使用 zk-SNARK 的简短教程,它不是一个完整教程,大家可能还存有很多问题,我们可以借助 Circom 和 snarkjs,他们都有很好的文档记录,我们也可以从 Tornado Cash 等现有项目中学到很多东西。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK