Browse Source

add allow import circuits in circuits language compiler

pull/10/head 0.0.2
arnaucube 4 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:
- [x] allow to call functions in circuits language
- [ ] allow `import` in circuits language
- [x] allow `import` in circuits language
- [ ] allow `for` in circuits language
- [ ] move witness values calculation outside the setup phase
- [ ] 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
import (
"bufio"
"math/big"
"os"
"strings"
"testing"
@ -172,3 +174,75 @@ func TestCircuitWithFuncCallsParser(t *testing.T) {
assert.Equal(t, len(circuit.PublicInputs), 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
import (
"bufio"
"errors"
"fmt"
"io"
@ -117,6 +118,19 @@ func (p *Parser) parseLine() (*Constraint, error) {
c.Out = varToReturn
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 =
c.Literal += lit
@ -302,6 +316,15 @@ func (p *Parser) Parse() (*Circuit, error) {
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)
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 goSnarkCircuitEquals equals
syn keyword goSnarkCircuitFunction func
syn keyword goSnarkCircuitImport import
syn match goSnarkCircuitFuncCall /\<\K\k*\ze\s*(/
syn keyword goSnarkCircuitPrivate private nextgroup=goSnarkCircuitInputName skipwhite
syn keyword goSnarkCircuitPublic public nextgroup=goSnarkCircuitInputName skipwhite
syn match goSnarkCircuitInputName '\i\+' contained
syn match goSnarkCircuitBraces "[{}\[\]]"
syn match goSnarkCircuitParens "[()]"
syn region goSnarkCircuitPath start=+"+ skip=+\\\\\|\\"+ end=+"\|$+
syn sync fromstart
syn sync maxlines=100
@ -44,12 +46,14 @@ hi def link goSnarkCircuitOpSymbols Operator
hi def link goSnarkCircuitFuncCall Function
hi def link goSnarkCircuitEquals Identifier
hi def link goSnarkCircuitFunction Keyword
hi def link goSnarkCircuitImport Keyword
hi def link goSnarkCircuitBraces Function
hi def link goSnarkCircuitPrivate Keyword
hi def link goSnarkCircuitPublic Keyword
hi def link goSnarkCircuitInputName Special
hi def link goSnarkCircuitOut Special
hi def link goSnarkCircuitPrivatePublic Keyword
hi def link goSnarkCircuitPath String
let b:current_syntax = "go-snark-circuit"
if main_syntax == 'go-snark-circuit'

Loading…
Cancel
Save