Browse Source

circuit parser (wip)

pull/5/head
arnaucube 5 years ago
parent
commit
a239ffe221
7 changed files with 100 additions and 36 deletions
  1. +8
    -5
      README.md
  2. +3
    -3
      bn128/g1_test.go
  3. +24
    -2
      circuitcompiler/circuit.go
  4. +14
    -8
      circuitcompiler/circuit_test.go
  5. +51
    -11
      circuitcompiler/parser.go
  6. +0
    -1
      go.mod
  7. +0
    -6
      go.sum

+ 8
- 5
README.md

@ -3,9 +3,14 @@
zkSNARK library implementation in Go 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.
Not finished, implementing this in my free time to understand it better, so I don't have much time.
`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
### Usage ### Usage
- [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark?status.svg)](https://godoc.org/github.com/arnaucube/go-snark) zkSnark - [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark?status.svg)](https://godoc.org/github.com/arnaucube/go-snark) zkSnark
@ -79,7 +84,5 @@ go test ./... -v
--- ---
## 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.

+ 3
- 3
bn128/g1_test.go

@ -1,10 +1,10 @@
package bn128 package bn128
import ( import (
"encoding/hex"
"math/big" "math/big"
"testing" "testing"
"github.com/arnaucube/cryptofun/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -26,6 +26,6 @@ func TestG1(t *testing.T) {
a := bn128.G1.Affine(grsum1) a := bn128.G1.Affine(grsum1)
b := bn128.G1.Affine(grsum2) b := bn128.G1.Affine(grsum2)
assert.Equal(t, a, b) 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()))
} }

+ 24
- 2
circuitcompiler/circuit.go

@ -1,10 +1,32 @@
package circuitcompiler package circuitcompiler
import (
"fmt"
"math/big"
)
type Circuit struct { type Circuit struct {
NVars int NVars int
NPublic int NPublic int
NSignals int NSignals int
Inputs []int
Witness []int
Inputs []string
Signals []string
Witness []*big.Int
Constraints []Constraint 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)
}
} }

+ 14
- 8
circuitcompiler/circuit_test.go

@ -21,16 +21,22 @@ func TestCircuitParser(t *testing.T) {
m3 = m2 + s1 m3 = m2 + s1
out = m3 + 5 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) assert.Nil(t, err)
fmt.Println(res)
fmt.Println(circuit)
// flat code
// flat code to R1CS // flat code to R1CS
fmt.Println("generating R1CS from flat code")
circuit.GenerateR1CS()
fmt.Println(circuit.Inputs)
} }

+ 51
- 11
circuitcompiler/parser.go

@ -3,6 +3,8 @@ package circuitcompiler
import ( import (
"errors" "errors"
"io" "io"
"regexp"
"strings"
) )
type Parser struct { type Parser struct {
@ -17,10 +19,12 @@ type Parser struct {
type Constraint struct { type Constraint struct {
// v1 op v2 = out // v1 op v2 = out
Op Token Op Token
V1 Token
V2 Token
Out Token
V1 string
V2 string
Out string
Literal string Literal string
Inputs []string // in func delcaration case
} }
func NewParser(r io.Reader) *Parser { func NewParser(r io.Reader) *Parser {
@ -57,36 +61,72 @@ func (p *Parser) ParseLine() (*Constraint, error) {
in this version, in this version,
line will be for example s3 = s1 * s4 line will be for example s3 = s1 * s4
this is: this is:
val op val op val
ident op ident op ident
val eq val op val
*/ */
c := &Constraint{} c := &Constraint{}
var lit string
c.Out, lit = p.scanIgnoreWhitespace()
tok, lit := p.scanIgnoreWhitespace()
c.Out = lit
c.Literal += 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 = _, lit = p.scanIgnoreWhitespace() // skip =
c.Literal += lit c.Literal += lit
c.V1, lit = p.scanIgnoreWhitespace()
// v1
_, lit = p.scanIgnoreWhitespace()
c.V1 = lit
c.Literal += lit c.Literal += lit
// operator
c.Op, lit = p.scanIgnoreWhitespace() c.Op, lit = p.scanIgnoreWhitespace()
c.Literal += lit c.Literal += lit
c.V2, lit = p.scanIgnoreWhitespace()
// v2
_, lit = p.scanIgnoreWhitespace()
c.V2 = lit
c.Literal += lit c.Literal += lit
if c.Out == EOF {
if tok == EOF {
return nil, errors.New("eof in parseline") return nil, errors.New("eof in parseline")
} }
return c, nil 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) { func (p *Parser) Parse() (*Circuit, error) {
circuit := &Circuit{} circuit := &Circuit{}
circuit.Signals = append(circuit.Signals, "one")
for { for {
constraint, err := p.ParseLine() constraint, err := p.ParseLine()
if err != nil { if err != nil {
// return circuit, err
break break
} }
if constraint.Literal == "func" {
circuit.Inputs = constraint.Inputs
continue
}
circuit.Constraints = append(circuit.Constraints, *constraint) 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 return circuit, nil
} }

+ 0
- 1
go.mod

@ -1,7 +1,6 @@
module github.com/arnaucube/go-snark module github.com/arnaucube/go-snark
require ( require (
github.com/arnaucube/cryptofun v0.0.0-20181210231954-f5d913b6a74c
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.2.2 github.com/stretchr/testify v1.2.2

+ 0
- 6
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

Loading…
Cancel
Save