Zcash是这样用零知识证明的

简介:之前我翻译了zcash官方关于零知识证明讲解的一系列文章,但以我个人的经验来看,我们还需要这篇文章,才能真正理解零知识证明。这篇文章也是翻译自Zcash官方的一篇介绍zk-SNARKs的文章,原文在这里。这篇文章可以让我们知道Zcash用zk-SNARKs实现了哪些内容,我们可以通过这篇文章,更加明白zk-SNARKs的脉络。
以下是正文翻译:

什么是zk-SNARKs

Zcash是zk-SNARKs的第一次广泛应用,它是一种新颖的零知识密码学形式。 Zcash具有强大隐私保护能力,这源于Zcash对交易的屏蔽,并且交易可以在区块链上完全加密,而且还可以通过使用zk-SNARK证明其有效性。

首字母缩略词zk-SNARK代表“零知识简洁非交互式知识证明”,它指的是一种证据构造,其中人们可以证明自己拥有某些信息,例如一个秘密密钥;而且不会在证明的过程中没有透露该信息,同时在证明者和验证者之间也无需任何交互。

“零知识”证明允许一方(证明者)向另一方(验证者)证明陈述是真实的,而不会泄露超出陈述本身有效性的任何信息。例如,给定随机数的散列,证明者可以说服验证者确实存在具有该散列值的数字,而不会揭示它是什么。

在零知识的“知识证明”中,证明者不仅可以使验证者相信该数字存在(当然,他们自己也确实知道那个数字) —— 而且,不会泄露有关该数字的任何信息。 “证明”(Proof)和“论证”(Arguments)之间的区别是非常技术性的,我们不在此处讨论。

“简洁”的零知识证明可以在几毫秒内得到验证,证据长度只有几百字节,即使对于非常大的程序的陈述也是如此。在第一个零知识协议中,证明者和验证者必须来回传递多轮,但在“非交互式”构造中,证明只包括从证明者发送到验证者的单个消息。目前,唯一已知的、生成非交互且足够短以发布到区块链的零知识证明的方法,是引入一个初始设置阶段,该阶段生成在证明者和验证者之间共享的公共参考字符串。我们将此公共引用字符串称为系统的公共参数。

如果某人有权访问用于生成这些参数的秘密随机性,他们将能够创建对验证者有效的假证明。对于Zcash,这意味着作恶方可能制造假币。为了防止这种情况发生,Zcash通过精心设计的多方共同参与的方式产生了公共参数。要了解有关我们的参数生成过程的更多信息,并查看我们为防止Zcash的秘密随机性被泄漏(例如计算机被黑掉了)而采取的预防措施,请访问我们的[Paramgen](Paramgen page)页面。要了解有关参数生成协议背后的数学逻辑,请阅读我们关于该主题的博客文章白皮书

ZK-SNARKs在Zcash中是如何被构造的

为了在Zcash中具有零知识隐私,根据网络的共识规则确定交易有效性的函数,必须返回交易是否有效的答案,而不揭示其执行计算的任何信息。这是通过在zk-SNARKs中对一些网络共识规则进行编码来完成的。在较高的层次上,zk-SNARKs首先将您想要证明的内容转化为关于知道某些代数方程的解的等价形式。在下一节中,我们简要概述一下如何将确定有效交易的规则转换为方程式,然后可以在候选解决方案上进行计算,而不会向验证方程式的各方显示任何敏感信息。

Computation → Arithmetic Circuit → R1CS → QAP → zk-SNARK

将交易有效性函数转换为数学表示的第一步,是将逻辑步骤分解为最小的操作,从而创建“运算电路”(Arithmetic Circuit)。 类似于布尔电路,其中程序被编译为离散的单个步骤,如AND,OR,NOT;而当程序转换为运算电路时,它被分解为单个步骤,包括加法,减法以及乘法和除法的基本算术运算(不过,在特定情况下,我们将避免使用除法)。

下面是计算表达式(a + b)*(b * c)的运算电路的示例:

arithmetic-circuit.png

看一下这个电路,我们可以将输入值a,b,c视为从左到由“行进”。我们的下一步是构建所谓的Rank 1约束系统,也即R1CS,以检查值是否“正确行进”。在这个例子中,R1CS将保证,从b和c进入的乘法门出来的值是b * c。

在此R1CS表示中,验证者必须检查许多约束 - 几乎每个约束电路。 (由于技术原因,事实证明我们只对来自乘法门的电线有一个限制。)在2012年关于该主题的论文中,Gennaro,Gentry,Parno和Raykova提出了一种很好的方法来“将所有这些约束捆绑成一个约束” 。该方法使用二次运算程序(QAP)来表示,需要检查的约束也从数字之间的约束转变为多项式之间的约束。多项式可能非常大,但这没关系,因为当多项式的等式不成立的时候,那么它也就代表着在大多数点都不会成立。因此,您只需检查两个多项式,在一个随机选择的点上是否匹配,如果匹配,就说明这个证明很大概率下是正确的。

如果证明者事先知道验证者将选择检查哪一点,他们可能能够制作无效的多项式,但仍然满足该点的验证。利用zk-SNARK,使用诸如同态加密和椭圆曲线的配对的复杂数学技术来“盲式”计算多项式 —— 即,不知道正在计算的是哪个点。上面描述的公共参数用于确定将检查哪个点,但是以加密形式存在的,所以证明者和验证者都不知道它是什么。

到目前为止的描述主要解决了如何在“SNARK”中获得S和N - 如何获得简短的,非交互式的单一消息证明 —— 但是没有解决允许“zk”(零知识)部分,它能允许证明者保持隐私数据的安全性。事实证明,在这个阶段,通过使证明者使用仍然满足原多项式方程的“随机移位”,可以容易地实现“zk”部分。

有关Zcash中zk-SNARK背后关键概念的逐步深入解释,请参阅我们的SNARKs Explainer系列,其中包含以下帖子:

  1. 同态隐藏
  2. 多项式的盲式计算
  3. 系数测试及其假设
  4. 可验证的多项式盲式计算
  5. 计算转为多项式
  6. 皮诺曹协议
  7. 椭圆曲线配对

Zcash使用了一个libsnark的分支,一个用于zk-SNARKs的C ++库。 您可以检查代码并了解有关我们在[github](on github
)上实现的更多信息。 要深入了解用于Zcash zk-SNARK的协议,请参阅有关[Pinocchio协议](Pinocchio protocol
)的论文。

如何应用ZK-SNARKS创建一个隐蔽(sheilded)交易

在比特币中,通过链接发送方地址,接收方地址以及公共区块链上的输入和输出值来验证交易。 Zcash使用zk-SNARK来证明满足有效交易的条件,而不会泄露所涉及的地址或价值的任何重要信息。隐蔽(sheilded)交易的发送者构造证据以证明:

  1. 输入值相加即是每个隐蔽的交易的输出
  2. 发送者证明他们拥有每个输入项的花费私钥,并因此可赋予他们消费的权力。
  3. 输入项的花费私钥以加密方式与整个交易的签名相链接,使得交易不能被不知道这些私钥的任意一方修改。

此外,隐蔽交易必须满足下面描述的一些其他条件。

比特币跟踪未使用的交易输出(UTXO)以确定可花费的交易。在Zcash中,等效的且隐蔽的UTXO被称为“承诺”,并且花费承诺还需要揭示“无效符号”。 Zcash节点保留已创建的所有承诺的列表,以及所有已显示的“无效符号”。承诺和无效符号存储为哈希值,以避免披露有关承诺的任何信息,包括“哪些无效符号与哪些承诺相关”这类的信息。

对于由隐蔽支付创建的每个新项,发布的承诺包括以下哈希值:发送项的地址,发送的金额,此项特有的数字“rho”(稍后用于派生出无效符号)和随机数。

承诺= HASH(收件人地址,金额,rho,r)

当花费隐蔽项时,发送者使用他们的花费密钥来发布一个无效符号,该无效符号是来自尚未花费的现有承诺的私有编号(“rho”)的哈希,并提供零知识证明,证明该他们被授权消费。此哈希值必须不在用于跟踪已花费交易的无效符号的集合中。

Nullifier = HASH(花费私钥,rho)

隐蔽事务的零知识证明,除了能验证上面的内容外,也验证了以下断言也是正确的:

对于每个输入项,存在一个能被揭示的承诺。
无效符号和承诺都被正确的计算了。
使得某一输出项的无效符号与任何其他项的​​无效符号发生碰撞是不可能做到的。

除了使用花费私钥控制地址之外,Zcash还使用一组证明和验证的密钥钥来创建和验证证明。这些密钥在上面讨论的公共参数创建过程中生成,并在Zcash网络中的所有参与者之间共享。对于每个隐蔽的事务,发送方使用其证明密钥生成其输入有效的证明。矿工使用验证密钥检查证明者的计算。 Zcash的证明生成方式的设计要求证明者预先做更多的工作,从而它简化了验证,因此主要的计算工作被放到了交易的创建者身上(这就是为什么创建一个隐蔽的Zcash交易可以占用到40秒,而验证交易是否有效只需要几毫秒)。

Zcash隐蔽交易的隐私安全性依赖于标准的、经过反复验证的密码术(哈希函数和流加密),但它是zk-SNARKs的补充,通过承诺和无效符号系统,允许发送者和接收者证明某个隐蔽交易是有效的。其他的为加密货币提供隐私的方法,依赖于把交易之间的联系模糊化;但Zcash的交易可以存储在完全加密的区块链上,这为加密货币应用开辟了新的可能性。加密交易允许各方享受公共区块链的好处,同时仍然能保护他们的隐私。我们计划在未来的版本中,将允许用户自行选择性地披露有关隐私交易的信息。请参阅Zcash的近期的博客文章,了解Zcash的未来计划。

有关如何在Zcash中构建隐私交易的更深入说明,请参阅我们关于隐蔽地址之间的交易如何工作的博客文章。有关当前Zcash协议的完整详细信息,请参阅我们的协议规范。

推荐阅读更多精彩内容