NIZK vs Sigma Proof
非交互式零知识证明(NIZK)和 Sigma 协议(Sigma Protocol)都是零知识证明技术,但它们在交互方式和应用场景上有显著的区别。以下是两者之间的主要区别:
交互性
-
Sigma 协议(Sigma Protocol):
- 交互式:Sigma 协议是交互式的,需要证明者和验证者之间进行多次消息传递,通常是三次消息传递(承诺、挑战、响应)。
- 消息传递:证明者首先发送承诺值,验证者发送挑战值,最后证明者发送响应值。
-
非交互式零知识证明(NIZK):
- 非交互式:NIZK 是非交互式的,证明者只需生成一次证明并发送给验证者,验证者可以独立地验证证明。
- 一次性生成:证明者生成的证明包含了所有必要的信息,验证者无需与证明者进行进一步的交互。
公共参数
-
Sigma 协议(Sigma Protocol):
- 无需公共参数:Sigma 协议通常不需要预先生成的公共参数,证明和验证过程依赖于参与方之间的交互。
-
非交互式零知识证明(NIZK):
- 需要公共参数:NIZK 通常需要一个设置阶段来生成公共参数,这些参数对所有参与方都是公开的。
实现方法
-
Sigma 协议(Sigma Protocol):
- 直接交互:通过直接的交互方式实现零知识证明。
- 特殊声音性:利用特殊声音性(Special Soundness)来确保安全性,即如果存在两个不同的挑战,验证者可以计算出秘密值。
-
非交互式零知识证明(NIZK):
- Fiat-Shamir 变换:常用的方法是将交互式零知识证明(如 Sigma 协议)转换为非交互式零知识证明,通过哈希函数生成挑战。
- 其他技术:还可以使用其他密码学技术,如 zk-SNARKs(零知识简洁非交互知识论证)来实现。
应用场景
-
Sigma 协议(Sigma Protocol):
- 适用于交互环境:适用于需要实时交互的环境,如身份认证和在线协议。
- 简单高效:由于 其简单的三次消息传递结构,Sigma 协议在许多应用中非常高效。
-
非交互式零知识证明(NIZK):
- 适用于非交互环境:适用于不方便进行多次交互的环境,如区块链和分布式系统。
- 离线验证:验证者可以在不需要与证明者交互的情况下进行验证,非常适合离线验证场景。
安全性
-
Sigma 协议(Sigma Protocol):
- 完备性:如果证明者诚实地执行协议,验证者总是能够成功验证。
- 零知识性:验证者无法从证明过程中获取任何有关秘密值的信息。
- 特殊声音性:如果存在两个不同的挑战,验证者能够计算出秘密值。
-
非交互式零知识证明(NIZK):
- 完备性:如果证明者诚实地执行协议,验证者总是能够成功验证。
- 零知识性:验证者无法从证明过程中获取任何有关秘密值的信息。
- 声音性:如果声明是假的,验证者能够检测到,并拒绝证明。
示例代码对比
Sigma 协议示例代码
import random
# 公共参数
g = ... # 生成元
y = pow(g, x, p) # y = g^x mod p
# 承诺阶段
r = random.randint(1, p-1)
t = pow(g, r, p)
send_to_verifier(t)
# 挑战阶段
c = random.randint(1, q-1)
send_to_prover(c)
# 响应阶段
s = (r + c * x) % (p-1)
send_to_verifier(s)
# 验证阶段
if t == (pow(g, s, p) * pow(y, -c, p)) % p:
print("验证成功")
else:
print("验证失败")
NIZK 示例代码(使用 Fiat-Shamir 变换)
import random
import hashlib
# 公共参数
g = ... # 生成元
y = pow(g, x, p) # y = g^x mod p
# 设置阶段
def setup():
return g, p, q
# 证明生成阶段
def generate_proof(x):
r = random.randint(1, p-1)
t = pow(g, r, p)
c = int(hashlib.sha256(str(t).encode()).hexdigest(), 16) % q
s = (r + c * x) % q
return t, s
# 验证阶段
def verify_proof(t, s):
c = int(hashlib.sha256(str(t).encode()).hexdigest(), 16) % q
return t == (pow(g, s, p) * pow(y, -c, p)) % p
# 示例使用
g, p, q = setup()
t, s = generate_proof(x)
if verify_proof(t, s):
print("验证成功")
else:
print("验证失败")
通过对比可以看出,Sigma 协议需要多次交互,而 NIZK 则通过一次性生成证明并使用哈希函数来实现非交互性。