

zkSNARK实践(一)——多项式方程的证明
source link: https://learnblockchain.cn/article/3220
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

zkSNARK实践(一)——多项式方程的证明
zkSNARK全称zero-knowledge Succinct Non-Interactive Arguments of Knowledge,翻译过来叫非交互式简洁零知识证明。网上关于zkSNARK的文章很多,几乎都只讲解它的数学原理。因为它实在太难了,...
zkSNARK全称zero-knowledge Succinct Non-Interactive Arguments of Knowledge,翻译过来叫非交互式简洁零知识证明。网上关于zkSNARK的文章很多,几乎都只讲解它的数学原理。因为它实在太难了,对于大多数像本人一样的学渣来说,理解起来真的很困难。只能隐约的感觉到它是一种很牛逼的技术,具体怎么应用总是一头雾水。所以本系列文章主要通过代码实例阐述zkSNARK,进而理解和体会它的思想精髓。
Groth16
zkSNARK的工程实践有多种方案,比如Groth16,GGPR13、PLORY等,其中Groth16应用最为广泛,包括zcash、filecoin、coda等项目都用到了这个方案。它是由一个叫Groth的大神于2016提出的算法,所以叫Groth16,整个算法流程如图所示:
矩形方块代表实体,紫色圆形代表函数,箭头代表输入输出。
Groth16的步骤如下:
- 将问题转换成电路描述。
- 将电路编译 (complie) 成R1CS(一节约束系统)。
- 任何一方使用Setup生成一些随机的参数,包括 PK (proving key),VK(verifying key)。
- 证明者使用函数 Prove 函数生成证明(Proof)。
- 验证者使用 Verify 函数,验证proof的真假。
前三步是一些初始化的工作,用来生成后面两步需要的参数。
这里面涉及到了大量的数学定理公式,当然这不是我们关心的,这里我们只关心它怎么使用。还是以那个v神文章里的方程来举例。Prover要向Verfier证明他知道方程 x^3+x+5=35 的解,但不能告诉他解是多少。我们将使用go语言的一个开源库gnark,来分析这个问题。
我们定义一个结构体,里面有两个变量X和Y,对应上面的方程中的x和35。为了一般化,我们把方程中的35也定义成变量。其中X是私有的,Y是共有的,也就是说X只对Prover可见,Verfier是看不到的。Define函数里面定义了变量的关系,也就是电路的描述。
type Circuit struct {
X frontend.Variable `gnark:"x"`
Y frontend.Variable `gnark:",public"`
}
func (circuit *Circuit) Define(curveID ecc.ID, api frontend.API) error {
x3 := api.Mul(circuit.X, circuit.X, circuit.X)
api.AssertIsEqual(circuit.Y, api.Add(x3, circuit.X, 5))
return nil
}
Compile
Compile将电路编译成R1CS,前两个参数都是常数,可以先不管。complie 内部会调用上面的Define函数,将电路的描述转换成真正的电路,然后再转化成R1CS。
var cubicCircuit Circuit
r1cs, _:= frontend.Compile(ecc.BN254, backend.GROTH16, &cubicCircuit)
Setup
Setup就是对上面生成的r1cs生成随机的pk和vk。pk给Prover,vk给Verifier。
pk, vk, _ := groth16.Setup(r1cs)
Prove
Prover知道x和y的值,所以他使用它们作为见证(witness),结合上面的pk,计算出证据(proof)。这个witness包含了私有的输入X和共有的输入Y。
witness := &Circuit{
X: frontend.Value(3),
Y: frontend.Value(35),
}
proof, _ := groth16.Prove(r1cs, pk, witness)
Verify
Verifier根据Prover提供的证据(proof)和其他公开参数,验证证据的真实性。Verifier从始至终都不知道x是多少,但如果证验证通过,他就是知道Prover知道x是多少。
publicWitness := &Circuit{
Y: frontend.Value(35),
}
err = groth16.Verify(proof, vk, publicWitness)
if err != nil {
fmt.Printf("verification failed\n")
return
}
fmt.Printf("verification succeded\n")
从这个例子我们对zkSNARK的使用有了大概的印象,基本上就是这些固定的步骤。当然作为一个入门的例子,这个有点简单。而实际应用中,我们遇到的问题比这个要复杂得多。这时我们又该如何解决呢。下一篇文章我们再继续探讨。
完整的代码
https://github.com/liyue201/gnark-examples
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。
- 发表于 4小时前
- 阅读 ( 30 )
- 学分 ( 2 )
- 分类:零知识证明
Recommend
-
54
-
25
网络上讲解零知识证明的文章就不多,这些文章要不太浅显,要不太深入,很少有能给入门者整体框架上的认识。 比如,阿里巴巴零知识证明就是一个非常好的通俗理解零知识证明的例子: 阿里巴巴被强盗抓住,为了保命,他需...
-
67
README.md go-snark
-
30
大量零知识证明项目由于错误地使用了某个 zkSNARKs 合约库,引入「输入假名 (Input Aliasing) 」漏洞,可导致伪造证明、双花、重放等攻击行为发生,且攻击成本极低。众多以太坊社区开源项目受影响,其中包括三大最常用的 zkSNARKs 零知开...
-
40
早上很多朋友@我,安比实验室发表了一篇文章 zkSNARK的“输入假名”的攻击 。迅速看了看,很赞。这个攻击原理其实比较简单,但是,不深入理解zkSNARK以及使用场景的朋友...
-
17
前几天在魔笛社区分享了三个zk-SNARK技术应用的场景,可以让大家zk-SNARK(Groth16)技术和场景的结合有初步的认识。 隐私:ZCash项目 Zcash项目,大家都知道是“隐私交易”。Zcash代表了zk-SNARK的一个应用方向:隐...
-
10
零知识证明 - KZG多项式承诺 零知识证明 - KZG多项式承诺 ...
-
6
zkSNARK实践(二)——指数方程的证明 zkSNARK实践(二)——指数方程的证明...
-
4
zkSNARK实践(四)—— merkle证明 zk-SNARK...
-
5
zkSNARK实践(三)—— 哈希函数的证明 哈希是一种常用的密码学工具,它可以把一个无限大的数据空间...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK