本教程的这一部分把前面几部分的“几个工具”整合在一起,构建一个具体、有用的 STARK 证明系统。此系统用于产生一个 STARK 证明,证明 Rescue-Prime 哈希函数在一个已知输出的秘密输入上的正确求值。该证明具体来说也是有用的,因为产生的非交互式证明同时可以作为一个后量子签名方案。
Rescue-Prime 是一个面向算术化的哈希函数,意味着它使用 AIR 会有一个紧致的描述。它是一个由 Rescue-XLIX 置换:
构建的海绵函数,包括若干个“几乎相同”的轮。每一轮由六个步骤组成:
前向-S盒(Forward S-box)。对状态中的每个元素进行
次幂运算,其中
是最小的可逆次幂。
MDS。状态元素的向量乘以一个具有特殊属性的矩阵。
轮常数(Round constants)。预先定义的常数被加到状态的每个元素中。
后向-S盒(Backward S-box)。对状态的每个元素进行
次幂运算,得到其幂函数是
的逆运算的整数。
MDS。状态元素的向量乘以一个具有特殊属性的矩阵。
轮常数。预先定义的常数被加到状态的每个元素中。

每一轮几乎都是相同的,但不完全是,因为每一轮的轮常数都不同。虽然“后向-S盒”步骤似乎是一个高阶的操作,但正如我们将看到的,Rescue-XLIX 轮函数的所有六个步骤都可以由阶为
的非决定性状态转移约束来记录。
一旦定义了 Rescue-XLIX 置换,就可以用它实例化一个海绵函数来获得 Rescue-Prime。在这个构造中,输入的域元素在置换之间被吸收到状态的顶部
个元素中。在最后一次置换后,顶部的
个元素被读出。Rescue-Prime 的哈希摘要包括了这
个元素。

此处展示的 STARK 证明,使用了以下参数:
含有
个元素的素域
且


此外,哈希计算的输入将是一个单一的域元素。所以特别地,将会只有一轮吸收和一次置换的应用。
Rescue-Prime 论文提供了几乎完整的参考实现。然而,这里的代码是针对这一个应用量身定做的。
单轮 Rescue-XLIX 置换 的状态转移约束条件是用开始时的状态值来表达该轮中间的状态值,并再次用结束时的状态值来表达,然后将这两个表达式等同起来。具体来说,用
表示
回合开始时的状态值,定义
和
为轮常数,定义
为 MDS 矩阵,用上标表示元素的幂。那么,单轮的转换由以下方程描述:
为了在 STARK 中使用,状态转移约束不能依赖于单一回合。换句话说,我们需要的是一个描述所有回合的单一方程,而不仅仅是第
轮。定义
为表示当前状态(本轮开始时)的变量向量,定义
为表示下一个状态(本轮结束时)的变量向量。此外,定义
为表示在
上取值为
的
个多项式的向量,类似地,定义
。假设在不失一般性的情况下,执行轨迹将在定义域
上(对于某些
)被插值。那么上述算术化状态转移约束就会产生以下描述相同状态转移条件的等式:
状态转移约束多项式是通过将所有项移到左手边,使得等式右边零得到的。请注意,有
个变量,对应于
个寄存器。
边界约束就简单多了。在开始时,第一个状态元素是未知的秘密,第二个状态元素是零,因为海绵结构就是这样定义的。在结束时(在所有
轮或
循环后),第一个状态元素是已知哈希摘要
的一个元素,而第二个状态元素是不受限制的。请注意,这第二个状态元素必须保持秘密才是安全的——否则攻击者就会反转置换。这种描述产生了以下的三元组集合
:


算术化的部分是证据,对于 STARKs 来说,它是执行轨迹。在这个特定的计算中,除了最开始的状态外,执行轨迹还是每一轮之后的状态集合。
一个非交互式的零知识证明系统可以被转化为一个签名方案。问题是,它必须能够证明拥有“一个密码学困难问题的解”的知识。STARKs 可以被用来证明任意复杂的计算声明。然而,Rescue-Prime 的全部意义在于,它以“对 STARK 友好”的方式生成密码学困难问题的实例——具体来说,就是一个紧致的 AIR。因此,让我们把一个对 Rescue-Prime 的 STARK 转换成一个签名方案。
为 STARK 定义一个用于 Rescue-Prime 的证明者和验证者,只需要将现有的代码片段连接起来即可。
注意关于证明流的显式论证。它必须是一个特殊的对象,它可以模拟依赖于消息的 Fiat-Shamir 转换,而不是常规的转换。
为了将零知识证明系统转换为签名方案,必须将非交式证明与被签名的文档绑定。传统上,通过 Fiat-Shamir 变换实现这一点的方法是将验证者的伪随机响应定义为“文档和整个协议的对话脚本”拼接起来的哈希摘要,拼接过程直到需要输出为止。
就代码实现而言,这需要一个新的证明流对象——一个知道这个需要被生成签名和验证的文档的对象。下一个类用于实现这个对象。
此时,可以定义组成签名方案的密钥生成、签名生成和签名验证功能。注意,这些函数是 Rescue-Prime STARK Signature Scheme (RPSSS)类的成员,其定义在上文已涉及。
这段代码定义了一个可证明安全的(笔者注:更具体地说,在随机预言机模型中,一个成功的签名伪造者会产生一个敌手,它以多项式相关的运行时间和成功概率打破 Rescue-Prime 的单向性。),(几乎)达到 128 位安全级别的后量子签名方案。虽然这种描述听起来很讨人喜欢,但该方案的性能指标却远没有这么讨人喜欢:
密钥大小:16 字节(耶!)
公钥大小:16 字节(耶!)
签名大小:~ 133 kb
密钥生成时间:0.01 秒(可接受)
签名时间:250 秒
验证时间:444 秒
可能存在一些优化方法可以缩减证明的大小,比如在打开一批 Merkle 叶子节点时合并共同路径。然而,这些优化方法超出了本教程的教学目的,本教程旨在强调和解释所涉及的数学知识。
在速度方面,很多地方性能不佳的原因是使用了 Python,而不是使用更贴近硬件的语言,比如 C 或 rust。选择 Python 也是出于同样的原因——突出和解释数学知识。但是就速度而言,最大的性能提升将来自于关键操作算法的优化。这将是本教程的下一部分也是最后一部分的主题。
上一篇:自我主权身份(SSI)和可验证数字凭证(VC)的基本要素
zCloak Network 是基于波卡生态的隐私计算服务平台,使用 zk-STARK 虚拟机为通用计算进行零知识证明的生成与验证。基于独创的自主权数据和自证明计算技术,可以让用户在无需对外发送数据的情况下,实现对数据的分析和计算。通过波卡跨链消息传递机制,可以为波卡生态内的其它平行链以及其它公链提供数据隐私保护支持。项目会采用“零知识证明即服务”的商业模式,打造一站式的多链隐私计算基础设施。
原文出自 《Anatomy of a STARK》系列,原文链接见“阅读原文”
转载请注明原文与本文出处及翻译团队 zCloak Network
【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。
