可信设置是 ZK-SNARKs 用于在某个秘密值上评估多项式的一种机制。
请注意,多项式 f(x) 可以通过计算其系数与 x 的连续幂的内积来进行评估:
例如,如果 f(x)=3x3+2x2+5x+10,那么其系数为 [3,2,5,10],我们可以将该多项式计算为
f(x)=⟨[3,2,5,10],[x3,x2,x,1]⟩
换句话说,对于上面的多项式,我们通常会将评估 f(2) 视为
f(2)=3(2)3+2(2)2+5(2)+10
但我们也可以将其评估为
f(2)=⟨[3,2,5,10],[8,4,2,1]⟩=3⋅8+2⋅4+5⋅2+10⋅1
现在假设有人选择了一个秘密标量 τ 并计算
[τ3,τ2,τ,1]
然后将这些点中的每一个与密码学椭圆曲线群的生成元(generator point)相乘。结果将如下所示:
[Ω3,Ω2,Ω1,G1]=[τ3G1,τ2G1,τG1,G1]
现在,任何人都可以获取结构化参考字符串(SRS,structure reference string)[Ω3,Ω2,Ω1,G1],并对 τ 评估一个三次(或更低次)的多项式。
例如,如果我们有一个二次多项式 g(x)=4x2+7x+8,我们可以通过计算该结构化参考字符串与多项式的内积来评估 g(τ):
⟨[0,4,7,8],[Ω3,Ω2,Ω1,G1]⟩=4Ω2+7Ω1+8G1
现在我们已经计算出了 g(τ),而根本不需要知道 τ 是什么!
这也被称为可信设置(trusted setup),因为尽管我们不知道 g(τ) 的离散对数是多少,但创建该结构化参考字符串的人知道。这可能会导致后续的信息泄露,因此我们必须信任创建该可信设置的实体会删除 τ 并且绝不保留它的记录。
Python 示例
from py_ecc.bn128 import G1, multiply, add
from functools import reduce
def inner_product(points, coeffs):
return reduce(add, map(multiply, points, coeffs))
## Trusted Setup
tau = 88
degree = 3
# tau^3, tau^2, tau, 1
srs = [multiply(G1, tau**i) for i in range(degree,-1,-1)]
## Evaluate
# p(x) = 4x^2 + 7x + 8
coeffs = [0, 4, 7, 8]
poly_at_tau = inner_product(srs, coeffs)
验证可信设置是否被正确生成
给定一个结构化参考字符串,我们如何才能知道它遵循 [xd,xd−1,…,x,1] 的结构,而不是通过掷骰子随机选择的?
如果进行可信设置的人还提供了 Θ=τG2,我们就可以验证结构化参考字符串确实是 τ 的连续幂。
e(Θ,Ωi)=?e(G2,Ωi+1)
其中 e 是双线性配对。直观地说,我们是在等式左边计算 τ⋅τi,在等式右边计算 1⋅τi+1。
为了验证 Θ 和 Ω1 具有相同的离散对数(Ω1 应该是 τG1),我们可以检查:
e(Θ,G1)=?e(G2,Ω1)
将结构化参考字符串的生成作为多方计算的一部分
仅仅假设生成结构化参考字符串的人确实删除了 τ,并不是一个稳妥的信任假设。
我们现在描述一个由多方协作创建结构化参考字符串的算法,只要其中有一方是诚实的(即删除了 τ),那么该结构化参考字符串的离散对数就是未知的。
Alice 生成结构化参考字符串 ([Ωn,...,Ω2,Ω1,G1],Θ) 并将其传递给 Bob。
Bob 使用上一节中的检查方法验证 SRS 是否“正确”。然后 Bob 选择他自己的秘密参数 γ 并计算:
([γnΩn,...,γ2Ω2,γΩ1,G1],γΘ)
请注意,现在 SRS 的离散对数变成了:
([(τγ)n,...,(τγ)2,(τγ),1],τγ)
如果 Alice 或 Bob 任意一方删除了他们的 τ 或 γ,那么最终 SRS 的离散对数将无法恢复。
当然,我们不需要将参与者限制为两个人,我们可以有任意数量的参与者。
这种多方计算通常被非正式地称为 powers of tau 仪式。
可信设置在 ZK-SNARKs 中的应用
在结构化参考字符串上评估多项式不会向验证者(verifier)泄露有关多项式的信息,且证明者(prover)也不知道他们正在评估的点是什么。我们稍后将会看到,这种方案有助于防止证明者作弊,并帮助保持其见证(witness)的零知识性。