Browse Source

add allow import circuits in circuits language compiler

pull/10/head 0.0.2
arnaucube 5 years ago
parent
commit
de5b60b826
8 changed files with 132 additions and 1 deletions
  1. +1
    -1
      README.md
  2. +8
    -0
      circuitcompiler/circuit-test-1.circuit
  3. +7
    -0
      circuitcompiler/circuit-test-2.circuit
  4. +74
    -0
      circuitcompiler/circuit_test.go
  5. +23
    -0
      circuitcompiler/parser.go
  6. +8
    -0
      circuitexamples/import-example.circuit
  7. +7
    -0
      circuitexamples/imported-example.circuit
  8. +4
    -0
      vim-syntax/syntax/go-snark-circuit.vim

+ 1
- 1
README.md

@ -32,7 +32,7 @@ Minimal complete flow implementation:
Improvements from the minimal implementation: Improvements from the minimal implementation:
- [x] allow to call functions in circuits language - [x] allow to call functions in circuits language
- [ ] allow `import` in circuits language
- [x] allow `import` in circuits language
- [ ] allow `for` in circuits language - [ ] allow `for` in circuits language
- [ ] move witness values calculation outside the setup phase - [ ] move witness values calculation outside the setup phase
- [ ] Groth16 - [ ] Groth16

+ 8
- 0
circuitcompiler/circuit-test-1.circuit

@ -0,0 +1,8 @@
import "circuit-test-2.circuit"
func main(private s0, public s1):
s3 = exp3(s0)
s4 = sum(s3, s0)
s5 = s4 + 5
equals(s1, s5)
out = 1 * 1

+ 7
- 0
circuitcompiler/circuit-test-2.circuit

@ -0,0 +1,7 @@
func exp3(private a):
b = a * a
c = a * b
return c
func sum(private a, private b):
c = a + b
return c

+ 74
- 0
circuitcompiler/circuit_test.go

@ -1,7 +1,9 @@
package circuitcompiler package circuitcompiler
import ( import (
"bufio"
"math/big" "math/big"
"os"
"strings" "strings"
"testing" "testing"
@ -172,3 +174,75 @@ func TestCircuitWithFuncCallsParser(t *testing.T) {
assert.Equal(t, len(circuit.PublicInputs), 1) assert.Equal(t, len(circuit.PublicInputs), 1)
assert.Equal(t, len(circuit.PrivateInputs), 1) assert.Equal(t, len(circuit.PrivateInputs), 1)
} }
func TestCircuitFromFileWithImports(t *testing.T) {
circuitFile, err := os.Open("./circuit-test-1.circuit")
assert.Nil(t, err)
parser := NewParser(bufio.NewReader(circuitFile))
circuit, err := parser.Parse()
assert.Nil(t, err)
// flat code to R1CS
a, b, c := circuit.GenerateR1CS()
assert.Equal(t, "s0", circuit.PrivateInputs[0])
assert.Equal(t, "s1", circuit.PublicInputs[0])
assert.Equal(t, []string{"one", "s1", "s0", "b0", "s3", "s4", "s5", "out"}, circuit.Signals)
// expected result
b0 := big.NewInt(int64(0))
b1 := big.NewInt(int64(1))
b5 := big.NewInt(int64(5))
aExpected := [][]*big.Int{
[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
[]*big.Int{b0, b0, b1, b0, b1, b0, b0, b0},
[]*big.Int{b5, b0, b0, b0, b0, b1, b0, b0},
[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
[]*big.Int{b0, b1, b0, b0, b0, b0, b0, b0},
[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
}
bExpected := [][]*big.Int{
[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
[]*big.Int{b0, b0, b0, b1, b0, b0, b0, b0},
[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
}
cExpected := [][]*big.Int{
[]*big.Int{b0, b0, b0, b1, b0, b0, b0, b0},
[]*big.Int{b0, b0, b0, b0, b1, b0, b0, b0},
[]*big.Int{b0, b0, b0, b0, b0, b1, b0, b0},
[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
[]*big.Int{b0, b1, b0, b0, b0, b0, b0, b0},
[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
[]*big.Int{b0, b0, b0, b0, b0, b0, b0, b1},
}
assert.Equal(t, aExpected, a)
assert.Equal(t, bExpected, b)
assert.Equal(t, cExpected, c)
b3 := big.NewInt(int64(3))
privateInputs := []*big.Int{b3}
b35 := big.NewInt(int64(35))
publicInputs := []*big.Int{b35}
// Calculate Witness
w, err := circuit.CalculateWitness(privateInputs, publicInputs)
assert.Nil(t, err)
b9 := big.NewInt(int64(9))
b27 := big.NewInt(int64(27))
b30 := big.NewInt(int64(30))
wExpected := []*big.Int{b1, b35, b3, b9, b27, b30, b35, b1}
assert.Equal(t, wExpected, w)
// circuitJson, _ := json.Marshal(circuit)
// fmt.Println("circuit:", string(circuitJson))
assert.Equal(t, circuit.NPublic, 1)
assert.Equal(t, len(circuit.PublicInputs), 1)
assert.Equal(t, len(circuit.PrivateInputs), 1)
}

+ 23
- 0
circuitcompiler/parser.go

@ -1,6 +1,7 @@
package circuitcompiler package circuitcompiler
import ( import (
"bufio"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -117,6 +118,19 @@ func (p *Parser) parseLine() (*Constraint, error) {
c.Out = varToReturn c.Out = varToReturn
return c, nil return c, nil
} }
if c.Literal == "import" {
line, err := p.s.r.ReadString('\n')
if err != nil {
return c, err
}
// read string inside " "
path := strings.TrimLeft(strings.TrimRight(line, `"`), `"`)
path = strings.Replace(path, `"`, "", -1)
path = strings.Replace(path, " ", "", -1)
path = strings.Replace(path, "\n", "", -1)
c.Out = path
return c, nil
}
_, lit = p.scanIgnoreWhitespace() // skip = _, lit = p.scanIgnoreWhitespace() // skip =
c.Literal += lit c.Literal += lit
@ -302,6 +316,15 @@ func (p *Parser) Parse() (*Circuit, error) {
continue continue
} }
if constraint.Literal == "import" {
circuitFile, err := os.Open(constraint.Out)
if err != nil {
panic(errors.New("imported path error: " + constraint.Out))
}
parser := NewParser(bufio.NewReader(circuitFile))
_, err = parser.Parse() // this will add the imported file funcs into the `circuits` map
continue
}
circuits[currCircuit].Constraints = append(circuits[currCircuit].Constraints, *constraint) circuits[currCircuit].Constraints = append(circuits[currCircuit].Constraints, *constraint)
isVal, _ := isValue(constraint.V1) isVal, _ := isValue(constraint.V1)

+ 8
- 0
circuitexamples/import-example.circuit

@ -0,0 +1,8 @@
import "imported-example.circuit"
func main(private s0, public s1):
s3 = exp3(s0)
s4 = sum(s3, s0)
s5 = s4 + 5
equals(s1, s5)
out = 1 * 1

+ 7
- 0
circuitexamples/imported-example.circuit

@ -0,0 +1,7 @@
func exp3(private a):
b = a * a
c = a * b
return c
func sum(private a, private b):
c = a + b
return c

+ 4
- 0
vim-syntax/syntax/go-snark-circuit.vim

@ -24,12 +24,14 @@ syn keyword goSnarkCircuitPrivatePublic private public
syn keyword goSnarkCircuitOut out syn keyword goSnarkCircuitOut out
syn keyword goSnarkCircuitEquals equals syn keyword goSnarkCircuitEquals equals
syn keyword goSnarkCircuitFunction func syn keyword goSnarkCircuitFunction func
syn keyword goSnarkCircuitImport import
syn match goSnarkCircuitFuncCall /\<\K\k*\ze\s*(/ syn match goSnarkCircuitFuncCall /\<\K\k*\ze\s*(/
syn keyword goSnarkCircuitPrivate private nextgroup=goSnarkCircuitInputName skipwhite syn keyword goSnarkCircuitPrivate private nextgroup=goSnarkCircuitInputName skipwhite
syn keyword goSnarkCircuitPublic public nextgroup=goSnarkCircuitInputName skipwhite syn keyword goSnarkCircuitPublic public nextgroup=goSnarkCircuitInputName skipwhite
syn match goSnarkCircuitInputName '\i\+' contained syn match goSnarkCircuitInputName '\i\+' contained
syn match goSnarkCircuitBraces "[{}\[\]]" syn match goSnarkCircuitBraces "[{}\[\]]"
syn match goSnarkCircuitParens "[()]" syn match goSnarkCircuitParens "[()]"
syn region goSnarkCircuitPath start=+"+ skip=+\\\\\|\\"+ end=+"\|$+
syn sync fromstart syn sync fromstart
syn sync maxlines=100 syn sync maxlines=100
@ -44,12 +46,14 @@ hi def link goSnarkCircuitOpSymbols Operator
hi def link goSnarkCircuitFuncCall Function hi def link goSnarkCircuitFuncCall Function
hi def link goSnarkCircuitEquals Identifier hi def link goSnarkCircuitEquals Identifier
hi def link goSnarkCircuitFunction Keyword hi def link goSnarkCircuitFunction Keyword
hi def link goSnarkCircuitImport Keyword
hi def link goSnarkCircuitBraces Function hi def link goSnarkCircuitBraces Function
hi def link goSnarkCircuitPrivate Keyword hi def link goSnarkCircuitPrivate Keyword
hi def link goSnarkCircuitPublic Keyword hi def link goSnarkCircuitPublic Keyword
hi def link goSnarkCircuitInputName Special hi def link goSnarkCircuitInputName Special
hi def link goSnarkCircuitOut Special hi def link goSnarkCircuitOut Special
hi def link goSnarkCircuitPrivatePublic Keyword hi def link goSnarkCircuitPrivatePublic Keyword
hi def link goSnarkCircuitPath String
let b:current_syntax = "go-snark-circuit" let b:current_syntax = "go-snark-circuit"
if main_syntax == 'go-snark-circuit' if main_syntax == 'go-snark-circuit'

Loading…
Cancel
Save