GitHub - arnaucube/go-snark: zkSNARK library implementation in Go
source link: https://github.com/arnaucube/go-snark
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.
README.md
go-snark
zkSNARK library implementation in Go
Succinct Non-Interactive Zero Knowledge for a von Neumann Architecture
, Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, Madars Virza https://eprint.iacr.org/2013/879.pdfPinocchio: Nearly practical verifiable computation
, Bryan Parno, Craig Gentry, Jon Howell, Mariana Raykova https://eprint.iacr.org/2013/279.pdf
Caution & Warning
Implementation of the zkSNARK Pinocchio protocol from scratch in Go to understand the concepts. Do not use in production.
Not finished, implementing this in my free time to understand it better, so I don't have much time.
Currently allows to do the complete path with Pinocchio protocol :
- compile circuuit
- generate trusted setup
- calculate witness
- generate proofs
- verify proofs
Minimal complete flow implementation:
- Finite Fields (1, 2, 6, 12) operations
- G1 and G2 curve operations
- BN128 Pairing
- circuit flat code compiler
- circuit to R1CS
- polynomial operations
- R1CS to QAP
- generate trusted setup
- generate proofs
- verify proofs with BN128 pairing
Improvements from the minimal implementation:
- allow
import
in circuits language - allow
for
in circuits language - code to flat code (improve circuit compiler)
- move witness values calculation outside the setup phase
- Groth16
- multiple optimizations
Usage
- zkSnark
- bn128 (more details: https://github.com/arnaucube/go-snark/tree/master/bn128)
- Finite Fields operations
- R1CS to QAP (more details: https://github.com/arnaucube/go-snark/tree/master/r1csqap)
- Circuit Compiler
CLI usage
The cli still needs some improvements, such as seting input files, etc.
In this example we will follow the equation example from Vitalik's article: y = x^3 + x + 5
, where y==35
and x==3
. So we want to prove that we know a secret x
such as the result of the equation is 35
.
Compile circuit
Having a circuit file test.circuit
:
func test(private s0, public s1):
s2 = s0 * s0
s3 = s2 * s0
s4 = s3 + s0
s5 = s4 + 5
equals(s1, s5)
out = 1 * 1
And a private inputs file privateInputs.json
[
3
]
And a public inputs file publicInputs.json
[
35
]
In the command line, execute:
> ./go-snark-cli compile test.circuit
This will output the compiledcircuit.json
file.
Trusted Setup
Having the compiledcircuit.json
, now we can generate the TrustedSetup
:
> ./go-snark-cli trustedsetup
This will create the file trustedsetup.json
with the TrustedSetup data, and also a toxic.json
file, with the parameters to delete from the Trusted Setup
.
Generate Proofs
Assumming that we have the compiledcircuit.json
, trustedsetup.json
, privateInputs.json
and the publicInputs.json
we can now generate the Proofs
with the following command:
> ./go-snark-cli genproofs
This will store the file proofs.json
, that contains all the SNARK proofs.
Verify Proofs
Having the proofs.json
, compiledcircuit.json
, trustedsetup.json
publicInputs.json
files, we can now verify the Pairings
of the proofs, in order to verify the proofs.
> ./go-snark-cli verify
This will return a true
if the proofs are verified, or a false
if the proofs are not verified.
Library usage
Example:
// compile circuit and get the R1CS flatCode := ` func test(private s0, public s1): s2 = s0 * s0 s3 = s2 * s0 s4 = s3 + s0 s5 = s4 + 5 equals(s1, s5) out = 1 * 1 ` // parse the code parser := circuitcompiler.NewParser(strings.NewReader(flatCode)) circuit, err := parser.Parse() assert.Nil(t, err) fmt.Println(circuit) b3 := big.NewInt(int64(3)) privateInputs := []*big.Int{b3} b35 := big.NewInt(int64(35)) publicSignals := []*big.Int{b35} // witness w, err := circuit.CalculateWitness(privateInputs, publicSignals) assert.Nil(t, err) fmt.Println("witness", w) // now we have the witness: // w = [1 35 3 9 27 30 35 1] // flat code to R1CS fmt.Println("generating R1CS from flat code") a, b, c := circuit.GenerateR1CS() /* now we have the R1CS from the circuit: a: [[0 0 1 0 0 0 0 0] [0 0 0 1 0 0 0 0] [0 0 1 0 1 0 0 0] [5 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] [0 1 0 0 0 0 0 0] [1 0 0 0 0 0 0 0]] b: [[0 0 1 0 0 0 0 0] [0 0 1 0 0 0 0 0] [1 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0]] c: [[0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] [0 1 0 0 0 0 0 0] [0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 1]] */ alphas, betas, gammas, _ := snark.Utils.PF.R1CSToQAP(a, b, c) ax, bx, cx, px := Utils.PF.CombinePolynomials(w, alphas, betas, gammas) // calculate trusted setup setup, err := GenerateTrustedSetup(len(w), *circuit, alphas, betas, gammas) hx := Utils.PF.DivisorPolynomial(px, setup.Pk.Z) proof, err := GenerateProofs(*circuit, setup, w, px) b35Verif := big.NewInt(int64(35)) publicSignalsVerif := []*big.Int{b35Verif} assert.True(t, VerifyProof(*circuit, setup, proof, publicSignalsVerif, true))
Test
go test ./... -v
vim/nvim circuit syntax highlighter
For more details and installation instructions see https://github.com/arnaucube/go-snark/tree/master/vim-syntax
Thanks to @jbaylina, @bellesmarta, @adriamb for their explanations that helped to understand this a little bit. Also thanks to @vbuterin for all the published articles explaining the zkSNARKs.
Recommend
-
53
-
21
网络上讲解零知识证明的文章就不多,这些文章要不太浅显,要不太深入,很少有能给入门者整体框架上的认识。 比如,阿里巴巴零知识证明就是一个非常好的通俗理解零知识证明的例子: 阿里巴巴被强盗抓住,为了保命,他需...
-
27
大量零知识证明项目由于错误地使用了某个 zkSNARKs 合约库,引入「输入假名 (Input Aliasing) 」漏洞,可导致伪造证明、双花、重放等攻击行为发生,且攻击成本极低。众多以太坊社区开源项目受影响,其中包括三大最常用的 zkSNARKs 零知开...
-
37
早上很多朋友@我,安比实验室发表了一篇文章 zkSNARK的“输入假名”的攻击 。迅速看了看,很赞。这个攻击原理其实比较简单,但是,不深入理解zkSNARK以及使用场景的朋友...
-
62
零知识证明 - zkSNARK应用的Nullifier Hash攻击 早上很多朋友@我,安比...
-
17
前几天在魔笛社区分享了三个zk-SNARK技术应用的场景,可以让大家zk-SNARK(Groth16)技术和场景的结合有初步的认识。 隐私:ZCash项目 Zcash项目,大家都知道是“隐私交易”。Zcash代表了zk-SNARK的一个应用方向:隐...
-
8
zkSNARK实践(一)——多项式方程的证明 零知识证明...
-
1
zkSNARK实践(二)——指数方程的证明 zkSNARK实践(二)——指数方程的证明...
-
1
zkSNARK实践(四)—— merkle证明 zk-SNARK...
-
4
zkSNARK实践(三)—— 哈希函数的证明 哈希是一种常用的密码学工具,它可以把一个无限大的数据空间...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK