基于Nova/SuperNova的zkVM

1. 引言

本文为2023年3月13~4月7日 ZK Spring Residency in Vietnam上,由PSE团队、Orochi Network团队、0xPARC团队、Oskar(独立个人)以及Delv团队联合发布。

  • Nova:借助Incremental Verifiable Computation(IVC)和 folding scheme,Nova可更高效地执行重复相同的代码块。
    Nova采用的安全假设为GLOG hardness以及RO(Random Oracle)。
  • SuperNova:借助Non-uniform IVC(NIVC),SuperNova扩大的了Nova的应用范围,可执行不同的代码块。

Nova和SuperNova都可对计算中的关键部分进行并行化,且不需要FFT运算。从而可具有更快的proving time以及更少的memory usage。

将Intermediate Representation(IR)及其opcodes 映射为不同的IVC steps,从而可更高效地执行更小的重复代码块。这就利用了现有的编译器架构和hot-path优化。为此,提出了基于vector commitments来处理VM state updates的设计提案。每个computation step可折叠进某binary tree中,该binary tree可修正为可并行化的。final fold(最后一次折叠)可确保整个计算的完整性,并最终包裹进某SNARK中以实现succinctness。

本提案可用于证明ZK-WASAM执行以及ZK-LLVM执行,并以一个toy VM为例描述了具体的实现。

不同于EVM with gas对应的bounded computation execution,本提案重点关注unbounded computation execution,从而不像Halo2那样对roots of unity和memory consumption具有限制。

2. 背景资料

2.1 Incrementally Verifiable Computation (IVC)

在这里插入图片描述

Incrementally Verifiable Computation (IVC)是指,在每一步,基于某public state z i z_i zi和某extra witness input W i W_i Wi,重复应用某step function F F F
IVC中定义每一步的proof π i \pi_i πi用于证明:

  • i i i步执行的正确性,即 F i ( z 0 ) = z i F^{i}(z_0)=z_i Fi(z0)=zi

通常,使用SNARKs来递增构建 π i \pi_i πi

2.2 Nova

在这里插入图片描述
Nova使用IVC,但是,通过将SNARK Verifier 替换为 Folding Scheme,可有效降低recursion开销达一个数量级或更多。

借助Nova,在每一步,Prover仅需做 O ( C ) O(C) O(C)次MSM(Multi Scalar Multiplications)运算。而若采用Halo,则每一步需要 O ( C ) O(C) O(C)次FFT运算和 O ( C ) O(C) O(C)次 EXP(在某密码group内的Exponentiations)运算。其中 C C C为circuit size。

实际上,recursion开销对应约为1万个量级的约束。这意味着,对于具有更多约束的某指定function,折叠是有意义的。

2.3 SuperNova

在这里插入图片描述
SuperNova将Nova扩展为支持Non-Uniform IVC(NIVC),这意味着可在每一步运行不同的函数。

借助Nova,将functions捆绑在一起并构建一个switch function,也可实现NIVC(Non-Uniform IVC)。但是,这样每一步的circuit size为 O ( C ⋅ L ) O(C\cdot L) O(CL),其中 C C C为对应该function的约束数, L L L为distinct functions数量。

而借助SuperNova,可并行维护 L L L个running instances,每个对应一个function,并折叠当前step的proof到相关函数中。

3. SuperNova VM

VM由 顺序执行的指令集 + state(memory/stack) 组成。VM中的每个opcode对应IVC中的某step。可使用SuperNova来更高效地利用不同的opcodes,也可并行化证明每个step。将memory state变化 看做是每个step change对应的public input和output,并通过vector commitments(或者设计为其它)来实现。

借助SuperNova,在每一步可运行多个不同的函数,这样可友好地映射为VM中的opcodes。

在具有N条指令的模VM上下文中,Prover work由 O ( N ⋅ C ⋅ L ) O(N\cdot C\cdot L) O(NCL)降低为 O ( N ⋅ ( C + L ) ) O(N\cdot (C+L)) O(N(C+L)),效果显著。对于 C > > L C>>L C>>L的场景,意味着可无需过多关注opcodes的数量。

如EVM具有约100个量级的opcodes,WASM具有约400个量级的opcodes,可安全地假设 C > > L C>>L C>>L,从而Prover time 变为 O ( N ⋅ C ) O(N\cdot C) O(NC),其中 C C C为每个opcode的平均约束数。

3.1 Nova并行化

为并行化Nova,构建了a binary tree of computations,其中每个节点执行一个step。在该tree的root,可声称所有的计算以正确的顺序执行正确。

由于每个节点所需的计算可在不知道其它节点状态的情况下执行,因此可对其并行化。
在这里插入图片描述
如上所示意,可只计算是如何向上折叠的。更通用的情况为, F ′ ( L , R ) F'(L,R) F(L,R)对应为声称由step L L L到 step R R R执行正确,该声称为某承诺值。

而Nova论文中的基础场景为, F ( L , L ) F(L,L) F(L,L),其中 F ( Z L − 1 ) = Z L F(Z_{L-1})=Z_L F(ZL1)=ZL Z i Z_i Zi表示了public input和output。

可采用binary tree structure来对Nova 计算进行并行化。计算某single step的incremental proofs,然后fold “upwards”。即将step1-2 和 step3-4 转换为证明由 step[1-2] transition to step[3-4]。

在该binary tree的最顶端,可用于保证计算的完整性 以及 所有state transitions都是正确的。

当前:

3.1.1 binary tree中的base node和internal node

在上述binary tree中,存在2类节点:

  • base layer node:仅证明execution trace。每个base layer node证明依赖于应用 F F F instance所引起的state change。
  • internal/intermediate node:也证明某correct step change。但此外,还证明the correct chaining of the previous output being equal to the actual input。同时,还会证明底层instance的折叠是正确的。

在这里插入图片描述
Nova中有2种不同的场景:

  • base layer:要求提供witness的同时,表达整个execution trace(如上图的 F F F boxes)
  • intermediate level:证明 F F F的正确执行,并处理好折叠见public input/output的一致性,同时执行NIFS.Verify step。

3.1.2 Nova中所需的checks

为更详细的理解Nova中的折叠机制,先了解下所需的checks以及在每种场景下的工作原理。
在这里插入图片描述
由上图可知,base node和internal node之间的差异。绿色表示需执行的check,红色表示无需执行的check。为便于表达recursion,无论是否需执行该check,均图示包含表示。

3.1.2.1 base node所需的check

对于base node,仅需证明基于某input,运行 F F F,可得到expected output。就证明给定某public inputs及,可获得某public outputs集,并forward给下一 F F F instance。

为此:

  • 创建 F ′ F' F instance,来验证a dummy-initialized,并认同Prover与Verifier之间的folding instance,见NIFS.Verify step。【注意,此时事实上并不验证任何previous folds,仅将initial dummy fold与 F ′ F' F instance结合。】
  • 需确保public input-output consistency。在base layer无需该step,且无 认可 F ′ F' F instance validation所需的initial inputs/outputs。

最终,简化为:

  • 生成一组Relaxed R1CS constraints,并将其累加到新生成的instance matrix中(其中包含了error term computation 和 math-related folding ops)。这些约束用于证明实际的 F ′ ( z L ) = z R F'(z_L)=z_R F(zL)=zR relation成立。注意并不直接验证该relation成立,而是将其累加到最终的foldings中。
  • 对previous folding verification做dummy checks。
  • 对input/output consistency checks做dummy checks。
3.1.2.2 intermediate node所需的check

不同于base node,intermediate node具有 F F F的输入,以及Relaxed R1CS instances pair的输入,可用于声称 previously folded F ′ F' F instance pair为one computational step apart。

如上图所示,intermediate nodes的目的为:

  • 强化Public Input/Output consistency的正确性,即检查F(left.out)=F(right.in)。
  • 验证previous fold of F ′ F' F nodes(NIFS)。

3.2 Curve Cycling

之前章节讨论了proof中 F ′ F' F如何在每个new step验证某folding step。但是,缺少的关键细节为:

  • 由于base filed 不等于 elliptic curve filed,约束若直接做field运算将非常昂贵。

为解决该问题,可一起运行two chains of folded proofs,把那个使用某elliptic curve cycle,使得某curve的椭圆曲线运算 可在另一曲线的base field上cheap验证。这将引入的recursive开销至少为 F ′ F' F circuit size,以及 sequential prover的每个step额外fold的proving time。

实际应用中,对于sequential场景,通过使用curve cycling来初始化2个relaxed R1CS instances,以及2个normal R1CS instances。proof中进行下一step的流程为:

  • 1)在第二条曲线上折叠源自previous step的relaxed R1CS instance以及normal R1CS instance。

  • 2)在第一条曲线上,为primary circuit构建新的 F ′ F' F R1CS instance,并将步骤1)中另一曲线的fold data作为 F ′ F' F folding verifier的输入。

  • 3)在primary曲线上,将步骤2)中的new R1CS 与 input relaxed R1CS 折叠。

  • 4)为步骤2)中的R1CS生成proof,并将步骤3)中的folding data作为 F ′ F' F verifier的输入。该R1CS instance声称:primary curve folding 以及 在第二曲线上 F F F circuit的正确性。

  • 5)输出:

    • 步骤1)中的folding result
    • 步骤2)中的new claimed R1CS
    • 步骤3)的folding result
    • 步骤4)的new claimed R1CS

    作为每条曲线的Relaxed R1CS instance和normal R1CS instance 新pair。

最终,有另一曲线Nova sequence的folding validity Nova proof,每条曲线的circuit将触发 n n n次。必须证明并验证每条曲线的Nova instance check了 另一条曲线的Nova instance。

下图证明了R1CS instances之间的关系。黑线表示folding关系,绿线表示验证关系,大写变量表示relaxed R1CS,小写变量表示normal R1CS。
在这里插入图片描述

3.2.1 并行世界的Curve Cycling

直接将curve cycling用于之前的Nova并行实现将失败。因为 F ′ F' F是针对sequential场景的,设计为仅能将1个relaxed R1CS 与 1个normal R1CS进行累计。在并行场景下,tree中每个节点同时具有:

  • a relaxed R1CS instance:声称底层folding node proof的有效性。
  • a new normal R1CS instance:声称下一次调用 F ′ F' F

为将这4个claims(声称)reduce为1个,需将2个relaxed R1CS instance和2个normal R1CS instance 折叠为1个relaxed instance,且 F ′ F' F可验证该1/4折叠。

为尽可能复用微软的Nova代码,实际实现为3 foldings of 2 instances。当degree更高时,效率将很低。

为此,创建了新的 u u u,其为an R1CS claim:将tree中左边和有变动节点折叠为新的relaxed R1CS claim N N N
在这里插入图片描述

3.3 SuperNova并行化

SuperNova的并行化要更复杂。
主要考量在于SuperNova设计为支持VM execution trace proving。即意味着对于每组opcodes,在每个fold中需支持每组opcode之一(并不清楚每个fold中有哪个opcode)。换句话说,并不清楚下一 F ′ F' F instance中所折叠的opcode。

现在,每次fold中包含尽可能多的opcodes和 F ′ F' F instances。

当前已知如何在Nova-style folds中支持多个opcodes,未知的是,如何在SuperNova中保证跨folds的内存、execution-order 以及 stack一致性,特别是在并行场景下。

为此,本文设计了一种在R1CS内具有可承受开销的SuperNova并行化方案。

3.3.1 使用vector commitments来更新state

其思想为:对 F ′ F' F执行前后的memory state进行承诺,因此可open所希望的所有positions,并证明R1CS内部等于所运算的witness值。

VM的挑战之一在于确保内存的一致性。

借助vector commitments,可做如下操作:

  • Open(Com, Idx) = Value
  • Edit(Com, Idx, NewValue) = NewCommitment

vector commitments可对vector a 0 , ⋯   , a n − 1 a_0,\cdots,a_{n-1} a0,,an1进行commit,并证明某位置 i i i的值为 a i a_i ai。可用Kate承诺方案来实现:令 p ( X ) p(X) p(X)为某多项式,对于所有的 i i i,有 p ( i ) = a i p(i)=a_i p(i)=ai

注意:其足以匹配对所有内存位置进行承诺,且需要证明电路内部所提供的witness 满足 memory中特定位置的openings。

根据KZG polynomial commitments 可知,可通过Lagrange插值表示该多项式:
∑ n = 0 n = i m a x M e m i ∏ n = 0 n = i m a x X − j n − j \sum_{n=0}^{n=i_{max}}Mem_i\prod_{n=0}^{n=i_{max}}\frac{X-j}{n-j} n=0n=imaxMemin=0n=imaxnjXj

关于zkVM中的内存管理可参看:

4. Nova bench

Nova benchmarks中指出,在https://github.com/privacy-scaling-explorations/nova-bench中,PSE团队对形如 h ( h ( h ( h ( h ( h ( x ) ) ) ) ) ) h(h(h(h(h(h(x)))))) h(h(h(h(h(h(x)))))) 的 recursively hashing of SHA256 k k k次的证明作了bench。

借助Nova+IVC,将其表示为:
h ( h ( h ( x ) ) ) (d times) → h ( h ( h ( x ) ) ) (d times) → … h(h(h(x))) \text{(d times)}\rightarrow h(h(h(x))) \text{(d times)} \rightarrow \dots h(h(h(x)))(d times)h(h(h(x)))(d times)

不同证明系统性能对比为:

FrameworkArithmetizationAlgorithmCurveOther
Circom (snarkjs)R1CSGroth16Pasta
Nova (seq)Relaxed R1CSNovaPasta
Nova (par)Relaxed R1CSNovaPastaparallel PoC
Halo2PlonkishKZGBN254

在配置高的笔记本(Macbook Pro M1 Max (2021), 64GB memory)上,Prover time为:

kCircomNova (total) d=1Nova (step sum) d=1Halo 2 (KZG)
10.3s0.2s0.1s0.8s
107.3s2.4s1.2s0.8s
10062s24s12.5s1.6s
1000-240s125s25s

在配置高的服务器(Server with 72 cores and ~350GB RAM)上,Prover time为:

kNova d=1Nova d=10Nova d=100Nova d=100 parHalo 2 (KZG)
10019s3.6s--2.5s
1000190s36s26.5s28.5s41.6s
100001900s360s265s226s389.1s
10000019000s?

在配置高的服务器(Server with 72 cores and ~350GB RAM)上,不同证明系统的内存使用情况为:

kNova (seq) d=1Halo 2 (KZG)Nova (par PoC)
1001.6GB3.7GB9GB
10001.6GB32GB244GB
100001.6GB245GBOOM
1000001.6GB??

不同证明系统的SRS size情况为:

  • 对于Circom:当 k = 100 k=100 k=100 约束数为300万时,需要23 powers of tau 或 structured reference string(SRS), 2 23 2^{23} 223。对应为9GB文件,随着约束数增加线性增加,很快会变得不可用。
  • 对于Halo2:为Plonkish。当 k = 100 k=100 k=100时,SRS size为 2 18 2^{18} 218 k = 1000 k=1000 k=1000时为 2 22 2^{22} 222 k = 10000 k=10000 k=10000时为 2 25 2^{25} 225。由于计算更搞笑,Halo2所需的SRS要比Circom的短。
  • 对于Nova:假设其原生运行,或,与Cirom C++ witness generator配合运行,都具有常量的内存开销。PSE库中采用Nova Scotia(将Circom电路编译给Nova prover的中间件)和Circom来编写带路,当 d = 1 d=1 d=1时,有约3万个约束,当 d = 10 d=10 d=10时,有30万个约束。以此类推。
  • 对于并行化Nova:当前程序实现有bug,会引起内存线性增加。该bug由软件实现引起,并不是Nova内部机制导致的。

由此可知,Nova是内存高效的。

5. 应用

不同于zkEVM,zkWASM或通用VM中并无Gas的概念。

由于其底层的曲线具有有限的roots of unity,像Halo2或Groth16这样的证明系统具有hard time来表示VM execution traces。

递归可实现unbounded computation,但难点在于如何合理地切分execution trace。Plonkish类型的证明系统,由于其有大量的行或列,存在的缺陷是聚合较慢。

Toy VM中仅包含ADD和MUL指令,以及内存和program counter。详细见下面基于WASM的execution trace。

5.1 zkWASM

zkWASM的有趣点在于,WASM比EVM更通用,可打开隐私计算和验证计算的大门。如,用户想要证明在浏览器中访问某网址的WASM execution,或证明其sqlite db中包含某entry。

详细设计可参看:

5.2 zkLLVM

与WASM类似,LLVM采用模块化架构,可添加新的backends并优化LLVM。该问题可转换为编译器优化问题。

5.3 zkRISC-V

RISC-V为基于现有R1CS原则的开源标准指令集架构。不同于ISA设计,RISC-V提供了开源license无需付费即可使用。

zkRISC-V为实现zkVM候选方式的优势在于:

  • 支持目标机器的几乎所有编译器
  • 开源标准且免费使用
  • WASM opcodes可编译为RISC opcode
  • 指令集标准化且不复杂

参考资料

[1] Towards a Nova-based ZK VM
[2] Nova-based ZKVM spec

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值