mirror of
https://github.com/arnaucube/go-snark-study.git
synced 2026-02-02 17:26:41 +01:00
circuit parser (wip)
This commit is contained in:
13
README.md
13
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.
|
||||
|
||||
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
|
||||
- [](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.
|
||||
|
||||
@@ -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 @@ func TestG1(t *testing.T) {
|
||||
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()))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,16 +21,22 @@ func TestCircuitParser(t *testing.T) {
|
||||
m3 = m2 + s1
|
||||
out = m3 + 5
|
||||
*/
|
||||
raw := `
|
||||
y = x^x
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package circuitcompiler
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Parser struct {
|
||||
@@ -17,10 +19,12 @@ type Parser struct {
|
||||
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 @@ func (p *Parser) ParseLine() (*Constraint, error) {
|
||||
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
|
||||
}
|
||||
|
||||
1
go.mod
1
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
|
||||
|
||||
6
go.sum
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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
||||
Reference in New Issue
Block a user