隐私保护之zk-SNARK

zk-SNARK 概述

zk-SNARK,就是一个为了将实际的零知识证明类问题转为计算机程序问题的理论。全称“zero knowledge Succinct Non-interactive ARgument of Knowledge” 可以拆分为下面几点去理解:

  1. zero knowledge,零知识,即不透露任何有用的信息。
  2. succinct,简洁的,主要是指计算机程序在验证的过程不涉及大量数据传输以及保证验证算法的简单。
  3. non-interactive,无交互。交互是个抽象名词,我这里要解释一下它。比如交互式程序就是你给它一个指令,它反馈给你一个对应的信息,而非交互式程序就是你给它一个指令,正确它就执行,错误它就不执行,而且它也不会将错误信息反馈给你。因此zk-SNARK的无交互,就是证明者提交证明后,错误的时候验证者是不会透露错误的信息是什么的。
  4. arguments,争议性。zk-SNARK 是有被攻击的争议的,这种争议仅且仅当证明者拥有足够的算力来通过伪造证据来欺骗验证者,才会存在,注意关键词:足够的算力,它足以打破公钥的加密,所以可以说概率极低。

zk-SNARK是“零知识证明”理论在区块链中的一个已经落地的被应用起来了的论证。zk-SNARK 是基于零知识证明理论,零知识证明是由S.Goldwasser、S.Micali及C.Rackoff这三个人在20世纪80年代初提出的。但是真正让它火了起来是区块链的zk-SNARK 。

零知识证明,它指的是证明者能够在不向验证者提供任何有用的信息的情况下,使验证者相信某个论断是正确的。

有两种角色,证明者 和 验证者:

  1. 证明者,证明自己知道问题的答案
  2. 验证者,验证证明者的答案是正确的

zk-SNARK 原理

零知识证明原理大体由以下组成:

  1. 多项式问题的转化 - 需要证明的问题转化为多项式问题 t (x) h (x) = w (x) v (x),证明者提交证明让验证者确认多项式成立。
  2. 随机挑选验证 - 随机选择验证的数值 s,验证 t (s) h (s) = w (s) v (s)。相对于验证多项式相等 t (x) h (x) = w (x) v (x),随机挑选验证,简单,验证数据少。随机挑选验证,安全性肯定不及多项式等式验证,但如果确实足够随机,安全性还是相当高的。
  3. 同态隐藏 - 同态隐藏指的是函数的一种特性。输入的计算和输出的计算保持 “同态”。以加法同态为例,满足如下的三个条件的函数 E (x),称为加法同态:1. 给定 E (x),很难推导出 x. 2. 不同的输入,对应不同输出 3. E (x+y) 可以由 E (x),E (y) 计算出来。乘法同态类似。
  4. 零知识 - 证明者和验证者之间除了 “问题证明与否” 知识外,不知道其他任何知识(不知道随机挑选值,不知道挑选值的多项式计算结果)。

 Libsnark介绍

       Libsnark库是由SCIPR Lab开发的zk-SNARKs算法库,使用c++编写,采取MIT开源许可证。目前的libsnark库实现提供以下功能:

  1. 针对通用目的的证明系统:
  •   面向NP完全语言“R1CS”(Rank-1约束系统)的预处理zk-SNARKs,其中R1CS与算术电路可满足性相似。该zk-SNARKs构建遵循、扩展并优化了[BCTV14a]中描述的方法。
  •   面向算术电路语言“BACS”(双线性算术电路可满足性)的预处理SNARK,当不需要R1CS带来的灵活性时,它简化了NP陈述的编写,最终在内部会约减为R1CS。
  •   面向“USCS”(Unitary-Square约束系统)的预处理SNARK,实现了[DFGK14]中提出的核心方法。
  •   面向布尔电路语言“TBCS”(双输入布尔电路可满足性)的预处理SNARK,在内部它约减为USCS,这将比使用R1CS更为高效。
  •   面向R1CS的模式可提取的预处理SNARK。该构建方法使用了[GM17]中描述的方法。对于算术电路来说,它比[BCTV14a]中的方法更慢,但是会生成更短的证据。
  •   ADSNARK,一个面向认证数据证明成熟的预处理SNARK,实现了[BBFR15]中描述的方法。
  •   PCD(证据携带数据),在[BCCT13]中提出解释,并在[BCTV14b]中进行了优化。
  1. 面向R1CS实例构建的工具库—gadgetlib1和gadgetlib2。
  2. 使用上述证明系统证明陈述的应用程序示例。

在证据被生成以及验证之前,首先需要选择代表将被证明的NP陈述的电路或者约束系统,然后运行一个生成器算法,生成相应的公共参数,包括一个很长的证明密钥以及一个很短的验证密钥,这种模式被称为预处理zk-SNARKs。

预处理zk-SNARKs可使用不同的参数进行初始化,这取决于使用的椭圆曲线,目前libsnark库提供了三种选择,我们采用的是alt_bn128:

  1. edwards:基于Edwards曲线的实例化,该曲线提供了80位的安全性。
  2. bn128:基于Barreto-Naehrig曲线[35]的实例化,该曲线提供了128位的安全性,该实现针对曲线算术使用动态生成机器码的方式,在某些不支持堆上代码执行的操作系统上可能会报错。
  3. alt_bn128:bn128的替代曲线,比bn128效率低,但是避免了动态机器码的分配。

使用libsnark库构建应用程序时,一般包括如下步骤:

  1.   将被证明的陈述表述为R1CS(或者上述提到的任意语言,例如算术电路,布尔电路)。通过编写C++代码构建R1CS实例,并且将该代码与libsnark库链接在一起。
  2.   使用libsnark库提供的生成器算法创建面向该陈述的公共参数,只需创建一次,随后可一直使用。
  3.   使用libsnark库提供的证明者算法创建真陈述关于R1CS可满足性的零知识证据。
  4.   使用libsnark库提供的验证者算法验证声称陈述的零知识证据。

Libsnark生成证明密钥与验证密钥时,在linux环境下使用的随机数来源是/dev/urandom,当考虑创建长期使用的证明密钥与验证密钥时,应使用更加真实的随机数来源,例如使用安全多方计算(MPC)生成随机数。

你可能感兴趣的:(密码学)