stark 证明实操 python 实现 04
2023-03-21 16:32
W3.Hitchhiker
2023-03-21 16:32
订阅此专栏
收藏此文章

译者:Xiang|W3.Hitchhiker


第四部分:查询阶段

加载之前的代码

运行下面代码块以加载我们将在这部分中使用的变量。由于它会重复前面部分中所做的所有操作 - 运行需要一段时间。

from channel import Channelfrom tutorial_sessions import part1, part3 _, _, _, _, _, _, _, f_eval, f_merkle, _ = part1()fri_polys, fri_domains, fri_layers, fri_merkles, _ = part3()print('Success!')

查询上解承诺(decommit)

我们在这部分的目标是生成验证前三个部分的承诺所需的所有信息。 这部分我们写了两个函数:

  1. decommit_on_fri_layers - 以特定索引采样时,通过信道发送数据显示每个 FRI 层与其他层一致。

  2. decommit_on_query - 发送轨迹上解承诺所需的数据,然后调用 decommit_on_fri_layers

在 FRI 层上解承诺

实施 decommit_on_fri_layers 函数。 该函数获取索引和信道,并通过信道发送相关数据以验证 FRI 层的正确性。 更具体地说,它迭代 fri_layersfri_merkles 并且在每次迭代中它发送以下数据(按规定的顺序):

请注意,我们发送最后一层元素的身份验证路径。 在最后一层,所有元素都是相等的,无论查询如何,因为它们是常数多项式的评估。

(请记住在通过信道发送之前将非字符串变量转换为字符串。)

def decommit_on_fri_layers(idx, channel):    for layer, merkle in zip(fri_layers[:-1], fri_merkles[:-1]):        length = len(layer)        idx = idx % length        sib_idx = (idx + length // 2) % length                channel.send(str(layer[idx]))        channel.send(str(merkle.get_authentication_path(idx)))        channel.send(str(layer[sib_idx]))        channel.send(str(merkle.get_authentication_path(sib_idx)))           channel.send(str(fri_layers[-1][0]))

跑测试:

# Test against a precomputed hash.test_channel = Channel()for query in [7527, 8168, 1190, 2668, 1262, 1889, 3828, 5798, 396, 2518]:    decommit_on_fri_layers(query, test_channel)assert test_channel.state == 'ad4fe9aaee0fbbad0130ae0fda896393b879c5078bf57d6c705ec41ce240861b', 'State of channel is wrong.'print('Success!')

在轨迹多项式上解承诺

为了证明我们解承诺的 FRI 层确实是从组合多项式的评估中生成的,我们还必须发送:

验证者知道组合多项式的随机系数,可以计算其在 x 处的评估,并将其与第一个 FRI 层发送的第一个元素进行比较。

因此,函数 decommit_on_query 应该通过信道发送上述(1、2 和 3),然后调用 decommit_on_fri_layers

提示:f_eval是组合多项式的评估,f_merkle是对应的 Merkle 树。

def decommit_on_query(idx, channel):     assert idx + 16 < len(f_eval), f'query index: {idx} is out of range. Length of layer: {len(f_eval)}.'    channel.send(str(f_eval[idx])) # f(x).    channel.send(str(f_merkle.get_authentication_path(idx))) # auth path for f(x).    channel.send(str(f_eval[idx + 8])) # f(gx).    channel.send(str(f_merkle.get_authentication_path(idx + 8))) # auth path for f(gx).    channel.send(str(f_eval[idx + 16])) # f(g^2x).    channel.send(str(f_merkle.get_authentication_path(idx + 16))) # auth path for f(g^2x).    decommit_on_fri_layers(idx, channel)   

一组查询的解承诺

为了完成证明,证明者从信道中获取一组随机查询,即 0 到 8191 之间的索引,并在每个查询上解承诺。

使用你刚刚实现的函数 decommit_on_query()Channel.receive_random_int 生成 3 个随机查询并在每个查询上解承诺。

def decommit_fri(channel):    for query in range(3):        # Get a random index from the verifier and send the corresponding decommitment.        decommit_on_query(channel.receive_random_int(0, 8191-16), channel)

证明时间!

运行以下将它们联系在一起的代码块,运行所有以前的代码,以及你在这部分中编写的函数,并打印证明。

import timefrom tutorial_sessions import part1, part3 start = time.time()start_all = startprint("Generating the trace...")_, _, _, _, _, _, _, f_eval, f_merkle, _ = part1()print(f'{time.time() - start}s')start = time.time()print("Generating the composition polynomial and the FRI layers...")fri_polys, fri_domains, fri_layers, fri_merkles, channel = part3()print(f'{time.time() - start}s')start = time.time()print("Generating queries and decommitments...")decommit_fri(channel)print(f'{time.time() - start}s')start = time.time()print(channel.proof)print(f'Overall time: {time.time() - start_all}s')print(f'Uncompressed proof length in characters: {len(str(channel.proof))}')

【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。

W3.Hitchhiker
数据请求中
查看更多

推荐专栏

数据请求中
在 App 打开