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 1375596a74 snark.Utils packed 5 years ago
bn128 circuit CalculateWitness, added - & / in GenerateR1CS(), added doc 5 years ago
circuitcompiler snark.Utils packed 5 years ago
fields snark trusted setup + generate proof + verify proof working. Added test to bn128 pairing 5 years ago
r1csqap snark.Utils packed 5 years ago
r1csqapFloat doing trusted setup 5 years ago
.gitignore key generation for proofs, snark files to the root directory 5 years ago
LICENSE Initial commit 5 years ago
README.md snark.Utils packed 5 years ago
go.mod circuit parser (wip) 5 years ago
go.sum circuit parser (wip) 5 years ago
snark.go snark.Utils packed 5 years ago
snark_test.go snark.Utils packed 5 years ago

README.md

go-snark Go Report Card

zkSNARK library implementation in Go

Caution

Implementation 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

Example:

// compile circuit and get the R1CS
flatCode := `
func test(x):
	aux = x*x
	y = aux*x
	z = x + y
	out = z + 5
`

// parse the code
parser := circuitcompiler.NewParser(strings.NewReader(flatCode))
circuit, err := parser.Parse()
assert.Nil(t, err)
fmt.Println(circuit)

// witness
b3 := big.NewInt(int64(3))
inputs := []*big.Int{b3}
w := circuit.CalculateWitness(inputs)
fmt.Println("\nwitness", w)
/*
now we have the witness:
w = [1 3 35 9 27 30]
*/

// 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 1 0 0 0 0] [0 0 0 1 0 0] [0 1 0 0 1 0] [5 0 0 0 0 1]]
b == [[0 1 0 0 0 0] [0 1 0 0 0 0] [1 0 0 0 0 0] [1 0 0 0 0 0]]
c == [[0 0 0 1 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1] [0 0 1 0 0 0]]
*/


alphas, betas, gammas, zx := snark.Utils.PF.R1CSToQAP(a, b, c)


ax, bx, cx, px := snark.Utils.PF.CombinePolynomials(w, alphas, betas, gammas)

hx := snark.Utils.PF.DivisorPolinomial(px, zx)

// hx==px/zx so px==hx*zx
assert.Equal(t, px, snark.Utils.PF.Mul(hx, zx))

// p(x) = a(x) * b(x) - c(x) == h(x) * z(x)
abc := snark.Utils.PF.Sub(pf.Mul(ax, bx), cx)
assert.Equal(t, abc, px)
hz := snark.Utils.PF.Mul(hx, zx)
assert.Equal(t, abc, hz)
	
div, rem := snark.Utils.PF.Div(px, zx)
assert.Equal(t, hx, div)
assert.Equal(t, rem, r1csqap.ArrayOfBigZeros(4))

// calculate trusted setup
setup, err := snark.GenerateTrustedSetup(len(w), circuit, alphas, betas, gammas, zx)
assert.Nil(t, err)
fmt.Println("t", setup.Toxic.T)

// piA = g1 * A(t), piB = g2 * B(t), piC = g1 * C(t), piH = g1 * H(t)
proof, err := snark.GenerateProofs(circuit, setup, hx, w)
assert.Nil(t, err)

assert.True(t, snark.VerifyProof(circuit, setup, proof))

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.