Circom乘法电路a*b约束的证明疑问:未输入乘积却通过验证
关于Circom乘法电路的两个问题解答
问题背景回顾
你使用的初始Circom电路:
pragma circom 2.0.0; /*This circuit template checks that c is the multiplication of a and b.*/ template Multiplier2 () { // Declaration of signals. signal input a; signal input b; signal output c; // Constraints. c <== a * b; }
输入文件input.json:
{"a": "3", "b": "11"}
执行完所有编译、见证生成、证明验证流程后,验证返回[INFO] snarkJS: OK!;修改电路约束为c <== a * b * -1后,验证依然通过。
1. 未手动输入33,为何能证明知晓33的因子?
这是零知识证明中信号自动计算与公开信号机制导致的:
- 当你运行
node generate_witness.js multiplier2.wasm input.json witness.wtns时,程序会严格按照电路的约束规则,自动计算输出信号c的值——也就是3 * 11 = 33。 - 这个计算出的
c=33会被作为公开信号写入public.json文件,验证者会拿到这个公开值。 - 你的证明本质是向验证者证明:你持有两个私有值
a和b,它们的乘积恰好等于公开的33。整个过程不需要你手动输入33,电路会帮你完成乘积计算并公开结果,从而实现“知晓33因子”的证明。
2. 修改约束为c <== a*b*-1后为何仍验证通过?
验证流程的核心是检查见证是否符合电路定义的约束规则,而非约束的实际业务含义:
- 修改约束后,见证生成时会计算
c=3*11*-1=-33,这个值会被写入新的public.json。 - 验证时,snarkJS只会检查你的私有输入
a=3、b=11和公开输出c=-33是否满足c = a*b*-1这个等式。只要等式成立,验证就会返回OK。 - 此时你证明的是“知晓-33的因子”,而非33的,但验证逻辑只关注约束是否被满足,所以结果依然是通过。
内容的提问来源于stack exchange,提问作者egor10_4
相关产品推荐
相关产品推荐

