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 0806af6b80 flat circuit code to R1CS working 5 years ago
bn128 circuit parser (wip) 5 years ago
circuitcompiler flat circuit code to R1CS working 5 years ago
fields snark trusted setup + generate proof + verify proof working. Added test to bn128 pairing 5 years ago
r1csqap snark trusted setup + generate proof + verify proof working. Added test to bn128 pairing 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 flat circuit code to R1CS working 5 years ago
go.mod circuit parser (wip) 5 years ago
go.sum circuit parser (wip) 5 years ago
snark.go starting circuitcompiler, lexer and parser (simple version) 5 years ago
snark_test.go flat circuit code to R1CS working 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.

Usage

Example:

bn, err := bn128.NewBn128()
assert.Nil(t, err)

// new Finite Field
fqR := fields.NewFq(bn.R)

// new Polynomial Field
pf := r1csqap.NewPolynomialField(f)

// 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)
// 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 := pf.R1CSToQAP(a, b, c)

// wittness = 1, 3, 35, 9, 27, 30
w := []*big.Int{b1, b3, b35, b9, b27, b30}

ax, bx, cx, px := pf.CombinePolynomials(w, alphas, betas, gammas)

hx := pf.DivisorPolinomial(px, zx)

// hx==px/zx so px==hx*zx
assert.Equal(t, px, pf.Mul(hx, zx))

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

// calculate trusted setup
setup, err := GenerateTrustedSetup(bn, fqR, pf, 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 := GenerateProofs(bn, fqR, circuit, setup, hx, w)
assert.Nil(t, err)

assert.True(t, VerifyProof(bn, 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.