零知识证明实战渔业监控【zksnark】

零知识证明可以在不泄露具体信息的情况下向其他人证明 自己掌握该信息,这听起来非常适合去中心化应用。在这个教程中, 我们将利用zksnark来实现一个具体的NodeJS零知识证明应用:渔船 无需透露自己的具体位置,就可以向监管机构证明自己处于划定的 合法捕捞区内 —— 我们的主要武器是snarkjs和circom。

zksnark-fishing-vessel

用自己熟悉的语言学习以太坊DApp开发: Java | Php | Python | .Net / C# | Golang | Node.JS | Flutter / Dart

1、需求分析

设计零知识证明应用方案的第一步是要将具体的问题 转换为一个电路。我们要证明渔船处于合法捕捞区内,这个问题 中存在以下变量:

  • 合法捕捞区的范围,可以用该区域的经度/维度的最大值和最小值来表示
  • 渔船的位置,用渔船的经度和维度来表示

容易得到如下的输入输出映射:

1
2
3
4
5
6
        渔船经度/维度 ->|              |
| |
捕捞区经度最大/最小值 ->| 电路 |-> 在/不在合法捕捞区
| |
捕捞区纬度最大/最小值 ->| |
+--------------+

2、circom电路实现

据此,我们可以得到如下的circom电路定义:

zksnark-fishing-vessel

其中:

  • 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
2
3
4
5
{
"latitudeRange": [ 20, 21],
"longitudeRange": [ 176, 190],
"fishingLocation": [ 20, 180]
}

使用sparkjs来计算得出见证文件witness.json:

1
snarkjs calculatewitness -c InRange.json

6、创建zksnark证据

有了witness.json,我们就可以创建提供给其他人的证据了:

1
snarkjs proof

上面的命令将在当前目录生成proof.json和公开文件public.json, publc.json实际上就是witness.json文件内容的一个子集,其中 仅包含电路中可公开信号的值。

现在目录里的文件如下图所示:

zksnark-fishing-vessel

7、校验zksnark证据

现在你(渔船船长)可以把verification_key.json、proof.json和public.json提供给 监管机构了,监管方使用如下命令即可验证你的船的确在合法捕捞区内,但却不知道 你的具体位置:

1
snarkjs verify

GOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOD!


原文链接:Using Zero-Knowledge Proofs with Fluree

汇智网翻译整理,转载请标明出处