circuit parser (wip)

This commit is contained in:
arnaucube
2018-12-24 22:59:18 +01:00
parent d42dffff22
commit a239ffe221
7 changed files with 101 additions and 37 deletions

View File

@@ -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)
}
}

View File

@@ -21,16 +21,22 @@ func TestCircuitParser(t *testing.T) {
m3 = m2 + s1
out = m3 + 5
*/
raw := `
y = x^x
z = x + y
out = z + 5
`
parser := NewParser(strings.NewReader(raw))
res, err := parser.Parse()
assert.Nil(t, err)
fmt.Println(res)
// flat code
flat := `
func test(x):
aux = x*x
y = aux*x
z = x + y
out = z + 5
`
parser := NewParser(strings.NewReader(flat))
circuit, err := parser.Parse()
assert.Nil(t, err)
fmt.Println(circuit)
// flat code to R1CS
fmt.Println("generating R1CS from flat code")
circuit.GenerateR1CS()
fmt.Println(circuit.Inputs)
}

View File

@@ -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
}