zk-SNARK:零知识的简洁非交互式知识论证

以太坊博客:


该技术的一个自然使用案例是在身份系统中。例如,假设您想向系统证明您是(i)给定国家的公民,并且(ii)19岁以上。假设您的政府在技术上是先进的,并且签发了加密签名的数字护照,其中包括一个人的姓名和出生日期以及一个私钥和公钥。您将构造一个函数,该函数将数字护照和护照中由私钥签名的签名作为输入,并在以下两个条件下输出1:(i)出生日期在1996年之前,(ii)护照是与政府的护照签署的公钥,以及(iii)签名正确,否则输出0。然后,您将进行零知识证明,以证明您有输入,当通过此函数传递时,该输入返回1,并使用另一个私钥对证明进行签名,该私钥将用于以后与该服务进行交互。该服务将验证证明,如果证明正确,它将接受使用您的私钥签名的消息为有效。


我加粗了那些在我看来似乎是不可能的部分。我发现了一些研究性论文,其中包含非常技术性的解释,我不理解。有人可以用外行的话解释为什么这是可能的吗?直观上来说,客户端似乎有很多方法可以更改程序代码,以产生可用于伪造其身份的输出。

一些文档和代码

#1 楼

退后一步,考虑一个更简单的零知识证明。

电子邮件上的数字签名可以被认为是零知识证明的非常具体,狭窄的示例。我(“提供者”)向您提供消息M和M上的数字签名(M的哈希,使用我的私钥加密)。

您(验证者)可以自己对M进行哈希,使用我的公钥解密我提供的签名并进行比较,如果匹配,则您已经确认了我的签名。您所做的只是验证我提供的以下NP语句的算术“证明”:

我知道与公钥P对应的私钥Q
我使用Q对消息M进行签名

您现在确信我知道Q,而无需我向您透露Q。我要做的就是以输入(消息M及其签名)和函数的形式给您证明我知道Q,在输入这​​些输入后,该函数可以正确进行比较。

这是一个零知识证明。

从概念上讲,现在将“我知道私钥Q”替换为“政府私钥已签署声明说我已经合法年龄”。运用相同的逻辑。

牢记“ zk”部分的思想,“ snark”部分的“魔术”是可以将其推广到逻辑上表示为算术电路。

在这两种情况下,“客户端都不能更改程序代码”。我发现在尝试理解数字签名类比时非常有用。

评论


$ \ begingroup $
我认为ZK意味着我不必透露M即可证明我知道M。但是对手方必须在您的示例中使用M。那么ZK在哪里呢?
$ \ endgroup $
–罗兰·科夫勒
17年1月8日在7:18

$ \ begingroup $
@Roland Kofler-消息M是一个示例,用于说明和阐明OP的问题。以此类推,“ ZK”是我的私钥“ Q”。我从不向您透露Q,但您确信我必须知道Q,因为只有这样我才能产生所有三个的集合:M(消息),P(公共密钥)和带符号的哈希。所有这些都可以引入到一个已知函数中,以说服自己我必须知道Q,即使我从未向您展示Q。
$ \ endgroup $
– JesseM
17年1月8日在9:11

$ \ begingroup $
我认为签名示例不是知道私钥的零知识证明。验证者V获得签名后,他不仅了解证明者知道私钥的事实,而且学到了很多东西。具体地说,V也可以说服另一个验证者V',证明者仅通过给V'提供签名即可知道私钥。据我了解ZKP,您也应该不可能拿到证明来说服另一个人。
$ \ endgroup $
– Alin Tomescu
17-2-24在16:55

$ \ begingroup $
事实并非如此,零知识并不一定能保证不可转让性,这是另一种特性。例如,公共参考字符串模型中的可公开验证的非交互式零知识证明始终是可转让的-但通常可以通过适当的技术使它们不可转让。不过,答案中的协议不是零知识的,而是另一个原因:通常,没有密钥,就无法在任意消息上模拟正确的签名,因此zk无法得到证明。
$ \ endgroup $
– Geoffroy Couteau
18年1月26日在9:10

$ \ begingroup $
正如Alin和Geoffroy所说的那样,此答案不是描述零知识证明,而是描述知识的证明。参见en.wikipedia.org/wiki/Zero-knowledge_proof
$ \ endgroup $
– A1m
18年3月2日在18:36

#2 楼


当您消除了不可能的事情之后,无论多么不可能的事情,剩下的都是真理。 (福尔摩斯)


如果我在宿舍里找到你并且门窗完好无损,我只能断定你以某种方式学会了入门代码,因为我不知道您可以通过任何其他方式进入我的房间而不会打碎门或窗户。

功能$ f $的ZK-SNARK类似于:如果您提供结果$ 1 $的证明,则可以通过验证程序,这必然意味着您必须知道$ x $,使得$ f(x)= 1 $。这是因为,如果您不知道$ x $的值,我们不知道有任何(有效的)方式来生成这样的证明。实际上,我们有一个证明,能够做到这一点将意味着能够解决某些认为很难的数学问题(尽管用于构造SNARK的问题更加复杂,但您可以考虑分解整数)。因此,当您直觉地说


看来,客户端将有很多方法可以更改程序代码,以产生可用于伪造其身份的输出。


...可能存在,也可能不存在,但是我们不知道任何事情,我们认为这不太可能(即,出于所有实际目的,这是不可能的)。

#3 楼

Amendig fkraiem的先前答案,让我集中于一个返回$ 1 $的示例。

可以重写Schnorr验证公式:
$$ g ^ {r} h ^ {-c} a ^ {-1} = 1 $$
对于组生成器$ g $,验证响应$ r $,验证者质询$ c $,验证$ a $的初始消息和公钥$ h $这样的$ h = g ^ x $用于某些私钥$ x $。使用此协议,Prover会计算$ r = xc + b $和$ a = g ^ b $,以使验证者无法从接收到的数据中学习$ x $。

点是,没有“知道”秘密$ x $,Prover仅能以可忽略的概率产生令人满意的响应,该概率由挑战集的基数定义,可以是组顺序。

#4 楼

我想以此为外行措手不及... zk-SNARK协议提供了证明,某些算法(或电路)针对某些数据运行。我想证明我知道公共w和私有x使得f(x,w)= 1,但是我不想给你x。我将x和w输入到f中,而f则输出1,而协议的zk-SNARK部分将生成一个签名,表明我刚刚使用该公共输入和该输出进行了所有操作,因此我必须具有有效的私有输入。

我看到的另一个实际应用是,您想知道市长候选人的DNA不在犯罪现场的DNA数据库中。候选人自然不希望向所有人透露他的DNA,那么我们如何知道他不在该数据库中?您可以设计zk-SNARK协议,其中有一种算法可以根据数据库检查输入的DNA,如果匹配则输出1,如果不匹配则输出0。您让警察私下运行该算法,然后他们提出并提交zk-SNARK证明,表明他们运行了该算法并获得了输出0-这将可靠地证明该警察检查了数据库中他的DNA并输出了没有匹配。

所以我认为这证明了我遍历了电路。

我发现这非常有用:
https:// media。 consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b

,这个也许太可爱的推文也很有帮助:
https://twitter.com/ChrisLundkvist/status/ 799807876982251520


直观上,似乎有很多方法可以使客户端更改程序代码,以产生可用于伪造其身份的输出。


好吧...我仍在研究Vitalik Buterin的论文,到目前为止,它很好地描述了引擎盖下发生的事情。当我开始理解它的时候,就像这样:

将函数f转换为特殊电路,其中每个操作都像门一样,具有特殊的编码。当这些运算一起运行时,每个门的复合编码可以转换为难以猜测的多项式-按顺序运行这些运算的任何项都会生成该多项式,而任何做不同的事情或超出范围的事情步骤将无法生成该多项式。

肉类中的类似物可能是每个线索都建立在最后的寻宝游戏之一,因此您需要按顺序排列每个点。如果到最后,您会得到一个锁定密码箱的钥匙。如果您将锁定的密码箱交给某人,无论您放什么东西,都证明您已经完成了到达目的地的所有步骤。仅以此类比,将这些线索中的每一个都视为计算机操作。

然后,将通过电路生成的多项式用于创建公钥和私钥对。当您通过电路运行输入时,zk-SNARK协议将为您提供证明$ \ pi $,该证明已使用该功能的私钥加密了您的私人输入和公共输入。这就是您证明您使用这些输入检查了函数的证明。

我确定我缺少其中的关键部分,因此我欢迎进行更正。当有人尝试了解w / zk-SNARK的情况时,我可以证明很多人都无法很好地解释它。