zkSnarks:证明问题到QAP的转换
许多待证明的问题可以表示为多项式函数的形式,而一个多项式函数可以转化为一个算术电路,已经有文献证明算术电路可以转换成QAP问题,基于QAP问题可以构造zkSNARKs,所以基于QAP问题构造zkSNARKs的第一步是将待证明问题转换成QAP问题,本文主要讲解如何将待证明问题转换成QAP问题。
QAP定义:
给一系列多项式以及一个目标多项式,是否能根据这一系列的多项式,求得它们的一个线性组合,刚好可以整除目标多项式,如下描述,给定一个解{ai}i=0−>n\{a_i\}_{i=0->n}{ai}i=0−>n,那么验证很简单,直接除t(x)即可,但是想求解就很难:
给定一系列多项式{li(x),ri(x),oi(x)}i=0−>n\{l_i(x),r_i(x),o_i(x)\}_{i=0->n}{li(x),ri(x),oi(x)}i=0−>n ,以及目标t(x)t(x)t(x)
求一个线性组合{ai}i=0−>n\{a_i\}_{i=0->n}{ai}i=0−>n,使得:
∑i=0n{(ai∗li(x))(ai∗ri(x))−(ai∗oi(x))}=t(x)h(x)\sum_{i=0}^{n}\{(a_i*l_i(x))(a_i*r_i(x))-(a_i*o_i(x))\}=t(x)h(x) i=0∑n{(ai∗li(x))(ai∗ri(x))−(ai∗oi(x))}=t(x)h(x)
下面以 a*(b+2) = c 为例,讲解QAP的构造过程
1.多项式拍成电路,首先将多项式的所有操作转化为算术电路形式,即x(op)y=zx(op)y =zx(op)y=z,根据算术电路可以画出相应的电路图
sum1 = b + 2
c = a * sum1
2.电路转换成R1CS,R1CS描述了向量组之间的约束关系,把算术电路变量包括中间变量组成一组向量 :s = [one,c,a,b,sum1]T,s即为R1CS中的解向量,其中one表示数字1,对上面的电路进行转换:
(b+2) * 1 = sum1
x = [2 0 0 1 0]
y = [1 0 0 0 0]
z = [0 0 0 0 1]
a * sum1 = c
x = [0 0 1 0 0]
y = [0 0 0 0 1]
z = [0 1 0 0 0]
由上可得X 、Y 、Z向量
3.R1CS to QAP,我们已经得到X 、Y 、Z向量,满足:
X⋅S∗Y⋅S−Z⋅S=0X\cdot S*Y\cdot S - Z\cdot S =0 X⋅S∗Y⋅S−Z⋅S=0
代入如x=1、2 ,即t(x) =(x-1)(x-2)由拉格朗日差值定理可以计算出 li(x),ri(x),oi(x)
由(1,2) (2,0) 得 l0(x) = 4 - 2x , 取有限域GF(11)上的多项式计算,则l0(x) = 4 + 9x,下同
由(0,0) (0,0) 得 l1(x) = 0
由(1,0) (2,1) 得 l2(x) = 10 +x
由(1,1) (2,0) 得 l3(x) = 2 + 10x
由(1,0) (2,0) 得 l4(x) = 0
—————————————
由(1,1) (2,0) 得 r0(x) = 2 + 10x
由(1,0) (2,0) 得 r1(x) = 0
由(1,0) (2,0) 得 r2(x) = 0
由(1,0) (2,0) 得 r3(x) = 0
由(1,0) (2,1) 得 r4(x) = 10 + x
—————————————
由(1,0) (2,0) 得 o0(x) = 0
由(1,0) (2,1) 得 o1(x) = 10 +x
由(1,0) (2,0) 得 o2(x) = 0
由(1,0) (2,0) 得 o3(x) = 0
由(1,1) (2,0) 得 o1(x) = 2 + 10x
—————————————
由上可得li(x)、ri(x)、oi(x)
下面进行验证:
a*(b+2) = c,取 a = 3 、b=2 ,得sum1=4、c=12
s = [1,12, 3,2,4],t(x) = (x-1)(x-2) = 2 + 8x + x2
L(x) = 5 +10x ,R(x) = 9 + 3x , O(x) = 7+ 8x
P(x) = L(x)R(X) - O(x) = 5 + 9x + 8x2
h(x) = P(x)/t(x) = 8
Coding 验证
package mainimport ("fmt""github.com/arnaucube/go-snark/circuitcompiler""github.com/arnaucube/go-snark/fields""github.com/arnaucube/go-snark/r1csqap""math/big""strings"
)func main() {str := `func main(private a, private b,public c):s1 = b + 2c = a * s1`fmt.Printf("code of the circuit: %s\n", str)parser := circuitcompiler.NewParser(strings.NewReader(str))circuit, _ := parser.Parse()fmt.Println("\ncode to R1CS")a, b, c := circuit.GenerateR1CS()fmt.Printf("a: %s\n", a)fmt.Printf("b: %s\n", b)fmt.Printf("c: %d\n\n", c)fmt.Println("\nR1CS to QAP")r, _ := new(big.Int).SetString("11", 10)pf := r1csqap.NewPolynomialField(fields.NewFq(r))alphas, betas, gammas, _ := pf.R1CSToQAP(a, b, c)fmt.Printf("As: %d\n\n", alphas)fmt.Printf("Bs: %d\n\n", betas)fmt.Printf("Cs: %d\n\n", gammas)// witnessprivateVal := []*big.Int{big.NewInt(int64(3)), big.NewInt(int64(2))}publicVal := []*big.Int{big.NewInt(int64(12))}w, _ := circuit.CalculateWitness(privateVal, publicVal)fmt.Println("\nWitness: ", w)ax, bx, cx, px := pf.CombinePolynomials(w, alphas, betas, gammas)fmt.Printf("\nax: %d\n", ax)fmt.Printf("\nbx: %d\n", bx)fmt.Printf("\ncx: %d\n", cx)fmt.Printf("\npx: %d\n", px)
}
why R1CS -> QAP ?
上述构造过程中需要将R1CS约束转换成QAP问题,但是 why R1CS -> QAP ?
我们知道R1CS约束矩阵是一个m行矩阵,m代表电路中门电路的数量,如前面例子中,下面三个矩阵就是原问题对应电路的R1CS约束矩阵,每个矩阵包含了两个行向量,代表了电路中的两个电路门
此时如果我们想证明我们知道原始计算的一个解,那么就需要证明X,Y,Z矩阵中的每个行向量与解向量S的内积之后的值是符合R1CS约束的:
在大规模电路下,存在成千上万个电路门,R1CS验证效率会十分低下,于是我们把向量的内积计算转化为多项式的形式,多项式具有良好的性质,可以通过一次计算来验证所有约束的正确性,比如 prover 声称他知道一些 verifier 也知道的多项式,通过一次抽样验证就行
对于约束矩阵X,我们假设存在这样一个多项式l1(x) ,经过点(1,2)、(2,0), 通过拉格朗日插值定理 ,可以计算出
l1(x)=4+9xl_1(x) = 4+9xl1(x)=4+9x
同理我们可以得到li(x)、ri(x)、oi(x)l_i(x)、r_i(x)、o_i(x)li(x)、ri(x)、oi(x),然后可以用多项式去表示R1CS约束:
(1∗l1(x)+12∗l2(x)+3∗l3(x)+2∗l4(x)+4∗l5(x))(1*l_1(x) +12*l_2(x) +3*l_3(x)+2*l_4(x)+4*l_5(x))(1∗l1(x)+12∗l2(x)+3∗l3(x)+2∗l4(x)+4∗l5(x))
∗(1∗r1(x)+12∗r2(x)+3∗r3(x)+2∗r4(x)+4∗r5(x))* (1*r_1(x) +12*r_2(x) +3*r_3(x)+2*r_4(x)+4*r_5(x))∗(1∗r1(x)+12∗r2(x)+3∗r3(x)+2∗r4(x)+4∗r5(x))
−(1∗o1(x)+12∗o2(x)+3∗o3(x)+2∗o4(x)+4∗o5(x))- (1*o_1(x) +12*o_2(x) +3*o_3(x)+2*o_4(x)+4*o_5(x))−(1∗o1(x)+12∗o2(x)+3∗o3(x)+2∗o4(x)+4∗o5(x))
=0= 0=0
令上式左边等于p(x)p(x)p(x)
当x=1时,即验证第一个门电路(p(1)=0p(1)=0p(1)=0)
当x=2时,即验证第二个门电路 (p(2)=0p(2)=0p(2)=0 )
根据多项式的因式分解:一个多项式只要它有解,就可以将它分解成线性多项式
所以p(x)p(x)p(x)可以 表示成 :
p(x)=(x−1)(x−2)...=t(x)h(x),t(x)=(x−1)(x−2)p(x) = (x-1)(x-2)... = t(x)h(x) ,t(x) = (x-1)(x-2)p(x)=(x−1)(x−2)...=t(x)h(x),t(x)=(x−1)(x−2)
zkSnarks:证明问题到QAP的转换相关推荐
- 深入浅出零知识证明(二):zkSNARKs基本原理
前言 本文开始对零知识证明应用最广泛的技术--zkSNARKs进行介绍,本文主要介绍其原理与流程,其中应用到的密码学知识和工具很多,本人能力有限,尽量做到阐述清晰,如有错误欢迎讨论. 零知识证明学习起 ...
- 小白也能看懂的零知识证明与zk-SNARKs
作为刚刚踏入密码学的领域的一只小白,我最近在学习ZCash (ZeroCash) 的原理,也就是zk-SNARKs .将一点点感悟和理解写下来,以抛砖引玉.(不得不说看得真让人头大啊!) zk-SNA ...
- 零知识证明 - 从QSP到QAP
前一段时间,介绍了零知识证明的入门知识,通过QSP问题证明来验证另外一个NP问题的解.最近在看QAP问题相关的文章和资料,这篇文章分享一下QAP问题的理解. 0 背景介绍 QSP/QAP问题的思想都是 ...
- 【译】zkSNARKs in a nutshell
zkSNARK的可能性令人印象深刻,您可以验证计算的正确性,而无需执行它们,您甚至不会知道执行了什么 - 只是它正确地完成了. 不幸的是,大多数zkSNARKs的解释都是在某种程度上挥手致意,因此他们 ...
- 零知识证明 SNARKs C++库:libsnark教程
gadgetlib2库的使用以及如何整合ppzkSNARK的教程和范例.这分文档专为小零件(gadget)写的,推荐从上至下作为教程来阅读. 1. 面包板(protoboard)的使用和范例 这个测试 ...
- 零知识证明 - bellman源码分析
bellman是Zcash团队用Rust语言开发的一个zk-SNARK软件库,实现了Groth16算法. 项目地址:https://github.com/zcash/librustzcash/tree ...
- 蚂蚁区块链第7课 零知识证明隐私保护原理和蚂蚁BAAS接口调用实现
1,摘要 本文试图普及隐私保护和零知识证明的相关技术知识,尝试使用更简单的描述来理解复杂的数学算法和技术原理.同时,也提供了蚂蚁区块链已经实现的隐私保护的接口函数说明. 本文涉及的专业知识有零知识证明 ...
- Step1. 理解零知识证明算法之Zk-stark
Concept:zk-stark vs zk-snark 谈到ZKP算法,大伙可能听过一些,比如zk-snark,zk-stark, bulletproof, aztec, plonk等等.今天,咱就 ...
- 命题逻辑的合理性和完备性证明
命题逻辑的合理性(Soundness)和完备性(Completeness) 学习背景: 这学期在学习Michael Huth版的<面向计算机科学的数理逻辑>,老师布置了证明命题逻辑的合理性 ...
最新文章
- McAfee ENS
- Application.DoEvents()的使用
- tomcat如何修改java版本_Java程序员必备——Tomcat配置技巧Top10
- Composition-based Multi-Relational Graph Convolutional Networks 多关系图神经网络 ICLR 2020
- VBA合并csv文件
- 色彩艺术海报PSD模板 | 用色彩挑动你的情趣
- 授权函php还是提示没权限_大快人心,只需一招,BAT 毒瘤再也不敢滥用权限
- django 环境配置.
- 惯性导航系统--百科笔记
- 使用EXCEL连接PGSQL
- scratch3.0探索000
- 智能名片小程序创建名片页功能实现关键代码
- oob袋外估计matlab,机器学习:随机森林RF-OOB袋外错误率
- VMware虚拟机如何联网详解
- s22服务器未响应,王者荣耀资源包升级失败怎么办_王者荣耀S22资源包升级失败解决办法_玩游戏网...
- 中国云计算已沦为系统集成商
- 谈一谈Coders Programmer Developer的区别
- 红外成像单筒望远镜TFN TD7产品 型号评测
- Laravel php 框架的使用写出第一个hello world,Laravel 入门配置
- 【高德地图进阶】--- 使用DistrictSearch 绘制城市版块