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 aefb298bb0 circuit CalculateWitness, added - & / in GenerateR1CS(), added doc 5 years ago
bn128 circuit CalculateWitness, added - & / in GenerateR1CS(), added doc 5 years ago
circuitcompiler circuit CalculateWitness, added - & / in GenerateR1CS(), added doc 5 years ago
fields snark trusted setup + generate proof + verify proof working. Added test to bn128 pairing 5 years ago
r1csqap circuit CalculateWitness, added - & / in GenerateR1CS(), added doc 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 circuit CalculateWitness, added - & / in GenerateR1CS(), added doc 5 years ago
go.mod circuit parser (wip) 5 years ago
go.sum circuit parser (wip) 5 years ago
snark.go circuit CalculateWitness, added - & / in GenerateR1CS(), added doc 5 years ago
snark_test.go circuit CalculateWitness, added - & / in GenerateR1CS(), added doc 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:

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
b3 := big.NewInt(int64(3))
inputs := []*big.Int{b3}
w := circuit.CalculateWitness(inputs)
fmt.Println("\nwitness", w)

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.