零知识证明(zk-SNARK)- groth16(一)

news2024/11/16 13:38:48

全称为 Zero-Knowledge Succinct Non-Interactive Argument of Knowledge,简洁非交互式零知识证明,简洁性使得运行该协议时,即便 statement 非常大,它的 proof 大小也仅有几百个bytes,并且验证一个 proof 的时间可以达到毫秒级别。
这是一个通用的零知识证明协议,可以用作各种证明,如范围证明。
核心方法是通过R1CS,QAP等方法将计算难题变为多项式,将计算结果正确性巧妙转化为了多项式的有特殊解的问题,生成对应proof,然后再运用多项式证明方法,来完成证明与验证。

Non-Interactive Argument of Knowledge of a Polynomial

(注意 计算和参数选取是在域内,即有模运算)

一般多项式的证明

场景如下:Verifier 有一个多项式 f ( x ) f(x) f(x),Prover 向 Verifer 证明他知道这一个多项式。
假设 Prover 知道的多项式为 p ( x ) p(x) p(x),那么现在要证明的就是 f ( x ) = p ( x ) f(x)=p(x) f(x)=p(x),如果这两个多项式的阶数最高为 d d d,那么两个多项式代表的曲线将最多有 d d d个交点,当 Verifier 随机在一个很大的范围内取一个值 s s s的时候,那么 s s s d d d相同的概率会非常低,所以有以下协议

  • Verifier 在大范围里随机选择一个值 s s s,并且在本地计算 f ( s ) f(s) f(s),然后把 s s s发送给 Prover
  • Prover 计算 p ( s ) p(s) p(s),然后发送给Verifier
  • Verifier 验证 f ( s ) = ? p ( s ) f(s)\overset{?}=p(s) f(s)=?p(s)

证明多项式的根

有些多项式是可以分解多个多项式的乘积的,如假设 p ( x ) = ( x − a ) ( x − b ) ( x − c ) p(x)=(x-a)(x-b)(x-c) p(x)=(xa)(xb)(xc)那么
假设 Prover 有一个多项式 p ( x ) p(x) p(x),现在他想证明他的多项式持有一部分根(部分多项式),也就是证明他的多项式 p ( x ) = t ( x ) h ( x ) p(x)=t(x)h(x) p(x)=t(x)h(x)中包含 t ( x ) t(x) t(x)假设为 ( x − a ) ( x − b ) (x-a)(x-b) (xa)(xb),而此时的 t ( x ) t(x) t(x)称为目标多项式,是公开的,要注意 Prover 是不能透露原多项式的。那么有以下协议

  • Verifier 在大范围内随机取值 s s s,计算 t = t ( s ) t= t(s) t=t(s),然后将 s s s发送给 Prover
  • Proer 计算 h ( x ) = p ( x ) t ( x ) h( x) = \frac {p(x)}{t(x)} h(x)=t(x)p(x), h ( s ) h(s) h(s), p ( s ) p(s) p(s),然后发送后两个给 Verifier
  • Verfier 验证 p ( s ) = ? t ( s ) h ( s ) p(s)\overset{?}=t(s)h(s) p(s)=?t(s)h(s)

显而易见以上变量都局限为整数,如果 p p p确实能够整除 t t t,那么等式一定是成立的,如果不能,那么式子将存在余式,有极大的概率不是整数。
当然此协议仍然有很大漏洞,比如 Prover 可能完全不知道 p ( x ) p(x) p(x),但知道公开的 t ( x ) t(x) t(x),所以可以完全捏造出 h ( x ) h(x) h(x)满足条件。

同态加密

显然我们不能在协议里进行明文的传输,但又需要密文的计算,所以需要一个满足加密和计算两种特性的算法。
同态加密算法 E ( x ) E(x) E(x),如 E ( a x + b y ) = g a x + b y = g a x ⋅ g b y = ( g x ) a ⋅ ( g y ) b = E ( x ) a ⋅ E ( y ) b . E(a x+b y)=g^{a x+b y}=g^{a x} \cdot g^{b y}=\left(g^{x}\right)^{a} \cdot\left(g^{y}\right)^{b}=E(x)^{a} \cdot E(y)^{b} . E(ax+by)=gax+by=gaxgby=(gx)a(gy)b=E(x)aE(y)b. g g g是生成元),这里基于离散对数难题和 CDH 假设(即给定 g a , g b g^a,g^b ga,gb,得到 g a b g^{ab} gab很困难)。显然这是仅仅满足同态加法的同态加密,不支持密文相乘。
那么该算法不支持乘法,仅有一个 s s s的情况下,该怎么同态计算多项式呢?显然是不行的,于是想办法把同态乘法转变为同态加法,注意到,多项式 P ( x ) P(x) P(x)可以看作是一组系数和未知数的线性结合,也就是计算出 s s s的各个幂次,这需要固定好多项式的阶数 d d d,相当于限制了多项式的阶数,这样提前计算出 s 1 , … , s d s^1,\dots,s^d s1,,sd,然后计算出多项式的每个部分相加即可。
具体使用如下,

  1. Verifier 在大范围里随机选择一个 s s s,先计算好 s s s的幂次 s 1 , … , s d s^1,\dots,s^d s1,,sd,接着计算 t ( s ) t(s) t(s),最后 E ( 1 ) , E ( s ) , … , E ( s d ) E(1),E(s),\dots,E(s^d) E(1),E(s),,E(sd)并发给 Prover
  2. Prover 收到数据后计算, h ( x ) = p ( x ) t ( x ) h( x) = \frac {p(x)}{t(x)} h(x)=t(x)p(x),然后配合多项式的系数计算 E ( p ( s ) ) E(p(s)) E(p(s)) E ( h ( s ) ) E(h(s)) E(h(s))并发送给Verifier
  3. Verifier 进行验证 E ( p ( s ) ) = ? E ( t ( s ) ) E ( h ( s ) ) E(p(s))\overset{?}=E(t(s))E(h(s)) E(p(s))=?E(t(s))E(h(s)),即 g p ( s ) = ( g h ( s ) ) t ( s ) g^{p(s)} = (g^{h(s)})^{t(s)} gp(s)=(gh(s))t(s)

** KCA(The Knowledge of Coefficient Test and Assumption)**

上面的协议的还是有很大漏洞,比如 Prover 在计算多项式的时候,没有采用多项式的格式(常数系数和未知数的线性组合),而是使用了另外的方法,算法找到一个满足 z p = ( z h ) t ( s ) z_p = (z_h)^{t(s)} zp=(zh)t(s)的两个值 z p , z h z_p,z_h zp,zh去替代掉 g p ( s ) , g h ( s ) g^{p(s)},g^{h(s)} gp(s),gh(s),也就是根本没用多项式,直接仿造了满足条件的结果。
这里就需要对 Prover 进行限制,让他必须使用满足条件的多项式,限定为常数,也限定了指数,不能随意改变指数。所以KCA也可以叫做KEA(Knowledge of exponent)
思路如下,
定义一对元素 ( a , b = α ⋅ a ) (a,b = \alpha \cdot a) (a,b=αa)(称为一个 α \alpha α-对), α ⋅ a \alpha \cdot a αa表示 α \alpha α a a a相加,也就是 a α a^\alpha aα,那么一个KC流程如下具体如下,

  1. 首先Verifier会随机选择一个非零的 α \alpha α,计算 b = α ⋅ a b = \alpha \cdot a b=αa,定义这是一个 α − s h i f t \alpha -shift αshift
  2. Verifier 发送这个 challenge pair ( a , b ) (a,b) (a,b)给 Prover。
  3. 这时候 Prover 会 respond 一对不一样,但具有相同性质的 pair ( a ′ , b ′ ) (a',b') (a,b),它应当是 α − s h i f t \alpha -shift αshift
  4. 如果收到的是一个 α − s h i f t \alpha -shift αshift,那么Verifier 接受这个response

注意,这是满足DL问题的, Prover 是很难找到一个 α \alpha α,那么她该如何构造新的 α − s h i f t \alpha -shift αshift呢?一个显而易见的方式是,Prover 选择一个常数系数 γ \gamma γ,直接构造 ( a ′ , b ′ ) = γ ( a , b ) (a',b') = \gamma(a,b) (a,b)=γ(a,b)
假设 Verifier 发送的不是一个,而是是 d d d α − s h i f t \alpha -shift αshift,那么 Prover 也将选择一组系数 c 1 , … , c d c_1,\dots,c_d c1,,cd,respond 一个
( a ′ , b ′ ) = ( ∑ i = 1 d c i a i , ∑ i = 1 d c i b i ) (a',b') = (\sum_{i=1}^d c_ia_i,\sum_{i=1}^d c_ib_i) (a,b)=(i=1dciai,i=1dcibi),显然该对也是满足 α − s h i f t \alpha -shift αshift。如果把 Verifier 发的内容优化一下,就构成了KCA。

Blind Evaluation of Polynomials Verifiable Protocol

完整的多项式盲验证协议。
解决整个问题需要满足的两个性质:

  • **Blindness:**也就是 Prover 不能获取到 s s s,同样 Verifier 也不能拿到 p ( x ) p(x) p(x)(同态)。
  • **Verifiability:**也就是得确保 Prover 发的 E ( p ( x ) ) E(p(x)) E(p(x))确实是用某个多项式 p ( x ) p(x) p(x)计算的,而不是完全不相关的数据(KCA)

那么使用KCA对前面协议进行优化如下,

  1. Verifier 随机选择 α \alpha α(非0)和 s s s,然后计算 t ( s ) t(s) t(s),接着构造 α − s h i f t \alpha -shift αshift ( g , g α ) , ( g s , g α ⋅ s ) , … , ( g s d , g α ⋅ s d ) (g,g^{\alpha}),(g^s,g^{\alpha \cdot s} ),\dots,(g^{s^d},g^{\alpha \cdot s^d}) (g,gα),(gs,gαs),,(gsd,gαsd)
  2. Prover 则使用多项式 p ( x ) p(x) p(x)的系数 c 1 , … , c d c_1,\dots,c_d c1,,cd,然后计算 E ( h ( s ) ) E(h(s)) E(h(s))以及 ( E ( p ( s ) ) , E ( α p ( s ) ) ) = ( g ∑ i = 1 d c i s i , g ∑ i = 1 d c i α ⋅ s d ) (E(p(s)),E(\alpha p(s))) = (g^{\sum_{i=1}^d c_is^i},g^{\sum_{i=1}^d c_i\alpha \cdot s^d}) (E(p(s)),E(αp(s)))=(gi=1dcisi,gi=1dciαsd),发送给Verifier
  3. Verifier进行验证 E ( p ( s ) ) = ? E ( α p ( s ) ) E(p(s))\overset ?=E(\alpha p(s)) E(p(s))=?E(αp(s)) E ( p ( s ) ) = ? E ( t ( s ) ) E ( h ( s ) ) E(p(s))\overset{?}=E(t(s))E(h(s)) E(p(s))=?E(t(s))E(h(s))即可

该方案也可以解决前面的问题,即Prover 不能随意构造满足类似 z p = ( z h ) t ( s ) z_p = (z_h)^{t(s)} zp=(zh)t(s) h ( s ) h(s) h(s),这样会很容易不满足 α − s h i f t \alpha -shift αshift的限制条件。

Parings and bilinear map

前面的协议基本实现了诚实两方之间的交互方案,相关的 proof 仅仅在两方之间有效,无法重复使用,但在实际运用中,存在这恶意的多方的情况,这显然不符合实际。所以,需要让一些秘密参数变得可重复使用甚至公开,而且足够可信以防止滥用。
首先考虑将 Verifier 生成的 ( t ( s ) , α ) (t(s),\alpha) (t(s),α)进行加密保护,防止泄露。如果采用前面的同态加密,那么在后面的乘法计算中就会涉及到同态的乘法 ,但是前面用的同态算法不支持同态乘法。那么必须用到类似乘法的时候应该怎么办呢?这时候就引入了椭圆双曲线映射。
Parings 是能够将一个集合里的两个加密输入确定性的映射到另一个集合里的一个输出的一种乘法表示函数。
即: e : G × G → G T e: \mathbb{G} \times \mathbb{G} \rightarrow \mathbb{G}_T e:G×GGT满足以下性质
e ( g 1 a , g 2 b ) = e ( g 1 , g 2 ) a b = e ( g 1 a b , g 2 ) = e ( g 1 , g 2 a b ) \begin{aligned}e(\mathrm{g_1^a,g_2^b})&=\mathrm{e(g_1,g_2)^{ab}=e(g_1^{ab},g_2)=e(g_1,g_2^{ab})}\end{aligned} e(g1a,g2b)=e(g1,g2)ab=e(g1ab,g2)=e(g1,g2ab)
e ( g 1 a , g 2 b ) e ( g 1 c , g 2 d ) = e ( g 1 , g 2 ) a b + c d \begin{aligned} e(\mathrm{g_1^a,g_2^b})e(\mathrm{g_1^c,g_2^d})&=\mathrm{e(g_1,g_2)^{ab+cd}}\end{aligned} e(g1a,g2b)e(g1c,g2d)=e(g1,g2)ab+cd
其意义在于,将某个群中的一对元素映射到一个新的群,当且仅当两个原像对应指数的积相同其像也相同。并且,该函数要求是可计算的(即不需要用暴力搜索等方式),它能够验证一对(加密后的)数据的乘积是否和另一对相同(虽然算不出这个乘积)
接下来将协议的计算放到满足Parings的椭圆曲线群上来。

Multiple Parties Composite Common Reference String

首先引入一个可信的第三方来随机生成 s s s α \alpha α,并且计算出CRS(Common Reference String),共证明和验证两部分,都是公开的( i ∈ { 0 , … , d } i \in \{0,\dots,d\} i{0,,d}),接着需要删除掉 s s s α \alpha α

  • Proving Key: E ( s i ) , E ( α s i ) = g s i , g α s i E(s^i),E(\alpha s^i) = g^{s^i},g^{\alpha s^i} E(si),E(αsi)=gsi,gαsi
  • Verification Key: E ( t ( s ) ) , E ( α ) = g t ( s ) , g α E(t(s)),E(\alpha) = g^{t(s)},g^{\alpha} E(t(s)),E(α)=gt(s),gα

接着基于CRS,让 Prover 和 Verifier 仅仅通过CRS就能完成协议。继续优化协议如下,(下面简化 p = p ( s ) , t , h p=p(s),t,h p=p(s),t,h也类似)

  • 对于 Prover 来说,公开的CRS中已经包含了第一步的内容,接下来是利用 Proving Key 来计算出 E ( h ( s ) ) E(h(s)) E(h(s)) ( E ( p ( s ) ) , E ( α p ( s ) ) ) (E(p(s)),E(\alpha p(s))) (E(p(s)),E(αp(s)))
  • 对于Verifier来说,是利用CRS中的 Verfication来进行验证( p ′ = α p p' = \alpha p p=αp
    • 首先验证 p = t ⋅ h p=t \cdot h p=th,即 e ( g p , g 1 ) = e ( g t , g h ) = e ( g , g ) p = e ( g , g ) t ⋅ h e(g^p,g^1) = e(g^t,g^h) = e(g,g)^p = e(g,g)^{t \cdot h} e(gp,g1)=e(gt,gh)=e(g,g)p=e(g,g)th
    • 然后验证 α − s h i f t \alpha -shift αshift,即 e ( g p , g α ) = e ( g p ′ , g ) e(g^p,g^\alpha) = e(g^{p'},g) e(gp,gα)=e(gp,g)

注意:这里也暴露出两个问题,

  1. Proving Key 中的 E ( α ) E(\alpha) E(α)是公开的,也就是对于 Prover 来说 ,他是可以打破多项式的限制条件的。
  2. 引入了一个可信第三方,但更复杂的现实中不能保证第三方不存在恶意,比如不销毁 trusted setup 的随机秘密,这一旦暴露会导致任何人都可以伪造证明。

于是 ZKSNARK 引入了多方联合的setup,每个人用自己的私钥 ( α , s ) (\alpha,s) (α,s)和前一个人生成的 CRS 作为输入生成一个新的 CRS,只要保证有一个人销毁了私钥,就能保证最终的CRS是安全的。具体实现如下,
假设有三方 Alice,Bob,Carol 参与,仅需要使用同态乘法让每个人的私钥相加即可
image.png
同理参与方 Carol 公开后也可以进行验证。

完整的简短非交互式的多项式证明方案

这里用 { g s i } i ∈ [ d ] \{g^{s^i}\}_{i\in[d]} {gsi}i[d]代表 s 1 , … , s d s^1,\dots,s^d s1,,sd
首先确定好目标多项式 t ( x ) t(x) t(x)和 prover 的多项式的阶数 d d d,prover 需要证明他持有的多项式里含有 t ( x ) t(x) t(x)
具体如下
image.png

参考

浅谈零知识证明:背景与起源
zcash官方科普
Exploring Elliptic Curve Pairings
Quadratic Arithmetic Programs: from Zero to Hero
Why and how zk-SNARK works
ZKSNARK介绍
李威翰,张宗洋,周子博等.简洁非交互零知识证明综述[J].密码学报,2022,9(03):379-447.DOI:10.13868/j.cnki.jcr.000525.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1352803.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法28:力扣64题,最小路径和------------样本模型

题目: 给定一个二维数组matrix,一个人必须从左上角出发,最后到达右下角 。沿途只可以向下或者向右走,沿途的数字都累加就是距离累加和 * 返回累加和最小值 思路: 1. 既然是给定二维数组matrix,那么二维数…

LDD学习笔记 -- Linux内核模块

LDD学习笔记 -- 内核模块 简介LKM类型Static Linux Kernel ModuleDynamic Linux Kernel ModuleLKM编写语法 syntax详细描述内核头文件用户空间头文件Module Initialization FunctionModule Cleanup FunctionKeyword & Tag宏 __init __exitLKM入口注册Module Metadate&#…

使用Matplotlib模拟绘制北京上海气温变化折线图

02 模拟北京上海气温变化折线图 通过本练习,可以掌握如何在一个坐标系中展示多个折线图,以及如何修改折线图的颜色和样式,以及如何设置和显示图例。 在一个坐标系中绘制两条折线 要在一个坐标系中绘制两条这些,我们只需要进行两…

Python open函数详解:打开指定文件与 readline和readlines函数:按行读取文件

Python open函数详解:打开指定文件 掌握了各种操作目录字符串或目录的函数之后,接下来可以准备读写文件了。在进行文件读写之前,首先要打开文件。 Python 提供了一个内置的 open() 函数,该函数用于打开指定文件。 open() 函数的…

Matplotlib基础

目录: 一、绘制函数图像:二、创建图形对象:三、绘制多子图: 一、绘制函数图像: from matplotlib import pyplot as plt import numpy as np #生成(-50,50)的数组 x np.arange(-50,50) #计算因…

口罩佩戴监测识别摄像机

口罩佩戴监测识别摄像机是一种应用于公共场所的智能监控设备,旨在监测人们是否正确佩戴口罩。这种摄像机使用先进的图像识别技术,能够准确辨识出人们的面部,并判断是否佩戴口罩。该技术可以用于各种场所,如火车站、机场、商场、学…

IDEA 修改 jdk 版本

三步: 一 、file--setting 二、 file--Project Structure 三 、file--Project Structure

【JUC的四大同步辅助类】

文章目录 一、CountDownLatch二、CyclicBarrier三、Semaphore四、Phaser 提示:以下是本篇文章正文内容,下面案例可供参考 一、CountDownLatch CountDownLatch如同火箭发射,计数只能不断减减,当到达0时即发射 场景示例&#xff1…

gitee创建仓库

描述 本文章记录了怎么在gitee上创建项目,以及使用vscode提代码到远程呢个仓库,如何创建一个新分支,并将新分支提交到远程仓库。 1、创建远程仓库 在创建远程仓库之前要先进行ssh密钥的设置 (1)打开黑窗口&#xff…

NSSCTF 简单包含

开启环境: 使用POST传flag&#xff0c;flag目录/var/www/html/flag.php 先使用post来尝试读取该flag.php 没反应: 查看一下源码index.php&#xff0c;看有什么条件 base64解密: <?php$path $_POST["flag"];if (strlen(file_get_contents(php://input)) <…

SSH

简介 SSH&#xff1a;Secure Shell Protocol&#xff0c;安全的远程登录&#xff0c;实现加密通信&#xff0c;替代传统telnet协议。 端口&#xff1a;22/tcp 软件实现&#xff1a; OpenSSH&#xff1a;ssh协议的开源实现&#xff0c;CentOS默认安装Dropbear&#xff1a;另…

Socket closed 异常解决方案:如何解决 JMeter 压测中的问题

问题描述 JMeter 压测时会报 java.net.SocketException: Socket closed java.net.SocketException: Socket closed at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.ne…

CMake入门教程【核心篇】宏模板(macro)

&#x1f608;「CSDN主页」&#xff1a;传送门 &#x1f608;「Bilibil首页」&#xff1a;传送门 &#x1f608;「本文的内容」&#xff1a;CMake入门教程 &#x1f608;「动动你的小手」&#xff1a;点赞&#x1f44d;收藏⭐️评论&#x1f4dd; 文章目录 1. 定义宏1.1 基本语…

红日靶场-3

目录 前言 外网渗透 外网渗透打点 1、arp 2、nmap 3、nikto 4、whatweb 5、gobuster 6、dirsearch CMS 1、主页内容 2、/configuration.php~ 目录 3、/administrator 目录 4、Joomla!_version探测 5、joomlascan python脚本 6、joomscan perl脚本 MySQL 1、远…

bootstrap5实现通用果蔬网站 FoodMart页面模板

一、需求分析 通用果蔬网站是指专门提供各类果蔬产品展示和销售的在线平台。它将不同种类的新鲜水果、蔬菜、干果、坚果等聚集在一起&#xff0c;为消费者提供方便、快捷的购物渠道。通用果蔬网站的作用主要包括以下几个方面&#xff1a; 商品展示和销售&#xff1a;通用果蔬网…

[DevOps-01] DevOps介绍

一、简要描述 DevOps&#xff1a;Development & Operations的缩写&#xff0c;也就是开发&运维 DevOps是一个不断提高效率并且持续不断工作的过程。 核心&#xff1a;简化Dev和Ops团队之间的流程&#xff0c;使整体软件开发过程更快速。 DevOps定义&#xff1a; DevOps…

4462 4.曙曙献爱心

#include<bits/stdc.h> using namespace std; int n,m,k; int a[1001]; int s[1001]; int f[1001][1001];//f[i][j]&#xff0c;i个警察&#xff0c;j个点&#xff0c;能管理的最大人数 int main(){cin>>n>>m>>k;for(int i1;i<n;i){cin>>a[i…

Langchain访问OpenAI ChatGPT API Account deactivated的另类方法,访问跳板机API

笔者曾经写过 ChatGPT OpenAI API请求限制 尝试解决 Account deactivated. Please contact us through our help center at help.openai.com if you need assistance. 结果如何&#xff1f; 没有啥用。目前发现一条曲线救国的方案。 1. 在官方 openai 库中使用 此处为最新Op…

什么是Maven ??? (以及关于依赖,中央仓库,国内源)

文章目录 什么是 Maven创建第一个 Maven 项目依赖管理Maven 的仓库Maven 如何设置国内源 什么是 Maven Maven &#xff1a;用于构建和管理任何基于java的项目的工具。**说白了就是管理 Java项目 的工具。**我们希望我们已经创建了一些东西&#xff0c;可以使Java开发人员的日常…

大一C语言基础知识点圈画1(结构体,共用体指针,数组字符串)

是所有成员占内存的总和吗&#xff1f; 不是&#xff0c; 非所有成员变量的内存总和