Appearance
KZG承诺
预备知识
双线性配对

这里要注意,配对的
可信设置 (Trusted Setup)
需要预先生成一组公共参数字符串(CRS - Common Reference String)。这个过程通常涉及一个或多个参与者共同生成一个秘密值(MPC)
根据椭圆曲线离散对数,在嵌入到多项式后,给定
KZG承诺方案
这里使用BLS12-381椭圆曲线。
承诺阶段Commit
假设证明者有一个次数不超过
计算承诺值:
既显然,证明者用他不知道的一个值
这个
证明阶段Prove
验证者提供一个
则如果
证明者计算这个商多项式
,记为 。 证明者计算证明
(也称为witness 或者 ): 。
验证阶段Verify
验证者拥有:(承诺
验证者执行以下检查:
正确性证明
- 左边:
- 右边:
根据双线性性质和
: - 左边:
- 右边:
- 因此,
左边 = 右边,验证通过。
如果等式成立,验证者就相信
优化
由于
如果 泄露该如何伪造证明
对于攻击者,假设已知(
- 选择任一点
,假设需要声称 。 - 构造证明
, 从 中可以知道 , 重写为 , 展开得到 , 又因为 , 则又可以得到 。 显然攻击者可以计算出 , 这里由于 和 已知, 和 自选。从而可以计算出 - 这样,攻击者提交(
, , )即可欺骗验证者。
Code
Details
python
# 这里使用 https://github.com/ethereum/py_ecc/blob/main/py_ecc/bls12_381/bls12_381_curve.py
# https://github.com/ethereum/py_ecc/blob/main/py_ecc/bls12_381/bls12_381_pairing.py
#type: ignore
from py_ecc.bls12_381.bls12_381_curve import (
G1,
G2,
add,
multiply,
neg,
is_on_curve,
curve_order,
)
from py_ecc.bls12_381.bls12_381_pairing import (
pairing,
final_exponentiate,
)
from sympy import Poly, Symbol
# 这里选择验证多项式 f(x) = x^3 + 2x + 3
x = Symbol('x')
fx = Poly(x**3 + 2*x + 3, x)
# 1. 生成承诺
# 生成私钥alpha
import random
alpha = random.randrange(1, curve_order) # alpha ∈ Fr
# 计算承诺C = f(alpha) * G1
C = multiply(G1, int(fx.subs(x, alpha)) % curve_order)
# 生成公开值h = alpha*G2
h = multiply(G2, alpha % curve_order)
# 2. 证明阶段
# 这里证明f(z) = y, 其中z = 5, y = f(5) = 5^3 + 2*5 + 3 = 138
z = 5
y = int(fx.subs(x, z)) % curve_order
# y = 140
# z = 6
# 这里可以取消注释试一试提交错误的值会怎么样
# 计算商多项式 q(x) = (f(x) - f(z)) / (x - z)
fx_poly = Poly(fx, x)
g = Poly(x - z)
qx, _ = fx.div(g)
# 计算证明w = q(alpha) * G1
w = multiply(G1, qx.subs(x, alpha))
# 3. 验证阶段
# 验证者知道(C, G1, G2, h, z, y, w)
# 验证 e(C - y*G1, G2) == e(w, h - z*G2) 等价于
# 验证 e(G2, C - y*G1) == e(h - z*G2, w) // 左右调换, 详见 bls12_381_pairing.py 里的定义 pairing(G2,G1)
# 如果觉得验证慢的话可以直接 import
# https://github.com/ethereum/py_ecc/tree/main/py_ecc/optimized_bls12_381
# 但是注意其他的相关运算也要换成里面的函数,比如 multiply, add, neg 等等
left = pairing(G2, add(C, neg(multiply(G1, int(y)))))
right = pairing(add(h, neg(multiply(G2, z))), w)
assert final_exponentiate(left) == final_exponentiate(right), "验证失败"
print("验证成功")
# --------------------------------------------------
# 伪造攻击
# 假设泄露了alpha
alpha_ = alpha
# 1. 伪造
y_fake = 99
z = 99
# 2. w_fake = (C - y_fake*G1) * mod_inverse(alpha - z)
# 计算 C - y_fake*G1
C_minus_yG1 = add(C, neg(multiply(G1, y_fake)))
# 计算 (alpha - z) 的模逆元
inv_alpha_minus_z = pow((alpha_ - z) % curve_order, -1, curve_order)
# w_fake = (C - y_fake*G1) * mod_inverse(alpha - z)
w_fake = multiply(C_minus_yG1, inv_alpha_minus_z)
# 3. 验证阶段
left_fake = pairing(G2, add(C, neg(multiply(G1, int(y_fake)))))
right_fake = pairing(add(h, neg(multiply(G2, z))), w_fake)
assert final_exponentiate(left_fake) == final_exponentiate(right_fake), "伪造验证失败"
print("伪造验证成功")批处理
假设 P 有两个多项式
- V 发送随机数
P - P 计算
与 - V 计算
, - V 验证