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
|
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
|
||||||
- [](https://godoc.org/github.com/arnaucube/go-snark) zkSnark
|
- [](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
|
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, "2f978c0ab89ebaa576866706b14787f360c4d6c3869efe5a72f7c3651a72ff00", hex.EncodeToString(a[0].Bytes()))
|
||||||
assert.Equal(t, "0x12e4ba7f0edca8b4fa668fe153aebd908d322dc26ad964d4cd314795844b62b2", utils.BytesToHex(a[1].Bytes()))
|
assert.Equal(t, "12e4ba7f0edca8b4fa668fe153aebd908d322dc26ad964d4cd314795844b62b2", hex.EncodeToString(a[1].Bytes()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
Inputs []string
|
||||||
Witness []int
|
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)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
// flat code
|
||||||
|
flat := `
|
||||||
|
func test(x):
|
||||||
|
aux = x*x
|
||||||
|
y = aux*x
|
||||||
z = x + y
|
z = x + y
|
||||||
out = z + 5
|
out = z + 5
|
||||||
`
|
`
|
||||||
parser := NewParser(strings.NewReader(raw))
|
parser := NewParser(strings.NewReader(flat))
|
||||||
res, err := parser.Parse()
|
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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
V1 string
|
||||||
V2 Token
|
V2 string
|
||||||
Out Token
|
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
|
val eq val op val
|
||||||
ident op ident op ident
|
|
||||||
*/
|
*/
|
||||||
c := &Constraint{}
|
c := &Constraint{}
|
||||||
var lit string
|
tok, lit := p.scanIgnoreWhitespace()
|
||||||
c.Out, 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
|
||||||
}
|
}
|
||||||
|
|||||||
1
go.mod
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
|
||||||
|
|||||||
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 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=
|
||||||
|
|||||||
Reference in New Issue
Block a user