title: 46. 电路复杂度 tags: zk complexity theory boolean circuits circuit-SAT circuit complexity WTF zk 教程第 46 讲:电路复杂度 这一讲,我们将介绍电路复杂度,着重介绍布尔电路和算术电路的概念,它们对理解零知识证明系统很重要。 布尔电路 布尔电路不同于我们在中学物理学习的电路,是由逻辑门(AND、OR、NOT)和连线组成的有向无环图(DAG),用于计算布尔函数。 1.1 定义 布尔电路 $C$ 是一个有向无环图,其中: 输入节点:代表输入变量。 内部节点:代表逻辑门,如AND、OR、NOT,分别用符号 $\wedge$, $\vee$, $\neg$ 表示。 输出节点:代表电路的输出。
title: 46. 电路复杂度 tags: - zk - complexity theory - boolean circuits - circuit-SAT - circuit complexity
这一讲,我们将介绍电路复杂度,着重介绍布尔电路和算术电路的概念,它们对理解零知识证明系统很重要。
布尔电路不同于我们在中学物理学习的电路,是由逻辑门(AND、OR、NOT)和连线组成的有向无环图(DAG),用于计算布尔函数。
布尔电路 C 是一个有向无环图,其中:
举个例子,下面的布尔电路有3个输入节点 (x_1, x_2, x_3),计算的布尔函数为:
当输入为 (0, 1, 0) 时,布尔电路的输出为 1。

下面,我们用python构建了例子中的布尔电路:
class Gate: def __init__(self, gate_type): self.type = gate_type self.inputs = [] def compute(self): if self.type == 'AND': return all(self.inputs) elif self.type == 'OR': return any(self.inputs) elif self.type == 'NOT': return not self.inputs[0] class BooleanCircuit: def __init__(self): self.gates = [] self.output_gate = None def add_gate(self, gate): self.gates.append(gate) def set_output(self, gate): self.output_gate = gate def evaluate(self, inputs): for gate in self.gates: gate.inputs = [inputs[i] if isinstance(i, int) else i.compute() for i in gate.inputs] return self.output_gate.compute() # 示例:构建 (NOT (x1 AND x2)) AND ((x2 AND x3) OR (NOT x3)) 的电路 circuit = BooleanCircuit() and0 = Gate('AND') and1 = Gate('AND') and2 = Gate('AND') not0 = Gate('NOT') not1 = Gate('NOT') or0 = Gate('OR') and0.inputs = [0, 1] # x1 AND x2 and1.inputs = [1, 2] # NOT x3 not0.inputs = [2] not1.inputs = [and0] or0.inputs = [and1, not0] and2.inputs = [not1, or0] circuit.add_gate(and0) circuit.add_gate(and1) circuit.add_gate(not0) circuit.add_gate(not1) circuit.add_gate(or0) circuit.add_gate(and2) circuit.set_output(and2) # 评估电路 print(circuit.evaluate([False, True, False])) # 输出: # True
Circuit-SAT(电路可满足性问题)是布尔可满足性问题(SAT)的电路版本。
由于任意布尔函数都可以由布尔电路表示,因此我们可以将SAT转换为Circuit-SAT问题,即给定一个布尔电路 C,判断是否存在一组输入使得 C 的输出为1。
由于SAT是NP完全问题,因此Circuit-SAT也是NP完全问题,这也就意味着任何NP问题都可以转换为Circuit-SAT。这体现了布尔电路的通用性。
电路复杂度研究计算问题需要的最小电路大小和深度。
算术电路也是一种计算模型,用于计算多项式。与布尔电路不同,算术电路的每个节点表示一个基本的算术运算,比如加法或乘法,而不是布尔运算。电路的输入是常量或变量,输出是多项式的结果。
算术电路 C 是一个有向无环图,其中:
举个例子,下面的算术电路有3个输入节点 (x_1, x_2, 1)(其中 1 为常数),计算的多项式为:
假设 x_1, x_2 \in \mathbb{F}_7 当输入为 (1, 2) 时,算术电路的输出为 4。

我们可以将 Circuit-SAT 问题转化为算术电路,具体方法是将每个布尔电路转换为算术电路:
转换后,布尔函数 \phi(x_1, x_2, ..., x_n) 可以表示为算术电路 p(x_1, x_2, ..., x_n),其中每个布尔运算都被替换为相应的算术运算。
因此,由于 circuit SAT 是 NP 完全问题,因此算术电路 SAT 也是 NP 完全问题。也就是说,每一个 NP 问题都可以算术电路化。
算术电路复杂度中有两类重要的复杂性类:
算术电路在零知识证明系统扮演着重要角色,特别是在zk-SNARK(零知识简洁非交互式知识论证)中。主要有以下几点原因:
通用性:算术电路几乎可以表示任意的计算问题。
兼容性:算术电路在有限域上工作,这与许多密码学原语(如椭圆曲线密码)天然兼容。
高效性:算术电路有助于生成更小、验证更快的证明,对于zk-SNARKs的"简洁"(Succinct)特性至关重要。
我们会在之后的章节中更详细的介绍zk-SNARK用到的算术电路相关概念,包括 R1CS 和 QAP。
这一讲,我们介绍了电路复杂度,着重介绍了布尔电路和算术电路。与物理学中的电路不同,这里的电路是由布尔运算/算术运算构成的有向无环图,用于计算布尔表达式或多项式。其中,算术电路几乎可以表示任意的计算问题,广泛用于零知识证明系统。