用途:为编写或审查 Noir 代码提供惯用法与优化准则,目标是让程序可读、地道并生成高效电路。
核心原则「提示并验证」:在电路中计算值通常比验证一个声称正确的值更昂贵。可用非约束函数在电路外算出结果,再用廉价约束验证。编译器已自动为部分操作(如整数除法)注入非约束辅助函数,不要重复提示编译器已优化的内容,应聚焦排序、搜索、数组构造等编译器无法自动应用该模式的高层计算。提示时只返回最终结果,不返回中间结构(掩码、索引、累加器),以减少所需约束。每个 unsafe 块必须写 // Safety: 注释,说明约束代码为何使提示可靠、强制了什么性质。
ACIR 与 Brillig 目标不同:ACIR(约束代码,默认)每个操作变成算术约束,应优化门/约束数量;Brillig(unconstrained 函数)运行在常规 VM 上,应优化执行速度与字节码大小。差异包括:ACIR 循环完全展开、边界须编译期已知,Brillig 支持运行时动态边界;ACIR 控制流被展平为条件选择、两分支都求值,Brillig 为真实分支;ACIR 函数调用总是内联,Brillig 在有利时保留;ACIR 不等式比较需范围检查(耗门),Brillig 有原生比较指令。函数可能被两种上下文调用时,可用 is_unconstrained() 分别提供优化实现,标准库常见此做法。
实用准则:约束代码尽量减少约束,使用提示并验证、避免多余比较、利用类型系统范围保证简化约束;非约束代码按普通命令式代码追求清晰与速度,可自由使用动态循环、提前返回和可变状态;不要在非约束函数内加约束式验证,浪费执行时间且不增加安全性;约束代码不要用运行时动态循环边界。
利用类型系统:bool 类型保证值为 0 或 1,编译器可生成更简单约束,逻辑条件优先用布尔运算符而非域乘法;条件值用 if/else 表达式而非手工 select;两分支都有断言时,把条件提取为值后只断言一次;断言优先用 assert_eq 而非 assert(x == y),错误信息更好;整数比较需范围检查耗门,等式检查更便宜,避免冗余比较,也不要过度优化比较(如用标志跟踪替代简单 <= 可能增加门数),提交前应测量。
限制:资料未提供安装命令、版本要求、价格或平台信息。