不告诉密码,也能证明你知道密码?——零知识证明入门
一个密码学悖论:我想让你相信我"知道一个秘密",但坚决不告诉你这个秘密是什么。听起来不可能?1985 年之后,密码学家把这件事变成了数学。今天从最经典的故事讲起,带你入门零知识证明(ZKP)。
一、先讲个故事:阿里巴巴的山洞
想象一个环形山洞,有两个入口 A 和 B,中间有一扇需要念咒语才能打开的门。
- Peggy(证明者)知道咒语
- Victor(验证者)想确认 Peggy 真的知道,但 Peggy 不想把咒语告诉他
怎么证明?协议是这样的:
- Peggy 随机选一个入口走进山洞(Victor 看不到她去了 A 还是 B)
- Victor 走到洞口,随机喊:“请从 A 出口出来!”(或 B)
- 如果 Peggy 知道咒语,她总能从指定的出口出来(不知道的话,只能赌 50%)
关键在重复:赌一次 50% 可能蒙对,赌 10 次全对的概率是 (1/2)^10 ≈ 0.1%,赌 20 次几乎为零。如果 Peggy 连续 20 次都从 Victor 指定的出口出来——她一定知道咒语,但 Victor 从头到尾没听到咒语!
这就是零知识证明的雏形:证明者证明"我知道",验证者除了"她确实知道"之外什么都没学到。
二、这不是玩具,它就在你身边
- 登录不泄露密码:很多网站验证"你知道密码"时,其实只是验证"你持有密码的某种数学指纹",密码本身不出现在网络上
- 隐私币:Zcash 用 zk-SNARK 证明"交易合法"而不公开金额和地址
- zk-rollup(二层网络):把成千上万笔交易打包成一个证明提交到主链,主链只需验证一个证明——2024 年 zk-rollup 总锁仓量突破 60 亿美元
三、零知识证明的"宪法":三条性质
一个合格的零知识证明必须同时满足:
- 完备性:如果 Peggy 真知道秘密,她总能通过验证(真命题有证明)
- 可靠性:如果 Peggy 不知道秘密,她蒙混过关的概率可忽略(假命题骗不过去)
- 零知识性:Victor 验证完,除了"命题为真"之外什么也学不到——存在一个"模拟器"能在没有 Peggy 的情况下生成和真实对话一模一样的记录
第三条最反直觉:验证者看完整个对话,信息量和没看一样。这保证验证者无法把对话转述给别人来冒充证明者。
四、代码演示 1:山洞协议的完整模拟
import random
def run_protocol(knows_secret=True, rounds=10):
"""模拟山洞协议:Peggy 是否知道秘密,重复 rounds 轮"""
successes = 0
for _ in range(rounds):
entry = random.choice(['A', 'B']) # Peggy 走进的入口
request = random.choice(['A', 'B']) # Victor 要求从哪个出口出来
if knows_secret:
comes_out = request # 知道咒语:穿门,总能按要求出来
else:
comes_out = entry if random.random() < 0.5 else request # 赌 50%
successes += (comes_out == request)
return successes
for rounds in [1, 10, 20]:
s = run_protocol(knows_secret=True, rounds=rounds)
s2 = run_protocol(knows_secret=False, rounds=rounds)
print(f"{rounds} 轮: 知道秘密 {s}/{rounds} 通过 | "
f"不知道秘密 {s2}/{rounds} {'撞运气通过' if s2 == rounds else '被识破'}")
运行输出(每次随机,趋势一致):
1 轮: 知道秘密 1/1 通过 | 不知道秘密 1/1 撞运气通过
10 轮: 知道秘密 10/10 通过 | 不知道秘密 7/10 被识破
20 轮: 知道秘密 20/20 通过 | 不知道秘密 17/20 被识破
看到没?知道秘密的人每轮都通过;不知道的人轮数越多越藏不住。这就是"可靠性"的直观体现——概率会累积。
五、代码演示 2:真实世界的 Schnorr 协议
山洞故事是"三轮交互"的经典原型,数学化之后就是 Schnorr 协议(第 072 期):Peggy 的秘密是 x,公开的是 g、p 和 y = g^x mod p。她不交出 x,却能证明"我知道 x":
import random
p, g = 101, 2 # 公开参数(小素数便于演示)
x = 33 # Peggy 的秘密
y = pow(g, x, p) # 公开值
def schnorr_round():
r = random.randrange(1, p)
t = pow(g, r, p) # 1. 承诺:Peggy 发 t
c = random.randrange(1, p) # 2. 挑战:Victor 随机发 c
s = (r + c * x) % (p - 1) # 3. 响应:Peggy 算 s(用到秘密 x!)
return pow(g, s, p) == (t * pow(y, c, p)) % p # 4. 验证:不接触 x
ok = all(schnorr_round() for _ in range(20))
print(f"20 轮 Schnorr 验证全部通过: {ok}")
验证等式成立,但 Victor 从头到尾没拿到 x——而且如果 Peggy 不知道 x,她无法构造出满足等式的 s(除非赌对挑战 c,概率 1/p)。这就是零知识证明的现实形态:Schnorr 签名、区块链里到处是它的身影。
六、常见误区
- “零知识 = 绝对保密”:错。它保证不泄露"秘密本身",但会泄露"命题为真"这个事实
- “验证者能冒充证明者”:错。正因为零知识性,验证者学到的对话记录不含任何有用信息,无法转述冒充
- “ZKP 很慢,只存在于学术”:2024 年 zk-rollup 每天生成数十万份证明,Groth16 的证明只有 3 个群元素大小,工程上已经非常成熟
- “知道秘密的人也可能失败”:协议设计保证诚实证明者总能通过(完备性),失败只可能来自实现 bug
七、想系统学密码学?
本文精选自 ima 知识号【Kruptos】《密码学与零知识证明》订阅库(第 071 期零知识定义、第 072 期 Schnorr 协议等 100 期系统教程,从古典密码到 RSA、椭圆曲线、零知识证明、后量子密码,每期配可运行 Python 代码)。
📚 完整系列 100 期 + 配套代码,已在 ima 知识号发布
本文只是系列的一个切片。完整系列(100 期系统教程 + 每期可运行代码)在 ima 知识号【Kruptos】持续更新中:
- 🗂 67+ 技术知识库:信号与系统、SDR 软件无线电、数字信号处理、操作系统、AI Agent、大模型微调……几乎覆盖全部软硬件技术栈
- 🧠 8 款 AI 技能:系列生产、知识库管理、CMMI 受管开发、自进化 Agent 等,已在 ima 技能广场上架,即装即用
- ✅ 全部免费订阅,后续更新自动推送
🔍 订阅方式:打开 ima(腾讯智能工作台)→ 搜索「Kruptos」→ 一键订阅。或在 ima 内直接搜索《密码学与零知识证明》等知识库名称。
💬 你还知道哪些"反直觉"的密码学概念?评论区聊聊——想看零知识证明的数学细节还是后量子密码,点赞高的安排。
作者:Kruptos(西电毕业,13 年无线通信/DSP/嵌入式科研)|原创内容,转载注明出处

7652

被折叠的 条评论
为什么被折叠?



