零知识证明
大约 2 分钟
零知识证明
使用场景
- 隐私保护的加密货币如 Zcash 利用了 zk-SNARKs 来隐藏交易的发送方、接收方和交易金额。通过零知识证明,用户可以证明他们拥有一定数量的资金并进行交易,而无需公开具体的交易细节。
- ZKP 可以用于去中心化身份验证系统,用户可以证明他们拥有某种属性或资格(如年龄超过18岁、拥有某个证书等),而无需透露更多的个人信息。
- ZKP 可以用于验证数据的完整性和正确性,而不需要暴露数据本身。这在跨链数据共享和数据市场中非常有用。
简单例子
const crypto = require('crypto');
// 生成随机数
function getRandomInt(max) {
return crypto.randomInt(max);
}
// 计算 (base ^ exp) % mod
function modPow(base, exp, mod) {
let result = 1;
base = base % mod;
while (exp > 0) {
if (exp % 2 === 1) {
result = (result * base) % mod;
}
exp = Math.floor(exp / 2);
base = (base * base) % mod;
}
return result;
}
// 零知识证明协议
class ZeroKnowledgeProof {
constructor(p, g, x) {
this.p = p; // 大素数
this.g = g; // 生成元
this.x = x; // 私钥
this.y = modPow(g, x, p); // 公钥
}
// 生成承诺
generateCommitment() {
this.r = getRandomInt(this.p - 1); // 随机数
this.C = modPow(this.g, this.r, this.p); // 承诺
return this.C;
}
// 提出挑战
generateChallenge() {
return getRandomInt(2); // 返回 0 或 1 的随机挑战
}
// 生成响应
generateResponse(challenge) {
if (challenge === 0) {
return (this.x + this.r) % (this.p - 1);
} else {
return this.r;
}
}
// 验证证明
verifyProof(C, challenge, response) {
if (challenge === 0) {
const lhs = (C * this.y) % this.p;
const rhs = modPow(this.g, response, this.p);
return lhs === rhs;
} else {
const lhs = C;
const rhs = modPow(this.g, response, this.p);
return lhs === rhs;
}
}
}
// 使用示例
const p = 23; // 素数
const g = 5; // 生成元
const x = 6; // 私钥
const zkProof = new ZeroKnowledgeProof(p, g, x);
// 生成承诺
const C = zkProof.generateCommitment();
console.log('Commitment:', C);
// 提出挑战
const challenge = zkProof.generateChallenge();
console.log('Challenge:', challenge);
// 生成响应
const response = zkProof.generateResponse(challenge);
console.log('Response:', response);
// 验证证明
const isValid = zkProof.verifyProof(C, challenge, response);
console.log('Proof is valid:', isValid);