4.4 算术化:R1CS 与 AIR 两种方言


文档摘要

4.4 算术化:R1CS 与 AIR 两种方言 本节摘要:算术化(Arithmeticization)把任意计算翻译成有限域上的加法与乘法,让前两节的多项式武器得以开火。本节拆解两大方言——面向电路的 R1CS 与面向轨迹的 AIR,用一段完整的 R1CS 构造与检查演算打通"计算到约束"的转换,并给出约束成本的直觉标尺。承接 4.3 的多项式承诺,通往 4.5 的可信设置。 为什么一切都要先过域算术这道关 有限域上的算术对证明系统有个不可替代的好处:没有溢出、没有浮点误差、没有边界情况——每个元素都能安全地加、乘、求逆,代数恒等式处处成立。所以现代证明系统的第一步永远是把业务计算"压"进这个代数世界:整数比较、哈希函数、椭圆曲线运算,全部拆解成域上的加法门与乘法门。

4.4 算术化:R1CS 与 AIR 两种方言

本节摘要:算术化(Arithmeticization)把任意计算翻译成有限域上的加法与乘法,让前两节的多项式武器得以开火。本节拆解两大方言——面向电路的 R1CS 与面向轨迹的 AIR,用一段完整的 R1CS 构造与检查演算打通"计算到约束"的转换,并给出约束成本的直觉标尺。承接 4.3 的多项式承诺,通往 4.5 的可信设置。

为什么一切都要先过域算术这道关

有限域上的算术对证明系统有个不可替代的好处:没有溢出、没有浮点误差、没有边界情况——每个元素都能安全地加、乘、求逆,代数恒等式处处成立。所以现代证明系统的第一步永远是把业务计算"压"进这个代数世界:整数比较、哈希函数、椭圆曲线运算,全部拆解成域上的加法门与乘法门。这个过程叫算术化,它的产物规模直接决定证明的一切成本——约束数就是 ZK 世界的"代码行数",也是"燃气费"。

先建立成本直觉,再学方言。SHA-256 哈希一次约需两万多个约束(按比特拆解后每轮移位异或都要展开);一次 AES 加密在同量级;而一次域乘法只占一两个约束。比较操作(大于小于判断)天然别扭——域上没有大小序,要靠比特分解绕行。这张成本表是每个 ZK 工程师的肌肉记忆:同一个业务逻辑,写法不同约束数可以差十倍,因此"电路优化"是 ZK 工程里实打实的专业工种。

方言一:R1CS——把计算写成矩阵

R1CS(秩一约束系统)把计算展开成一串"乘法门",每个门用三个向量(A、B、C)描述,并要求满足逐元素的线性组合内积关系:设 z 是包含全部输入、中间值与输出的向量,则 (Az) ∘ (Bz) = (Cz),其中 ∘ 是逐元素相乘。一句话记法:A 线性组合出的数,乘以 B 组合出的数,必须等于 C 组合出的数。加法免费(线性组合直接写进向量),乘法收费(一个门一条约束)——这条经济规律决定了电路写手的全部技巧。

空说抽象,直接构造一个最小完整系统:证明"我知道 x 使 x 的立方等于 27"。设中间值 v1 = x·x,v2 = v1·x,断言 v2 = 27。向量为 z = (一, x, v1, v2),三条约束如下——随后用代码跑一遍合法见证与非法见证:

# R1CS 玩具实现:证明知识 x 使 x*x*x = 27 P = 97 # 玩具素数域 # 变量序:z = [1(常数一), x, v1(即x平方), v2(即x立方)] # 约束1: x * x = v1 约束2: v1 * x = v2 约束3: v2 * 1 = 27 A = [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] B = [[0, 1, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0]] C = [[0, 0, 1, 0], [0, 0, 0, 1], [27, 0, 0, 0]] def dot(vec, z): return sum(a * b for a, b in zip(vec, z)) % P def check(z): for r in range(3): lhs = dot(A[r], z) * dot(B[r], z) % P if lhs != dot(C[r], z): return False, r + 1 return True, 0 witness = [1, 3, 9, 27] # 合法见证:x=3 ok, gate = check(witness) print("合法见证通过:", ok) # True,三条约束全绿 liar = [1, 4, 16, 27] # 作弊者谎称 x=4(4 的立方是 64 不是 27) ok, gate = check(liar) print("非法见证卡在约束", gate) # 卡在约束 2:16*4=64 不等于 27 wrong_out = [1, 4, 16, 64] # 过程自洽(4 的立方确实是 64)、结论造假 ok, gate = check(wrong_out) print("输出造假卡在约束", gate) # 卡在约束 3:64 不等于声称的 27 # 真实系统里矩阵有数万行、向量含全部中间值, # 但验证逻辑与这三行完全同构:Az∘Bz ?= Cz

三组见证的检查结果把 R1CS 的检验逻辑暴露得干干净净:约束系统不信任任何输入,哪怕只有一处对不上,具体卡在哪一行都查得出来。Groth16、Plonk 系的原始输入就是这套矩阵(Plonk 会再加工成自定义门与复制约束,骨架不变)。

图:从计算到证明的算术化流水线

图:从计算到证明的算术化流水线

方言二:AIR——把计算写成轨迹

AIR(代数化中间表示)换了个视角:不复盘"哪些门被计算",而是记录"执行轨迹每一步如何推出下一步"。把计算排成一张表,每行是一个状态,AIR 用少量转移约束描述"相邻两行必须满足的关系"。斐波那契式递推是最直白的例子:第 n 行第 2 列的值等于第 n−1 行第 2 列加第 n−1 行第 1 列,一条约束管住全部行。哈希轮函数、虚拟机指令循环这类"同一动作重复百万次"的计算,AIR 的表达密度远超 R1CS——这正是 STARK 主打大规模计算的原因。两种方言的取舍由此清晰:逻辑复杂选 R1CS,动作重复选 AIR;工程上两者还能互相转换,代价是转换层引入的开销。

成本优化的三个惯用手法

写电路与写代码的优化直觉常常相反,三个惯用手法先记下。查表替代计算:复杂的非线性函数(如 S 盒)用查找表约束代替展开计算,约束数骤减。延迟比特分解:域上自由加法能合并的先合并,实在需要按比特判断时再分解,避免过早展开。批处理证明:把多个实例叠进同一条轨迹共用约束(递归与聚合的雏形,7.2 节的 ZK 虚拟机会再遇到)。这些手法的共同哲学:在约束世界里,加法是风、乘法是刀、比特是金子——省着用刀和金子。

过渡:参数从哪来

流水线走到这里还差最后一环:KZG 路线需要的那些"有毒参数"从何而来、如何处置?下一节进入仪式现场。

约束成本速查与工程习惯

把常见操作的约束量级固化成一张心算表(示意量级,随实现浮动):一次域乘法一到两条约束、一次哈希(电路友好型)数百门、一次经典哈希(SHA 系列)上万门、一次比较操作几十门起步、一次椭圆曲线点运算数千门。写电路前先按这张表估算总成本,超预算的业务逻辑优先考虑换原语(经典哈希换电路友好哈希,往往是数量级级别的节省)而非优化细节。

两条工程习惯与成本表配套。先写"规格电路"再做优化版本:先用最直白的方式把逻辑写成约束,作为正确性基准,再做查表、合并等优化,两版约束数与行为对拍——4.4 正文的非法见证演算就是基准电路的测试方式。把约束数计入持续集成:每次提交输出约束总数的变化曲线,突然的膨胀通常意味着有人在无意识中展开了昂贵操作。

三问三答

**问:见证和输入有什么区别?**公开输入是陈述的公开部分(如"承诺值为多少"),见证是私有部分(如"对应的原像")。约束系统把两者一起吃进向量 z,但对外的证明只覆盖"存在这样的完整向量"——公开输入人人可复核,见证永远不出场。写协议文档时把两者分开列,是审计友好性的第一步。

**问:为什么域的大小要选得那么讲究?**域大小决定安全冗余与效率的平衡:太小则 Schwartz-Zippel 抽查的撞车概率上升(4.3 的 d/域大小),太大则每次乘法的硬件成本上升。生产方案会同时用一个大域做主算术、一个小域做聚合,跨界转换用专门的桥电路——这也是 7.2 分层流水线里"层与层之间有适配层"的原因之一。

**问:AIR 的约束少了,安全性会不会也少?**不会。约束数量决定表达成本,安全性由"约束是否完整覆盖正确执行"决定——覆盖不完整才是 5.1 节说的约束缺失缺陷。AIR 的转移约束写得是否完备,与 R1CS 的门是否写全,是同一种审计对象,只是方言不同。

本节要点回顾

  • 算术化是必经翻译:一切计算先进有限域,约束数即成本单位,写法差异可达十倍;
  • R1CS 一句话:线性组合相乘必须等于另一组线性组合,加法免费、乘法收费;
  • AIR 一句话:轨迹相邻行满足转移约束,重复计算的表达密度远超电路;
  • 优化三板斧:查表、延迟分解、批处理,核心是省乘法与比特。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U