You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
arnaucube 8ad8ae35f7 minimal clean & update tests 5 years ago
bn128 circuit CalculateWitness, added - & / in GenerateR1CS(), added doc 6 years ago
circuitcompiler minimal clean & update tests 5 years ago
cli minimal clean & update tests 5 years ago
fields cli 6 years ago
r1csqap small update, fix trusted setup ops over Field R 5 years ago
r1csqapFloat doing trusted setup 6 years ago
.gitignore fixing Z(x), VkIC, Vkz, piH calculations 5 years ago
LICENSE Initial commit 6 years ago
README.md minimal clean & update tests 5 years ago
go.mod cli 6 years ago
go.sum cli 6 years ago
snark.go minimal clean & update tests 5 years ago
snark_test.go minimal clean & update tests 5 years ago

README.md

go-snark Go Report Card

zkSNARK library implementation in Go

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.

Current implementation status:

Usage

Library usage

Warning: not finished.

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))

CLI usage

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.

Test

go test ./... -v

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.