在通过一个例子介绍了零知识证明 (ZKP) 之后,我们展示了如何将它用作一个强大的工具来增加隐私并进一步开发许多构建在上面的应用程序。
零知识证明允许声称知道秘密的一方(即证明者)说服另一方(即验证者)该声明是有效的,同时不泄露秘密。
寻找 Waldo 是一款游戏,您必须在与他相似的人海中找到 Waldo。

Peggy(证明者)告诉 Victor(验证者)她知道 Waldo 在场景中的位置,但她不想向他展示他的确切位置。那么,她如何向他证明她找到了 Waldo 而不显示他的确切位置?
Peggy 找到了一大块硬纸板,在中间挖了一个 Waldo 形状的洞。

然后,她将 Waldo 的位置(在一张纸上)用胶带粘在纸板的背面,这样 Waldo 就在占据中心的 Waldo 形状的洞。当 Peggy 用胶带粘好纸板时,Victor 应该站在纸板前。

当 Victor 从洞里看到 Waldo 时,他确信 Peggy 的说法是有效的,但他不知道 Waldo 的确切位置

由于零知识证明的隐藏特性,它可以在需要隐私的许多情况下使用。更重要的是,它也可以作为构建更复杂协议的基础,如下所示。
Alice 想用比特币支付 Bob 购买商品。Alice 和 Bob 分别生成随机私钥 a/b, 对应公钥 A/B。Alice 在托管人的公钥 E 下加密她的私钥 a 并将密文 c = Enc(a, E) 发送给 Bob。她还向 Bob 发送了一个零知识证明,证明 c 确实是 a 通过 E 加密的。反之亦然,Bob 做同样的事情。
与传统的 2-of-3 多重签名托管相比,有几个优点:
我们已经实现了完整的协议,下面列出了代码的零知识证明部分。
const encryptionResultA = ve.encrypt(ucPubKeyEscrow, privKeyA.toBuffer());
const proofA = ve.prove(ucPubKeyEscrow, encryptionResultA);
// zero knowledge proof: Bob can verify if encryptionResultA is encrypted privKeyA (without knowing it)
// with ucPubKeyEscrow, whose corresponding public key is ucPubKeyA
const isVerifiedA = ve.verify(proofA, ucPubKeyEscrow, ucPubKeyA, encryptionResultA.ciphertexts);
assert(isVerifiedA);
[1]: Escrow Protocols for Cryptocurrencies: How to Buy Physical Goods Using Bitcoin. Steven Goldfeder, 2017