You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Circom数组零计数代码编译问题及约束数量相关疑问

关于Circom统计输入零数量的问题解答

1. var与signal的差异为何导致编译结果不同

  • var是Circom的本地编译期变量:它只在电路编译阶段完成数值计算,完全不参与零知识证明的约束系统。你最初用var s[N]和var sum时,sum是靠本地逻辑算出的结果,当你用<==把sum赋值给输出信号y时,编译器会把sum的计算逻辑直接代入约束,但统计零数量的逻辑(比如判断输入是否为0再累加)没法转换成Circom要求的二次约束形式,所以直接报错“Non quadratic constraints are not allowed!”。
  • signal是参与证明的信号变量:改成signal s[N]后,如果你只是用普通的=给s[i]赋值(比如s[i] = (input[i] == 0)),这种赋值只是编译期的数值计算,不会生成任何约束关系——Circom只有用<==、==>或者组件连接时才会生成约束。所以编译器能通过,但整个电路没定义任何需要证明的约束,自然约束数为0。

2. 零约束是否意味着无证明内容

没错,零约束等于你的电路没有任何需要验证的逻辑。这时候证明器根本不会检查输入和输出之间的关联,随便给一组输入输出都能生成合法证明,完全起不到零知识证明的验证作用,这个电路是无效的,不能用在任何实际场景里。

3. 是否应使用引入IsZero组件、含10个非线性约束的代码

必须用IsZero组件(或者用等效的二次约束实现)。原因很简单:

  • 要准确统计零的数量,必须让每个输入对应的标记位s[i]满足“输入为0时s[i]=1,否则s[i]=0”,而且这个关系必须被证明验证——IsZero组件就是用二次约束(比如input[i] * s[i] = 0和s[i] + input[i] * inv_i = 1,inv_i是输入的逆元信号)来实现这个逻辑的,能保证s[i]的正确性是被约束的。
  • 之后再用加法约束把所有s[i]累加得到sum,绑定到输出y,这样整个电路的约束是有效的,能真正证明输出y就是输入数组里零的数量。
  • 你说的“10个非线性约束”其实是IsZero组件生成的二次约束(可能你把逻辑上的条件判断当成了非线性,但实际转换成了Circom支持的二次约束),这是实现正确逻辑的必要约束数量,没有这些约束,电路根本没法验证统计结果的真实性。

内容的提问来源于stack exchange,提问作者wannik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 05:58:26