arnaucube
arnaucube/go-snarkPublic Self-hosted repository
circuit parser (wip)
arnaucube arnaucube@gmail.com
Mon, 24 Dec 2018 22:59:18 +0100
commit

a239ffe2210a89bb4b33b1755ab1e9fa883d5ccc

parent

d42dffff22e48b2428769d4922afbfbcc78692fd

M README.md → README.md

@@ -3,9 +3,14 @@

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.pdf +- `Pinocchio: Nearly practical verifiable computation`, Bryan Parno, Craig Gentry, Jon Howell, Mariana Raykova https://eprint.iacr.org/2013/279.pdf + +## Caution +Implementation from scratch in Go to understand the concepts. Do not use in production. -`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.pdf -`Pinocchio: Nearly practical verifiable computation`, Bryan Parno, Craig Gentry, Jon Howell, Mariana Raykova https://eprint.iacr.org/2013/279.pdf +Not finished, implementing this in my free time to understand it better, so I don't have much time. + ### Usage - [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark?status.svg)](https://godoc.org/github.com/arnaucube/go-snark) zkSnark

@@ -79,7 +84,5 @@ ```

--- -## Caution -Not finished, work in progress (implementing this in my free time to understand it better, so I don't have much time). -Thanks to [@jbaylina](https://github.com/jbaylina), [@bellesmarta](https://github.com/bellesmarta), [@adriamb](https://github.com/adriamb) for their explanations that helped to understand this a little bit. +Thanks to [@jbaylina](https://github.com/jbaylina), [@bellesmarta](https://github.com/bellesmarta), [@adriamb](https://github.com/adriamb) for their explanations that helped to understand this a little bit. Also thanks to [@vbuterin](https://github.com/vbuterin) for all the published articles explaining the zkSNARKs.
M bn128/g1_test.go → bn128/g1_test.go

@@ -1,10 +1,10 @@

package bn128 import ( + "encoding/hex" "math/big" "testing" - "github.com/arnaucube/cryptofun/utils" "github.com/stretchr/testify/assert" )

@@ -26,6 +26,6 @@ assert.True(t, bn128.G1.Equal(grsum1, grsum2))

a := bn128.G1.Affine(grsum1) b := bn128.G1.Affine(grsum2) assert.Equal(t, a, b) - assert.Equal(t, "0x2f978c0ab89ebaa576866706b14787f360c4d6c3869efe5a72f7c3651a72ff00", utils.BytesToHex(a[0].Bytes())) - assert.Equal(t, "0x12e4ba7f0edca8b4fa668fe153aebd908d322dc26ad964d4cd314795844b62b2", utils.BytesToHex(a[1].Bytes())) + assert.Equal(t, "2f978c0ab89ebaa576866706b14787f360c4d6c3869efe5a72f7c3651a72ff00", hex.EncodeToString(a[0].Bytes())) + assert.Equal(t, "12e4ba7f0edca8b4fa668fe153aebd908d322dc26ad964d4cd314795844b62b2", hex.EncodeToString(a[1].Bytes())) }
M circuitcompiler/circuit.go → circuitcompiler/circuit.go

@@ -1,10 +1,32 @@

package circuitcompiler +import ( + "fmt" + "math/big" +) + type Circuit struct { NVars int NPublic int NSignals int - Inputs []int - Witness []int + Inputs []string + Signals []string + Witness []*big.Int Constraints []Constraint + R1CS struct { + A [][]*big.Int + B [][]*big.Int + C [][]*big.Int + } +} + +func (c *Circuit) GenerateR1CS() { + fmt.Print("function with inputs: ") + fmt.Println(c.Inputs) + fmt.Print("signals: ") + fmt.Println(c.Signals) + for _, constraint := range c.Constraints { + fmt.Println(constraint.Literal) + + } }
M circuitcompiler/circuit_test.go → circuitcompiler/circuit_test.go

@@ -21,16 +21,22 @@ m2 = m1 * s1

m3 = m2 + s1 out = m3 + 5 */ - raw := ` - y = x^x - z = x + y - out = z + 5 + + // flat code + flat := ` + func test(x): + aux = x*x + y = aux*x + z = x + y + out = z + 5 ` - parser := NewParser(strings.NewReader(raw)) - res, err := parser.Parse() + parser := NewParser(strings.NewReader(flat)) + circuit, err := parser.Parse() assert.Nil(t, err) - fmt.Println(res) + fmt.Println(circuit) - // flat code // flat code to R1CS + fmt.Println("generating R1CS from flat code") + circuit.GenerateR1CS() + fmt.Println(circuit.Inputs) }
M circuitcompiler/parser.go → circuitcompiler/parser.go

@@ -3,6 +3,8 @@

import ( "errors" "io" + "regexp" + "strings" ) type Parser struct {

@@ -17,10 +19,12 @@

type Constraint struct { // v1 op v2 = out Op Token - V1 Token - V2 Token - Out Token + V1 string + V2 string + Out string Literal string + + Inputs []string // in func delcaration case } func NewParser(r io.Reader) *Parser {

@@ -57,36 +61,72 @@ /*

in this version, line will be for example s3 = s1 * s4 this is: - val op val op val - ident op ident op ident + val eq val op val */ c := &Constraint{} - var lit string - c.Out, lit = p.scanIgnoreWhitespace() + tok, lit := p.scanIgnoreWhitespace() + c.Out = lit c.Literal += lit + + if c.Literal == "func" { + // format: `func name(in):` + line, err := p.s.r.ReadString(':') + if err != nil { + return c, err + } + // read string inside ( ) + rgx := regexp.MustCompile(`\((.*?)\)`) + insideParenthesis := rgx.FindStringSubmatch(line) + varsString := strings.Replace(insideParenthesis[1], " ", "", -1) + c.Inputs = strings.Split(varsString, ",") + return c, nil + } + _, lit = p.scanIgnoreWhitespace() // skip = c.Literal += lit - c.V1, lit = p.scanIgnoreWhitespace() + + // v1 + _, lit = p.scanIgnoreWhitespace() + c.V1 = lit c.Literal += lit + // operator c.Op, lit = p.scanIgnoreWhitespace() c.Literal += lit - c.V2, lit = p.scanIgnoreWhitespace() + // v2 + _, lit = p.scanIgnoreWhitespace() + c.V2 = lit c.Literal += lit - if c.Out == EOF { + if tok == EOF { return nil, errors.New("eof in parseline") } return c, nil } +func addToArrayIfNotExist(arr []string, elem string) []string { + for _, v := range arr { + if v == elem { + return arr + } + } + arr = append(arr, elem) + return arr +} func (p *Parser) Parse() (*Circuit, error) { circuit := &Circuit{} + circuit.Signals = append(circuit.Signals, "one") for { constraint, err := p.ParseLine() if err != nil { - // return circuit, err break } + if constraint.Literal == "func" { + circuit.Inputs = constraint.Inputs + continue + } circuit.Constraints = append(circuit.Constraints, *constraint) + circuit.Signals = addToArrayIfNotExist(circuit.Signals, constraint.V1) + circuit.Signals = addToArrayIfNotExist(circuit.Signals, constraint.V2) + circuit.Signals = addToArrayIfNotExist(circuit.Signals, constraint.Out) } return circuit, nil }
M go.mod → go.mod

@@ -1,7 +1,6 @@

module github.com/arnaucube/go-snark require ( - github.com/arnaucube/cryptofun v0.0.0-20181210231954-f5d913b6a74c github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.2.2
M go.sum → go.sum

@@ -1,9 +1,3 @@

-github.com/arnaucube/bn128 v0.0.0-20181124004642-3bb6b68ddbe4/go.mod h1:bIKGJe1ZaHy7HYQML7Me4q38pOpggn3JO1VPPyMe3zI= -github.com/arnaucube/cryptofun v0.0.0-20181124001128-d55d875d7a54/go.mod h1:PZE8kKpHPD1UMrS3mTfAMmEEinGtijSwjxLRqRcD64A= -github.com/arnaucube/cryptofun v0.0.0-20181124004321-9b11ae8280bd/go.mod h1:PZE8kKpHPD1UMrS3mTfAMmEEinGtijSwjxLRqRcD64A= -github.com/arnaucube/cryptofun v0.0.0-20181210231954-f5d913b6a74c h1:i0PwrCdHaQXw6KhbIS+VVj1x/GmqHgOs/LCXLeevE3c= -github.com/arnaucube/cryptofun v0.0.0-20181210231954-f5d913b6a74c/go.mod h1:jLYDEjM/9/Q/bpdj+9ZdKh2qDIgS2gqcywjg+93MyGI= -github.com/arnaucube/go-snark v0.0.0-20181207210027-19f7216d0e3d/go.mod h1:gLycS/B43DufBaH0jH8kqiE4A7w5FdOM8I9S416xh2Y= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=