title | tags | |||||
---|---|---|---|---|---|---|
46. 电路复杂度 |
|
这一讲,我们将介绍电路复杂度,着重介绍布尔电路和算术电路的概念,它们对理解零知识证明系统很重要。
布尔电路不同于我们在中学物理学习的电路,是由逻辑门(AND、OR、NOT)和连线组成的有向无环图(DAG),用于计算布尔函数。
布尔电路
- 输入节点:代表输入变量。
- 内部节点:代表逻辑门,如AND、OR、NOT,分别用符号
$\wedge$ ,$\vee$ ,$\neg$ 表示。 - 输出节点:代表电路的输出。
举个例子,下面的布尔电路有3个输入节点
当输入为
- 电路大小(Size):电路中逻辑门的总数。上面例子中的电路大小为 6。
- 电路深度(Depth):从输入到输出的最长路径长度。上面例子中的电路深度为 3。
下面,我们用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问题,即给定一个布尔电路
由于SAT是NP完全问题,因此Circuit-SAT也是NP完全问题,这也就意味着任何NP问题都可以转换为Circuit-SAT。这体现了布尔电路的通用性。
电路复杂度研究计算问题需要的最小电路大小和深度。
-
$\text{SIZE}(t(n))$ :可以用大小为$O(t(n))$ 的电路族计算的函数类。时间复杂度为$t(n)$ 的图灵机可以模拟为大小为$O(t^2(n))$ 的电路。 -
$\text{DEPTH}(d(n))$ :可以用深度为$O(d(n))$ 的电路族计算的函数类。 -
P/poly:可以用多项式大小的电路族计算的函数类。包含所有在多项式时间内可决定的语言,即
$P \subseteq P/\text{poly}$ ,但也包含一些不可判定的语言。
算术电路也是一种计算模型,用于计算多项式。与布尔电路不同,算术电路的每个节点表示一个基本的算术运算,比如加法或乘法,而不是布尔运算。电路的输入是常量或变量,输出是多项式的结果。
算术电路
- 输入节点:代表输入变量或常量,一般属于有限域。
- 内部节点:代表加法( )、乘法(*)、或其他算术运算。
- 输出节点:代表电路的输出,即计算的多项式结果。
举个例子,下面的算术电路有3个输入节点
假设
- 电路大小(Size):电路中逻辑门的总数。上面例子中的电路大小为 3。
- 电路深度(Depth):从输入到输出的最长路径长度。上面例子中的电路深度为 2。
我们可以将 Circuit-SAT 问题转化为算术电路,具体方法是将每个布尔电路转换为算术电路:
- NOT 门:
$\neg x = 1 - x$ - AND 门:
$x \wedge y = x \times y$ - OR 门:
$x \vee y = 1 - (1 - x)(1 - y)$
转换后,布尔函数
因此,由于 circuit SAT 是 NP 完全问题,因此算术电路 SAT 也是 NP 完全问题。也就是说,每一个 NP 问题都可以算术电路化。
算术电路复杂度中有两类重要的复杂性类:
- VP类:类比于P类,包含那些可以在多项式大小的算术电路中计算的问题,比如计算行列式的值。
- VNP类:类比于NP类,包含那些虽然可以在多项式时间内验证结果是否正确,但可能无法在多项式大小的算术电路中有效计算的问题。
算术电路在零知识证明系统扮演着重要角色,特别是在zk-SNARK(零知识简洁非交互式知识论证)中。主要有以下几点原因:
-
通用性:算术电路几乎可以表示任意的计算问题。
-
兼容性:算术电路在有限域上工作,这与许多密码学原语(如椭圆曲线密码)天然兼容。
-
高效性:算术电路有助于生成更小、验证更快的证明,对于zk-SNARKs的"简洁"(Succinct)特性至关重要。
我们会在之后的章节中更详细的介绍zk-SNARK用到的算术电路相关概念,包括 R1CS 和 QAP。
这一讲,我们介绍了电路复杂度,着重介绍了布尔电路和算术电路。与物理学中的电路不同,这里的电路是由布尔运算/算术运算构成的有向无环图,用于计算布尔表达式或多项式。其中,算术电路几乎可以表示任意的计算问题,广泛用于零知识证明系统。