为认证实现零知识证明
概述
零知识证明(ZKP,Zero-Knowledge Proof)允许证明者(prover)在不泄露秘密本身的情况下证明对某个秘密(如密码或私钥)的了解。本技能实现 Schnorr 身份识别协议和使用离散对数问题的简化 ZKPP(Zero-Knowledge Password Proof,零知识密码证明),使认证过程中服务器永远不需要获取用户密码。
目标
- 实现用于 ZKP 认证的 Schnorr 身份识别协议
- 使用 Fiat-Shamir 启发式构建非交互式 ZKP
- 实现零知识密码证明(ZKPP)
- 演示完备性、可靠性和零知识属性
- 比较 ZKP 认证与传统密码验证
核心概念
ZKP 属性
| 属性 | 描述 |
|---|---|
| 完备性(Completeness) | 诚实的证明者总能说服诚实的验证者 |
| 可靠性(Soundness) | 不诚实的证明者无法说服验证者(除极小概率外) |
| 零知识(Zero-Knowledge) | 验证者除了陈述的真实性外不学习任何信息 |
Schnorr 协议
- 设置:公共生成器 g,素数 p,q(g 的阶)
- 注册:证明者计算 y = g^x mod p(从秘密 x 得到公钥)
- 承诺:证明者发送 t = g^r mod p(随机 r)
- 挑战:验证者发送随机 c
- 响应:证明者发送 s = r + c*x mod q
- 验证:检查 g^s == t * y^c mod p
安全注意事项
- 使用密码安全随机数生成器
- 挑战必须是不可预测的(从验证者的角度)
- 对于非交互式证明,使用带抗碰撞哈希的 Fiat-Shamir
- ZKP 单独不提供前向保密;需结合 TLS 使用
验证标准
- 诚实的证明者始终验证成功(完备性)
- 没有秘密的随机响应无法通过验证(可靠性)
- 服务器永远不会收到秘密值
- 非交互式证明可离线验证
- 多次认证产生不同的证明记录
- 协议抵抗重放攻击