零知识证明可以在不泄露具体信息的情况下向其他人证明 自己掌握该信息,这听起来非常适合去中心化应用。在这个教程中, 我们将利用zksnark来实现一个具体的NodeJS零知识证明应用:渔船 无需透露自己的具体位置,就可以向监管机构证明自己处于划定的 合法捕捞区内 —— 我们的主要武器是snarkjs和circom。
1、需求分析
设计零知识证明应用方案的第一步是要将具体的问题 转换为一个电路。我们要证明渔船处于合法捕捞区内,这个问题 中存在以下变量:
- 合法捕捞区的范围,可以用该区域的经度/维度的最大值和最小值来表示
- 渔船的位置,用渔船的经度和维度来表示
容易得到如下的输入输出映射:
1 | 渔船经度/维度 ->| | |
2、circom电路实现
据此,我们可以得到如下的circom电路定义:
其中:
- latitudeRange:电路输入,表示合法捕捞区域的纬度的最小值和最大值,数组
- longitudeRange:电路输入,表示合法捕捞区域的经度的最小值和最大值,数组
- fishingLocation:电路输入,表示渔船的经度和维度,数组
- out:电路输出,1表示渔船在合法捕捞区,0表示渔船不在合法捕捞区
由于我们要隐藏渔船的具体位置,因此在上面的circom电路中,你可以看到 fishingLocation被定义为private。
3、circom电路编译
如果还没有安装circom的话,使用如下命令全局安装circom:
1 | npm install -g circom |
注意:推荐使用node 12,因为内置了原生的大数计算,效率提升10倍!
使用如下命令编译电路文件InRange.circom,输出结果命名为InRange.json:
1 | circom InRange.circom -o InRange.json |
4、zksnark的可信设置
在使用zksnark之前,需要一个可信设置,而且该可信设置依赖于具体的电路, 例如我们编译得到的InRange.json。
使用snarkjs来创建这个可信设置,同样,如果需要安装的话,使用如下命令:
1 | npm install -g snarkjs |
现在我们利用渔业监控电路进行可信设置:
1 | snarkjs setup -c InRange.json |
上面的命令将会在当前目录创建两个文件:proving_key.json和verification_key.json。 其中proving_key.json用于证明你的输入是有效的(满足电路约束),而verification_key.json 用来验证别人提供的证据。
5、计算ziksarnk电路信号的见证(witness)
在我们创建提供给其他人的证据之前,需要先计算出电路中所有信号(包括输入信号和中间信号) 的见证。为此我们需要创建一个输入文件input.json,其中包含所有输入(公开输入和私有输入)的值, 然后利用这个输入文件计算得到见证文件witness.json,这两个文件都不会公开。
下面是我们的渔业监控电路的输入文件示例:
1 | { |
使用sparkjs来计算得出见证文件witness.json:
1 | snarkjs calculatewitness -c InRange.json |
6、创建zksnark证据
有了witness.json,我们就可以创建提供给其他人的证据了:
1 | snarkjs proof |
上面的命令将在当前目录生成proof.json和公开文件public.json, publc.json实际上就是witness.json文件内容的一个子集,其中 仅包含电路中可公开信号的值。
现在目录里的文件如下图所示:
7、校验zksnark证据
现在你(渔船船长)可以把verification_key.json、proof.json和public.json提供给 监管机构了,监管方使用如下命令即可验证你的船的确在合法捕捞区内,但却不知道 你的具体位置:
1 | snarkjs verify |
GOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOD!
原文链接:Using Zero-Knowledge Proofs with Fluree
汇智网翻译整理,转载请标明出处