ZKP应用实例之哈希与其原像知识
本实例,将实现一个在区块链用例中非常典型的操作:证明给定哈希摘要的原像知识。 特别是,假设证明者(Peggy)向验证者(Victor)毫无疑问地证明她知道摘要的哈希原像 ,但没有透露原像是什么。
- 本实例以zokrates为ZKP工具(iden3亦可)。
1. 计算hash
我们将通过使用 ZoKrates 计算任意选择的原像的哈希值来开始本教程,在本例中,原像内容为数字 5。
首先,我们创建一个名为 hashexample.zok 的新文件,内容如下:
1 | import "hashes/sha256/512bitPacked" as sha256packed; |
第一行从 ZoKrates 标准库导入 sha256packed 函数。
sha256packed 是一个 SHA256 的实现。它是这样工作的:我们想将 512 位的输入传递给 SHA256。 但是,由于其背后使用的基础字段的原因,Zokrates中字段值只能容纳 254 位,无法容纳256位的输入。因此,我们使用四个字段元素,每个元素编码 128 位,来表示我们的输入。然后这四个元素在 ZoKrates 中连接起来并传递给 SHA256。 鉴于生成的散列长度为 256 位,我们将其一分为二并将每个值作为 128 位数字返回。
如上,代码实际上只是使用 sha256packed,返回计算出的哈希值。
1.1 首先,我们使用编译命令将程序编译成一个运算电路。
1 | zokrates compile -i hashexample.zok |
1.2 第二步,我们可以使用以下命令创建见证文件
1 | zokrates compute-witness -a 0 0 0 5 |
使用标志 -a 我们将参数传递给程序。 回想一下,我们的目标是计算数字 5 的哈希值。因此我们将 a、b 和 c 设置为 0,将 d 设置为 5。
此时,我们可以检查 witness 文件中的返回值:
1 | grep '~out' witness |
因此,通过将输出连接为 128 位数字,我们得到以下值作为我们选择的原像的哈希值:
1 | // 计算5的sha256 |
此处,愿像的hash值‘c6481e22c5ff4164af680b8cfaa5e8ed3120eeff89c4f307c4a6faaae059ce10’ 与 witness中out_0 out_1拼接后的hash内容是一致的。
2. 证明原像知识
现在,我们已经看到我们可以使用 ZoKrates 计算哈希值。
让我们回顾一下我们的目标:Peggy 想证明她知道 Victor 选择的摘要的原像,但不透露原像是什么。 现在让我们假设 Victor 选择摘要作为我们在上面的示例中找到的摘要。
为了让它发挥作用,双方必须遵循他们在协议中的角色:
2.1 Victor 必须指定他感兴趣的哈希
因此,我们必须调整由 ZoKrates 编译的 zkSNARK 电路,这样除了计算摘要外,它还根据 Victor 提供的感兴趣的摘要对其进行验证。 这导致 hashexample.zok 的以下更新:
1 | import "hashes/sha256/512bitPacked" as sha256packed; |
请注意,现在将 sha256packed 的结果与 Victor 定义的硬编码正确解决方案进行比较。 我们添加的行被视为断言:验证者不会接受不满足这些约束的证明。 显然,如果所有计算的位都相等,则此程序仅返回 1。
2.2 Victor 现在可以编译代码
1 | zokrates compile -i hashexample.zok |
setup创建一个 verification.key 文件和一个 proving.key 文件。 Victor把证明钥匙给了Peggy。
2.3 Peggy 提供正确的原像作为程序的参数
1 | zokrates compute-witness -a 0 0 0 5 |
2.4 Peggy 可以运行命令来构建证明
1 | zokrates generate-proof |
由于输入在程序中被声明为私有,因此由于协议的零知识属性,它们不会出现在证明中。
ZoKrates 创建一个文件 proof.json,由构成 zkSNARKs 证明的三个椭圆曲线点组成。 Victor 部署的智能合约中的 verifyTx 函数接受这三个值以及一系列公共输入。公共输入数组包括:
- main 函数的任何公共输入,声明时没有使用 private 关键字
- ZoKrates 函数的返回值
在本示例中,所有输入都是私有的,并且只有一个返回值 1。
2.5 然后 Peggy 可以通过调用 verifyTx 提交她的证明
2.6 Victor 监控验证智能合约以获取 Peggy 交易的返回值
一旦Victor观察到来自 Peggy 的公共地址的具有真实返回值的交易,Victor就可以确定Peggy拥有他在智能合约中设置的哈希值的有效原像。
3.延伸
在此示例中只涉及两方。这种特殊情况使得处理 zkSNARKs 的信任假设变得容易:只有 Victor 对验证 Peggy 的声明感兴趣,因此他可以信任他对设置阶段的执行。
一般来说,多方可能有兴趣验证Peggy声明的正确性。例如,在基于零知识的加密货币 Zcash 中,每个节点都需要能够验证交易的正确性。为了将设置阶段推广到这些多方用例,需要执行一个通常称为“可信设置”或“仪式”的过程。
即可以实现 - https://willzhuang.github.io/2020/06/23/%E4%BD%93%E9%AA%8Czksync-2/
4.结论
这可能算做一个知识证明,但是题目中的应用实例,是什么呢?
参考链接 - circom - https://willzhuang.github.io/2021/05/06/circom%E8%AF%95%E7%94%A8/