不告诉密码,也能证明你知道密码?——零知识证明入门

不告诉密码,也能证明你知道密码?——零知识证明入门

一个密码学悖论:我想让你相信我"知道一个秘密",但坚决不告诉你这个秘密是什么。听起来不可能?1985 年之后,密码学家把这件事变成了数学。今天从最经典的故事讲起,带你入门零知识证明(ZKP)。

一、先讲个故事:阿里巴巴的山洞

想象一个环形山洞,有两个入口 A 和 B,中间有一扇需要念咒语才能打开的门。

  • Peggy(证明者)知道咒语
  • Victor(验证者)想确认 Peggy 真的知道,但 Peggy 不想把咒语告诉他

怎么证明?协议是这样的:

  1. Peggy 随机选一个入口走进山洞(Victor 看不到她去了 A 还是 B)
  2. Victor 走到洞口,随机喊:“请从 A 出口出来!”(或 B)
  3. 如果 Peggy 知道咒语,她总能从指定的出口出来(不知道的话,只能赌 50%)

关键在重复:赌一次 50% 可能蒙对,赌 10 次全对的概率是 (1/2)^10 ≈ 0.1%,赌 20 次几乎为零。如果 Peggy 连续 20 次都从 Victor 指定的出口出来——她一定知道咒语,但 Victor 从头到尾没听到咒语!

这就是零知识证明的雏形:证明者证明"我知道",验证者除了"她确实知道"之外什么都没学到

二、这不是玩具,它就在你身边

  • 登录不泄露密码:很多网站验证"你知道密码"时,其实只是验证"你持有密码的某种数学指纹",密码本身不出现在网络上
  • 隐私币:Zcash 用 zk-SNARK 证明"交易合法"而不公开金额和地址
  • zk-rollup(二层网络):把成千上万笔交易打包成一个证明提交到主链,主链只需验证一个证明——2024 年 zk-rollup 总锁仓量突破 60 亿美元

三、零知识证明的"宪法":三条性质

一个合格的零知识证明必须同时满足:

  1. 完备性:如果 Peggy 真知道秘密,她总能通过验证(真命题有证明)
  2. 可靠性:如果 Peggy 不知道秘密,她蒙混过关的概率可忽略(假命题骗不过去)
  3. 零知识性: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 签名、区块链里到处是它的身影。

六、常见误区

  1. “零知识 = 绝对保密”:错。它保证不泄露"秘密本身",但会泄露"命题为真"这个事实
  2. “验证者能冒充证明者”:错。正因为零知识性,验证者学到的对话记录不含任何有用信息,无法转述冒充
  3. “ZKP 很慢,只存在于学术”:2024 年 zk-rollup 每天生成数十万份证明,Groth16 的证明只有 3 个群元素大小,工程上已经非常成熟
  4. “知道秘密的人也可能失败”:协议设计保证诚实证明者总能通过(完备性),失败只可能来自实现 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/嵌入式科研)|原创内容,转载注明出处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值