Browse Source

new variable renaming logic

new renaming logic preparations

new renaming logic preparations
pull/8/head
mottla 5 years ago
parent
commit
7aaf0527e4
7 changed files with 371 additions and 317 deletions
  1. +125
    -117
      .idea/workspace.xml
  2. +131
    -129
      circuitcompiler/Programm.go
  3. +27
    -27
      circuitcompiler/Programm_test.go
  4. +83
    -39
      circuitcompiler/circuit.go
  5. +1
    -1
      circuitcompiler/circuit_test.go
  6. +2
    -2
      circuitcompiler/parser.go
  7. +2
    -2
      r1csqap/r1csqap.go

+ 125
- 117
.idea/workspace.xml

@ -5,6 +5,7 @@
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/circuitcompiler/Programm.go" beforeDir="false" afterPath="$PROJECT_DIR$/circuitcompiler/Programm.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/circuitcompiler/circuit.go" beforeDir="false" afterPath="$PROJECT_DIR$/circuitcompiler/circuit.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/circuitcompiler/parser.go" beforeDir="false" afterPath="$PROJECT_DIR$/circuitcompiler/parser.go" afterDir="false" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
@ -17,8 +18,8 @@
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/circuitcompiler/Programm_test.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="149">
<caret line="24" column="26" selection-start-line="24" selection-start-column="26" selection-end-line="24" selection-end-column="26" />
<state relative-caret-position="381">
<caret line="38" column="19" lean-forward="true" selection-start-line="38" selection-start-column="19" selection-end-line="38" selection-end-column="19" />
</state>
</provider>
</entry>
@ -35,7 +36,7 @@
<file pinned="false" current-in-tab="false">
<entry file="file:///usr/local/go/src/testing/testing.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="171">
<state relative-caret-position="11625">
<caret line="791" selection-start-line="791" selection-end-line="791" />
</state>
</provider>
@ -50,11 +51,11 @@
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/circuitcompiler/Programm.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="191">
<caret line="399" lean-forward="true" selection-start-line="399" selection-end-line="399" />
<state relative-caret-position="210">
<caret line="364" column="33" lean-forward="true" selection-start-line="364" selection-start-column="33" selection-end-line="364" selection-end-column="33" />
<folding>
<element signature="e#25#165#0" expanded="true" />
</folding>
@ -62,11 +63,23 @@
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/circuitcompiler/circuit.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="176">
<caret line="74" column="32" lean-forward="true" selection-start-line="74" selection-start-column="32" selection-end-line="74" selection-end-column="32" />
<state relative-caret-position="394">
<caret line="166" column="32" selection-start-line="166" selection-start-column="32" selection-end-line="166" selection-end-column="32" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/circuitcompiler/parser.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2265">
<caret line="156" column="34" selection-start-line="156" selection-start-column="34" selection-end-line="156" selection-end-column="34" />
<folding>
<element signature="e#25#72#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
@ -74,8 +87,8 @@
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/r1csqap/r1csqap.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="585">
<caret line="45" column="5" selection-start-line="45" selection-start-column="5" selection-end-line="45" selection-end-column="5" />
<state relative-caret-position="315">
<caret line="27" column="30" lean-forward="true" selection-start-line="27" selection-start-column="30" selection-end-line="27" selection-end-column="30" />
</state>
</provider>
</entry>
@ -145,14 +158,14 @@
<option value="$PROJECT_DIR$/../../go-lexer/lexer.go" />
<option value="$PROJECT_DIR$/circuitcompiler/lexer/lexer.go" />
<option value="$PROJECT_DIR$/circuitcompiler/lexer/lexer_test/lexer_test.go" />
<option value="$PROJECT_DIR$/circuitcompiler/parser.go" />
<option value="$PROJECT_DIR$/r1csqap/r1csqap.go" />
<option value="$PROJECT_DIR$/snark.go" />
<option value="$PROJECT_DIR$/snark_test.go" />
<option value="$PROJECT_DIR$/circuitcompiler/Programm_test.go" />
<option value="$PROJECT_DIR$/circuitcompiler/test.py" />
<option value="$PROJECT_DIR$/circuitcompiler/circuit.go" />
<option value="$PROJECT_DIR$/r1csqap/r1csqap.go" />
<option value="$PROJECT_DIR$/circuitcompiler/parser.go" />
<option value="$PROJECT_DIR$/circuitcompiler/Programm.go" />
<option value="$PROJECT_DIR$/circuitcompiler/circuit.go" />
</list>
</option>
</component>
@ -167,7 +180,6 @@
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="Scope" />
<pane id="ProjectPane">
<subPane>
<expand>
@ -184,65 +196,11 @@
<item name="go-snark" type="b2602c69:ProjectViewProjectNode" />
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
</path>
<path>
<item name="go-snark" type="b2602c69:ProjectViewProjectNode" />
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
<item name="Go SDK 1.11.2" type="20ee2d1f:SyntheticLibraryElementNode" />
</path>
<path>
<item name="go-snark" type="b2602c69:ProjectViewProjectNode" />
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
<item name="Go SDK 1.11.2" type="20ee2d1f:SyntheticLibraryElementNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="go-snark" type="b2602c69:ProjectViewProjectNode" />
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
<item name="Go SDK 1.11.2" type="20ee2d1f:SyntheticLibraryElementNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="go" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="go-snark" type="b2602c69:ProjectViewProjectNode" />
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
<item name="Go SDK 1.11.2" type="20ee2d1f:SyntheticLibraryElementNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="go" type="462c0819:PsiDirectoryNode" />
<item name="parser" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="go-snark" type="b2602c69:ProjectViewProjectNode" />
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
<item name="Go SDK 1.11.2" type="20ee2d1f:SyntheticLibraryElementNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="go" type="462c0819:PsiDirectoryNode" />
<item name="token" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="go-snark" type="b2602c69:ProjectViewProjectNode" />
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
<item name="Go SDK 1.11.2" type="20ee2d1f:SyntheticLibraryElementNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="image" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="go-snark" type="b2602c69:ProjectViewProjectNode" />
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
<item name="Go SDK 1.11.2" type="20ee2d1f:SyntheticLibraryElementNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="index" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="go-snark" type="b2602c69:ProjectViewProjectNode" />
<item name="External Libraries" type="cb654da1:ExternalLibrariesNode" />
<item name="Go SDK 1.11.2" type="20ee2d1f:SyntheticLibraryElementNode" />
<item name="src" type="462c0819:PsiDirectoryNode" />
<item name="mime" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="Scope" />
</panes>
</component>
<component name="PropertiesComponent">
@ -343,34 +301,34 @@
</recent_temporary>
</component>
<component name="TestHistory">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 09h 52m 13s.xml">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 21h 42m 51s.xml">
<configuration name="TestNewProgramm in github.com/mottla/go-snark/circuitcompiler" configurationId="GoTestRunConfiguration" />
</history-entry>
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 09h 57m 21s.xml">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.24 at 08h 36m 33s.xml">
<configuration name="TestNewProgramm in github.com/mottla/go-snark/circuitcompiler" configurationId="GoTestRunConfiguration" />
</history-entry>
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 09h 57m 24s.xml">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.24 at 08h 38m 35s.xml">
<configuration name="TestNewProgramm in github.com/mottla/go-snark/circuitcompiler" configurationId="GoTestRunConfiguration" />
</history-entry>
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 09h 58m 26s.xml">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.24 at 08h 42m 49s.xml">
<configuration name="TestNewProgramm in github.com/mottla/go-snark/circuitcompiler" configurationId="GoTestRunConfiguration" />
</history-entry>
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 10h 10m 46s.xml">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.24 at 08h 47m 09s.xml">
<configuration name="TestNewProgramm in github.com/mottla/go-snark/circuitcompiler" configurationId="GoTestRunConfiguration" />
</history-entry>
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 10h 10m 48s.xml">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.24 at 08h 49m 21s.xml">
<configuration name="TestNewProgramm in github.com/mottla/go-snark/circuitcompiler" configurationId="GoTestRunConfiguration" />
</history-entry>
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 10h 14m 40s.xml">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.24 at 08h 52m 52s.xml">
<configuration name="TestNewProgramm in github.com/mottla/go-snark/circuitcompiler" configurationId="GoTestRunConfiguration" />
</history-entry>
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 10h 16m 30s.xml">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.24 at 08h 52m 53s.xml">
<configuration name="TestNewProgramm in github.com/mottla/go-snark/circuitcompiler" configurationId="GoTestRunConfiguration" />
</history-entry>
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 10h 16m 31s.xml">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.24 at 09h 57m 52s.xml">
<configuration name="TestNewProgramm in github.com/mottla/go-snark/circuitcompiler" configurationId="GoTestRunConfiguration" />
</history-entry>
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.23 at 10h 21m 54s.xml">
<history-entry file="TestNewProgramm_in_github_com_mottla_go-snark_circuitcompiler - 2019.05.24 at 09h 57m 53s.xml">
<configuration name="TestNewProgramm in github.com/mottla/go-snark/circuitcompiler" configurationId="GoTestRunConfiguration" />
</history-entry>
</component>
@ -385,14 +343,13 @@
</component>
<component name="ToolWindowManager">
<frame x="64" y="-11" width="1857" height="1020" extended-state="6" />
<editor active="true" />
<layout>
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.16141514" />
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.18518518" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info id="Favorites" order="2" side_tool="true" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" weight="0.32893288" />
<window_info active="true" anchor="bottom" id="Run" order="2" visible="true" weight="0.3751375" />
<window_info active="true" anchor="bottom" id="Run" order="2" visible="true" weight="0.34543455" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.39823982" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
@ -442,7 +399,9 @@
<MESSAGE value="optimizing R1CS representation" />
<MESSAGE value="cleaning up a bit" />
<MESSAGE value="working on multiplication gate reduction algo" />
<option name="LAST_COMMIT_MESSAGE" value="working on multiplication gate reduction algo" />
<MESSAGE value="constraint is no longer a reference pointer" />
<MESSAGE value="new renaming logic preparations" />
<option name="LAST_COMMIT_MESSAGE" value="new renaming logic preparations" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
@ -494,14 +453,63 @@
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>244</line>
<line>204</line>
<option name="timeStamp" value="79" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>111</line>
<line>421</line>
<option name="timeStamp" value="107" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>425</line>
<option name="timeStamp" value="108" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>406</line>
<option name="timeStamp" value="109" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>410</line>
<option name="timeStamp" value="111" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>275</line>
<option name="timeStamp" value="135" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>276</line>
<properties />
<option name="timeStamp" value="138" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>299</line>
<properties />
<option name="timeStamp" value="140" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>292</line>
<properties />
<option name="timeStamp" value="141" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>370</line>
<properties />
<option name="timeStamp" value="144" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/circuitcompiler/Programm.go</url>
<line>380</line>
<properties />
<option name="timeStamp" value="105" />
<option name="timeStamp" value="145" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
@ -644,16 +652,6 @@
<entry file="file:///usr/local/go/src/image/png/testdata/benchPaletted.png">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/circuitcompiler/parser.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1830">
<caret line="127" column="9" selection-start-line="127" selection-start-column="9" selection-end-line="127" selection-end-column="9" />
<folding>
<element signature="e#25#72#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/fields/fq6.go">
<provider selected="true" editor-type-id="text-editor" />
</entry>
@ -734,10 +732,27 @@
</state>
</provider>
</entry>
<entry file="file:///usr/local/go/src/testing/testing.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="11625">
<caret line="791" selection-start-line="791" selection-end-line="791" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circuitcompiler/parser.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2265">
<caret line="156" column="34" selection-start-line="156" selection-start-column="34" selection-end-line="156" selection-end-column="34" />
<folding>
<element signature="e#25#72#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/r1csqap/r1csqap.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="585">
<caret line="45" column="5" selection-start-line="45" selection-start-column="5" selection-end-line="45" selection-end-column="5" />
<state relative-caret-position="315">
<caret line="27" column="30" lean-forward="true" selection-start-line="27" selection-start-column="30" selection-end-line="27" selection-end-column="30" />
</state>
</provider>
</entry>
@ -761,13 +776,6 @@
</state>
</provider>
</entry>
<entry file="file:///usr/local/go/src/testing/testing.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="171">
<caret line="791" selection-start-line="791" selection-end-line="791" />
</state>
</provider>
</entry>
<entry file="file:///usr/local/go/src/runtime/panic.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="164">
@ -777,25 +785,25 @@
</entry>
<entry file="file://$PROJECT_DIR$/circuitcompiler/Programm_test.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="149">
<caret line="24" column="26" selection-start-line="24" selection-start-column="26" selection-end-line="24" selection-end-column="26" />
<state relative-caret-position="381">
<caret line="38" column="19" lean-forward="true" selection-start-line="38" selection-start-column="19" selection-end-line="38" selection-end-column="19" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circuitcompiler/Programm.go">
<entry file="file://$PROJECT_DIR$/circuitcompiler/circuit.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="191">
<caret line="399" lean-forward="true" selection-start-line="399" selection-end-line="399" />
<folding>
<element signature="e#25#165#0" expanded="true" />
</folding>
<state relative-caret-position="394">
<caret line="166" column="32" selection-start-line="166" selection-start-column="32" selection-end-line="166" selection-end-column="32" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circuitcompiler/circuit.go">
<entry file="file://$PROJECT_DIR$/circuitcompiler/Programm.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="176">
<caret line="74" column="32" lean-forward="true" selection-start-line="74" selection-start-column="32" selection-end-line="74" selection-end-column="32" />
<state relative-caret-position="210">
<caret line="364" column="33" lean-forward="true" selection-start-line="364" selection-start-column="33" selection-end-line="364" selection-end-column="33" />
<folding>
<element signature="e#25#165#0" expanded="true" />
</folding>
</state>
</provider>
</entry>

+ 131
- 129
circuitcompiler/Programm.go

@ -6,6 +6,7 @@ import (
"github.com/mottla/go-snark/fields"
"github.com/mottla/go-snark/r1csqap"
"math/big"
"sync"
)
type utils struct {
@ -15,11 +16,11 @@ type utils struct {
}
type Program struct {
functions map[string]*Circuit
globalInputs []Constraint
arithmeticEnvironment utils //find a better name
extendedFunctionRenamer func(context *Circuit, c Constraint) (newContext *Circuit)
R1CS struct {
functions map[string]*Circuit
globalInputs []Constraint
arithmeticEnvironment utils //find a better name
R1CS struct {
A [][]*big.Int
B [][]*big.Int
C [][]*big.Int
@ -35,16 +36,26 @@ func (p *Program) PrintContraintTrees() {
func (p *Program) BuildConstraintTrees() {
functionRootMap := make(map[string]*gate)
for _, circuit := range p.functions {
//circuit.addConstraint(p.oneConstraint())
fName := composeNewFunction(circuit.Name, circuit.Inputs)
root := circuit.gateMap[fName]
functionRootMap[fName] = root
circuit.root = root
circuit.buildTree(root)
mainRoot := p.getMainCircuit().root
if mainRoot.value.Op&(MINUS|PLUS) != 0 {
newOut := Constraint{Out: "out", V1: "1", V2: "out2", Op: MULTIPLY}
p.getMainCircuit().addConstraint(&newOut)
mainRoot.value.Out = "main@out2"
p.getMainCircuit().gateMap[mainRoot.value.Out] = mainRoot
}
var wg = sync.WaitGroup{}
for _, circuit := range p.functions {
wg.Add(1)
func() {
circuit.buildTree(circuit.root)
wg.Done()
}()
}
wg.Wait()
return
}
@ -61,8 +72,6 @@ func (c *Circuit) buildTree(g *gate) {
//g.funcInputs = []*gate{}
for _, in := range g.value.Inputs {
if gate, ex := c.gateMap[in]; ex {
//sadf
g.funcInputs = append(g.funcInputs, gate)
//note that we do repeated work here. the argument
c.buildTree(gate)
@ -90,56 +99,11 @@ func (c *Circuit) buildTree(g *gate) {
func (p *Program) ReduceCombinedTree() (orderedmGates []gate) {
mGatesUsed := make(map[string]bool)
orderedmGates = []gate{}
functionRootMap := make(map[string]*gate)
for k, v := range p.functions {
functionRootMap[k] = v.root
}
p.extendedFunctionRenamer = func(context *Circuit, c Constraint) (nextContext *Circuit) {
if c.Op != FUNC {
panic("not a function")
}
if _, ex := context.gateMap[c.Out]; !ex {
panic("constraint mus be within the context circuit")
}
if b, name, in := isFunction(c.Out); b {
if newContext, v := p.functions[name]; v {
//fmt.Println("unrenamed thing")
//PrintTree(k.root)
for i, argument := range in {
if gate, ex := context.gateMap[argument]; ex {
oldGate := newContext.gateMap[newContext.Inputs[i]]
//we take the old gate which was nothing but a input
//and link this input to its constituents comming from the calling context.
//i think this is pretty neat
oldGate.value = gate.value
oldGate.right = gate.right
oldGate.left = gate.left
} else {
panic("not expected")
}
}
newContext.renameInputs(in)
//fmt.Println("renamed thing")
//PrintTree(k.root)
return newContext
}
}
panic("not a function dude")
return nil
}
//traverseCombinedMultiplicationGates(p.getMainCircut().root, mGatesUsed, &orderedmGates, functionRootMap, functionRenamer, false, false)
//markMgates(p.getMainCircut().root, mGatesUsed, &orderedmGates, functionRenamer, false, false)
p.markMgates2(p.getMainCircut(), p.getMainCircut().root, mGatesUsed, &orderedmGates, false, false)
p.r1CSRecursiveBuild(p.getMainCircuit(), p.getMainCircuit().root, mGatesUsed, &orderedmGates, false, false)
return orderedmGates
}
func (p *Program) markMgates2(contextCircut *Circuit, root *gate, mGatesUsed map[string]bool, orderedmGates *[]gate, negate bool, inverse bool) (isConstant bool) {
func (p *Program) r1CSRecursiveBuild(currentCircuit *Circuit, root *gate, mGatesUsed map[string]bool, orderedmGates *[]gate, negate bool, inverse bool) (isConstant bool) {
if root.OperationType() == IN {
return false
@ -149,27 +113,31 @@ func (p *Program) markMgates2(contextCircut *Circuit, root *gate, mGatesUsed map
return true
}
if _, alreadyComputed := mGatesUsed[root.value.Out]; alreadyComputed {
return false
}
if root.OperationType() == FUNC {
nextContext := p.extendedFunctionRenamer(contextCircut, root.value)
isConstant = p.markMgates2(nextContext, nextContext.root, mGatesUsed, orderedmGates, negate, inverse)
} else {
if _, alreadyComputed := mGatesUsed[root.value.V1]; !alreadyComputed {
isConstant = p.markMgates2(contextCircut, root.left, mGatesUsed, orderedmGates, negate, inverse)
}
nextContext := p.extendedFunctionRenamer(currentCircuit, root.value)
isConstant = p.r1CSRecursiveBuild(nextContext, nextContext.root, mGatesUsed, orderedmGates, negate, inverse)
return isConstant
}
if _, alreadyComputed := mGatesUsed[root.value.V2]; !alreadyComputed {
cons := p.markMgates2(contextCircut, root.right, mGatesUsed, orderedmGates, Xor(negate, root.value.negate), Xor(inverse, root.value.invert))
isConstant = isConstant || cons
}
if _, alreadyComputed := mGatesUsed[root.value.V1]; !alreadyComputed {
isConstant = p.r1CSRecursiveBuild(currentCircuit, root.left, mGatesUsed, orderedmGates, negate, inverse)
}
if _, alreadyComputed := mGatesUsed[root.value.V2]; !alreadyComputed {
cons := p.r1CSRecursiveBuild(currentCircuit, root.right, mGatesUsed, orderedmGates, Xor(negate, root.value.negate), Xor(inverse, root.value.invert))
isConstant = isConstant || cons
}
if root.OperationType() == MULTIPLY {
_, n, _ := isFunction(root.value.Out)
if isConstant && !root.value.invert && n != "main" {
if isConstant && !root.value.invert && root != p.getMainCircuit().root {
return false
}
root.leftIns = p.collectAtomsInSubtree2(contextCircut, root.left, mGatesUsed, false, false)
root.leftIns = p.collectFactors(currentCircuit, root.left, mGatesUsed, false, false)
//if root.left.value.Out== root.right.value.Out{
// //note this is not a full copy, but shouldnt be a problem
// root.rightIns= root.leftIns
@ -177,10 +145,16 @@ func (p *Program) markMgates2(contextCircut *Circuit, root *gate, mGatesUsed map
// collectAtomsInSubtree(root.right, mGatesUsed, 1, root.rightIns, functionRootMap, Xor(negate, root.value.negate), Xor(inverse, root.value.invert))
//}
//root.rightIns = collectAtomsInSubtree3(root.right, mGatesUsed, Xor(negate, root.value.negate), Xor(inverse, root.value.invert))
root.rightIns = p.collectAtomsInSubtree2(contextCircut, root.right, mGatesUsed, false, false)
root.rightIns = p.collectFactors(currentCircuit, root.right, mGatesUsed, false, false)
root.index = len(mGatesUsed)
mGatesUsed[root.value.Out] = true
var nn = root.value.Out
//if _, ex := p.functions[nn]; ex {
// nn = composeNewFunction(root.value.Out, currentCircuit.Inputs)
//}
mGatesUsed[nn] = true
rootGate := cloneGate(root)
rootGate.value.Out = nn
*orderedmGates = append(*orderedmGates, *rootGate)
}
@ -260,10 +234,12 @@ func abs(n int) (val int, positive bool) {
//returns the reduced sum of two input factor arrays
//if no reduction was done (worst case), it returns the concatenation of the input arrays
func addFactors(leftFactors, rightFactors []factor) (res []factor) {
func addFactors(leftFactors, rightFactors []factor) []factor {
var found bool
res := make([]factor, 0, len(leftFactors)+len(rightFactors))
for _, facLeft := range leftFactors {
found = false
for i, facRight := range rightFactors {
if facLeft.typ&facRight.typ == CONST {
@ -274,8 +250,10 @@ func addFactors(leftFactors, rightFactors []factor) (res []factor) {
if facRight.negate {
b0 *= -1
}
absValue, negate := abs(a0*facRight.multiplicative[1] + facLeft.multiplicative[1]*b0)
rightFactors[i] = factor{typ: CONST, negate: negate, multiplicative: [2]int{absValue, facLeft.multiplicative[1] * facRight.multiplicative[1]}}
absValue, positive := abs(a0*facRight.multiplicative[1] + facLeft.multiplicative[1]*b0)
rightFactors[i] = factor{typ: CONST, negate: !positive, multiplicative: [2]int{absValue, facLeft.multiplicative[1] * facRight.multiplicative[1]}}
found = true
//res = append(res, factor{typ: CONST, negate: negate, multiplicative: [2]int{absValue, facLeft.multiplicative[1] * facRight.multiplicative[1]}})
break
@ -288,8 +266,10 @@ func addFactors(leftFactors, rightFactors []factor) (res []factor) {
if facRight.negate {
b0 *= -1
}
absValue, negate := abs(a0*facRight.multiplicative[1] + facLeft.multiplicative[1]*b0)
rightFactors[i] = factor{typ: IN, invert: facRight.invert, name: facRight.name, negate: negate, multiplicative: [2]int{absValue, facLeft.multiplicative[1] * facRight.multiplicative[1]}}
absValue, positive := abs(a0*facRight.multiplicative[1] + facLeft.multiplicative[1]*b0)
rightFactors[i] = factor{typ: IN, invert: facRight.invert, name: facRight.name, negate: !positive, multiplicative: [2]int{absValue, facLeft.multiplicative[1] * facRight.multiplicative[1]}}
found = true
//res = append(res, factor{typ: CONST, negate: negate, multiplicative: [2]int{absValue, facLeft.multiplicative[1] * facRight.multiplicative[1]}})
break
@ -297,13 +277,19 @@ func addFactors(leftFactors, rightFactors []factor) (res []factor) {
}
if !found {
res = append(res, facLeft)
found = false
}
}
return append(res, rightFactors...)
for _, val := range rightFactors {
if val.multiplicative[0] != 0 {
res = append(res, val)
}
}
return res
}
func (p *Program) collectAtomsInSubtree2(contextCircut *Circuit, g *gate, mGatesUsed map[string]bool, negate bool, invert bool) []factor {
func (p *Program) collectFactors(contextCircut *Circuit, g *gate, mGatesUsed map[string]bool, negate bool, invert bool) []factor {
if _, ex := mGatesUsed[g.value.Out]; ex {
return []factor{{typ: IN, name: g.value.Out, invert: invert, negate: negate, multiplicative: [2]int{1, 1}}}
@ -314,7 +300,7 @@ func (p *Program) collectAtomsInSubtree2(contextCircut *Circuit, g *gate, mGates
}
if g.OperationType() == FUNC {
nextContext := p.extendedFunctionRenamer(contextCircut, g.value)
return p.collectAtomsInSubtree2(nextContext, nextContext.root, mGatesUsed, negate, invert)
return p.collectFactors(nextContext, nextContext.root, mGatesUsed, negate, invert)
}
if g.OperationType() == CONST {
@ -331,16 +317,16 @@ func (p *Program) collectAtomsInSubtree2(contextCircut *Circuit, g *gate, mGates
var leftFactors, rightFactors []factor
if g.left.OperationType() == FUNC {
nextContext := p.extendedFunctionRenamer(contextCircut, g.left.value)
leftFactors = p.collectAtomsInSubtree2(nextContext, nextContext.root, mGatesUsed, negate, invert)
leftFactors = p.collectFactors(nextContext, nextContext.root, mGatesUsed, negate, invert)
} else {
leftFactors = p.collectAtomsInSubtree2(contextCircut, g.left, mGatesUsed, negate, invert)
leftFactors = p.collectFactors(contextCircut, g.left, mGatesUsed, negate, invert)
}
if g.right.OperationType() == FUNC {
nextContext := p.extendedFunctionRenamer(contextCircut, g.right.value)
rightFactors = p.collectAtomsInSubtree2(nextContext, nextContext.root, mGatesUsed, Xor(negate, g.value.negate), Xor(invert, g.value.invert))
rightFactors = p.collectFactors(nextContext, nextContext.root, mGatesUsed, Xor(negate, g.value.negate), Xor(invert, g.value.invert))
} else {
rightFactors = p.collectAtomsInSubtree2(contextCircut, g.right, mGatesUsed, Xor(negate, g.value.negate), Xor(invert, g.value.invert))
rightFactors = p.collectFactors(contextCircut, g.right, mGatesUsed, Xor(negate, g.value.negate), Xor(invert, g.value.invert))
}
switch g.OperationType() {
@ -356,7 +342,7 @@ func (p *Program) collectAtomsInSubtree2(contextCircut *Circuit, g *gate, mGates
//copies a gate neglecting its references to other gates
func cloneGate(in *gate) (out *gate) {
constr := Constraint{Inputs: in.value.Inputs, Out: in.value.Out, Op: in.value.Op, invert: in.value.invert, negate: in.value.negate, V2: in.value.V2, V1: in.value.V1}
constr := &Constraint{Inputs: in.value.Inputs, Out: in.value.Out, Op: in.value.Op, invert: in.value.invert, negate: in.value.negate, V2: in.value.V2, V1: in.value.V1}
nRightins := make([]factor, len(in.rightIns))
nLeftInst := make([]factor, len(in.leftIns))
for k, v := range in.rightIns {
@ -368,11 +354,12 @@ func cloneGate(in *gate) (out *gate) {
return &gate{value: constr, leftIns: nLeftInst, rightIns: nRightins, index: in.index}
}
func (p *Program) getMainCircut() *Circuit {
func (p *Program) getMainCircuit() *Circuit {
return p.functions["main"]
}
func (p *Program) addGlobalInput(c Constraint) {
c.Out = "main@" + c.Out
p.globalInputs = append(p.globalInputs, c)
}
@ -392,47 +379,56 @@ func prepareUtils() utils {
PF: pf,
}
}
func NewProgramm() *Program {
//return &Program{functions: map[string]*Circuit{}, signals: []string{}, globalInputs: []*Constraint{{Op: PLUS, V1:"1",V2:"0", Out: "one"}}}
return &Program{functions: map[string]*Circuit{}, globalInputs: []Constraint{{Op: IN, Out: "one"}}, arithmeticEnvironment: prepareUtils()}
}
func (p *Program) addFunction(constraint *Constraint) (c *Circuit) {
name := constraint.Out
fmt.Println("try to add function ", name)
b, name2, _ := isFunction(name)
if !b {
panic(fmt.Sprintf("not a function: %v", constraint))
}
name = name2
func (p *Program) extendedFunctionRenamer(contextCircuit *Circuit, constraint *Constraint) (nextContext *Circuit) {
if _, ex := p.functions[name]; ex {
panic("function already declared")
if constraint.Op != FUNC {
panic("not a function")
}
c = newCircuit(name)
p.functions[name] = c
//I need the inputs to be defined as input constraints for each function for later renaming conventions
//if constraint.Literal == "main" {
for _, in := range constraint.Inputs {
newConstr := Constraint{
Op: IN,
Out: in,
}
if name == "main" {
p.addGlobalInput(newConstr)
//if _, ex := contextCircuit.gateMap[constraint.Out]; !ex {
// panic("constraint must be within the contextCircuit circuit")
//}
if b, n, _ := isFunction(constraint.Out); b {
if newContext, v := p.functions[n]; v {
//am i certain that constraint.inputs is alwazs equal to n??? me dont like it
for i, argument := range constraint.Inputs {
isConst, _ := isValue(argument)
if isConst {
continue
}
isFunc, _, _ := isFunction(argument)
if isFunc {
panic("functions as arguments no supported yet")
//p.extendedFunctionRenamer(contextCircuit,)
}
//at this point I assert that argument is a variable. This can become troublesome later
inputOriginCircuit := p.functions[getContextFromVariable(argument)]
if gate, ex := inputOriginCircuit.gateMap[argument]; ex {
oldGate := newContext.gateMap[newContext.Inputs[i]]
//we take the old gate which was nothing but a input
//and link this input to its constituents comming from the calling contextCircuit.
//i think this is pretty neat
oldGate.value = gate.value
oldGate.right = gate.right
oldGate.left = gate.left
} else {
panic("not expected")
}
}
newContext.renameInputs(constraint.Inputs)
return newContext
}
c.addConstraint(newConstr)
} else {
panic("not expected")
}
//}
c.Inputs = constraint.Inputs
return
return nil
}
func NewProgram() (p *Program) {
p = &Program{functions: map[string]*Circuit{}, globalInputs: []Constraint{{Op: IN, Out: "one"}}, arithmeticEnvironment: prepareUtils()}
return
}
// GenerateR1CS generates the R1CS polynomials from the Circuit
@ -496,11 +492,17 @@ func fractionToField(in [2]int) *big.Int {
}
func convertAndInsertFactorAt(arr []*big.Int, val factor, index int) {
value := new(big.Int).Add(new(big.Int), fractionToField(val.multiplicative))
if val.negate {
value.Neg(value)
}
if val.typ == CONST {
arr[0] = new(big.Int).Add(arr[0], fractionToField(val.multiplicative))
return
arr[0] = value
} else {
arr[index] = value
}
arr[index] = new(big.Int).Add(arr[index], fractionToField(val.multiplicative))
}

+ 27
- 27
circuitcompiler/Programm_test.go

@ -15,35 +15,35 @@ func TestProgramm_BuildConstraintTree(t *testing.T) {
func TestNewProgramm(t *testing.T) {
flat := `
func do(x):
e = x * 5
b = e * 6
c = b * 7
f = c * 1
d = c * f
out = d * mul(d,e)
func add(x ,k):
z = k * x
out = do(x) + mul(x,z)
func main(x,z):
out = do(z) + add(x,x)
func mul(a,b):
out = a * b
`
//flat := `
//func do(x):
// e = x * 5
// b = e * 6
// c = b * 7
// f = c * 1
// d = c * f
// out = d * mul(d,e)
//
//func add(x ,k):
// z = k * x
// out = do(x) + mul(x,z)
//
//func main(x,z):
// out = do(z) + add(x,x)
//
//func mul(a,b):
// out = a * b
//
//func main(a):
// b = a * a
// c = 4 - b
// d = 5 * c
// out = d / mul(b,b)
//`
flat := `
func mul(a,b):
out = a * b
func main(a):
b = a * a
c = 4 - b
d = 5 * c
out = mul(d,b) / mul(b,b)
`
//flat := `
//func main(a,b):
// c = a + b
@ -80,8 +80,8 @@ func TestNewProgramm(t *testing.T) {
fmt.Println(b)
fmt.Println(c)
a1 := big.NewInt(int64(6))
a2 := big.NewInt(int64(5))
inputs := []*big.Int{a1, a2}
//a2 := big.NewInt(int64(5))
inputs := []*big.Int{a1}
w := program.CalculateWitness(inputs)
fmt.Println("witness")
fmt.Println(w)

+ 83
- 39
circuitcompiler/circuit.go

@ -9,6 +9,8 @@ import (
"strings"
)
var variableIndicationSign = "@"
// Circuit is the data structure of the compiled circuit
type Circuit struct {
Inputs []string
@ -24,8 +26,8 @@ type gate struct {
left *gate
right *gate
funcInputs []*gate
value Constraint //is a pointer a good thing here??
leftIns []factor //leftIns and RightIns after addition gates have been reduced. only multiplication gates remain
value *Constraint //is a pointer a good thing here??
leftIns []factor //leftIns and RightIns after addition gates have been reduced. only multiplication gates remain
rightIns []factor
}
@ -48,6 +50,7 @@ type Constraint struct {
//fV2 *variable
//fOut *variable
//Literal string
//TODO once i've implemented a new parser/lexer we do this differently
Inputs []string // in func declaration case
//fInputs []*variable
negate bool
@ -65,15 +68,56 @@ func newCircuit(name string) *Circuit {
return &Circuit{Name: name, gateMap: make(map[string]*gate)}
}
func (circ *Circuit) addConstraint(constraint Constraint) {
func (p *Program) addFunction(constraint *Constraint) (c *Circuit) {
name := constraint.Out
fmt.Println("try to add function ", name)
b, name2, _ := isFunction(name)
if !b {
panic(fmt.Sprintf("not a function: %v", constraint))
}
name = name2
if _, ex := p.functions[name]; ex {
panic("function already declared")
}
c = newCircuit(name)
p.functions[name] = c
renamedInputs := make([]string, len(constraint.Inputs))
//I need the inputs to be defined as input constraints for each function for later renaming conventions
//if constraint.Literal == "main" {
for i, in := range constraint.Inputs {
newConstr := &Constraint{
Op: IN,
Out: in,
}
if name == "main" {
p.addGlobalInput(*newConstr)
}
c.addConstraint(newConstr)
renamedInputs[i] = newConstr.Out
}
//}
c.Inputs = renamedInputs
return
}
func (circ *Circuit) addConstraint(constraint *Constraint) {
if _, ex := circ.gateMap[constraint.Out]; ex {
panic("already used FlatConstraint")
}
gateToAdd := &gate{value: constraint}
if constraint.Op == DIVIDE {
constraint.Op = MULTIPLY
constraint.invert = true
} else if constraint.Op == MINUS {
}
if constraint.Op == MINUS {
constraint.Op = PLUS
constraint.negate = true
}
@ -81,47 +125,40 @@ func (circ *Circuit) addConstraint(constraint Constraint) {
//todo this is dangerous.. if someone would use out as variable name, things would be fucked
if constraint.Out == "out" {
constraint.Out = composeNewFunction(circ.Name, circ.Inputs)
if circ.Name == "main" {
//the main functions output must be a multiplication gate
//if its not, then we simple create one where outNew = 1 * outOld
if constraint.Op&(MINUS|PLUS) != 0 {
newOut := Constraint{Out: constraint.Out, V1: "1", V2: "out2", Op: MULTIPLY}
//TODO reachable?
delete(circ.gateMap, constraint.Out)
circ.addConstraint(newOut)
constraint.Out = "out2"
circ.addConstraint(constraint)
}
}
circ.root = gateToAdd
} else {
constraint.Out = circ.renamer(constraint.Out)
}
addConstantsAndFunctions := func(constraint string) {
if b, _ := isValue(constraint); b {
circ.gateMap[constraint] = &gate{value: Constraint{Op: CONST, Out: constraint}}
} else if b, _, inputs := isFunction(constraint); b {
//check if function input is a constant like foo(a,4)
for _, in := range inputs {
if b, _ := isValue(in); b {
circ.gateMap[in] = &gate{value: Constraint{Op: CONST, Out: in}}
continue
}
//if the argument is not in the constraint map, we panic. I used to do this later, but since we have a line
//interpreter, we can do this here
//the downside is that there cannot be functions passed as arguments
//if _, ex := circ.constraintMap[in];!ex {
// panic("undefined argument")
//
//}
}
circ.gateMap[constraint] = &gate{value: Constraint{Op: FUNC, Out: constraint, Inputs: inputs}}
constraint.V1 = circ.renamer(constraint.V1)
constraint.V2 = circ.renamer(constraint.V2)
circ.gateMap[constraint.Out] = gateToAdd
}
func (circ *Circuit) renamer(constraint string) string {
if constraint == "" {
return ""
}
if b, _ := isValue(constraint); b {
circ.gateMap[constraint] = &gate{value: &Constraint{Op: CONST, Out: constraint}}
return constraint
}
if b, name, inputs := isFunction(constraint); b {
renamedInputs := make([]string, len(inputs))
for i, in := range inputs {
renamedInputs[i] = circ.renamer(in)
}
nn := composeNewFunction(name, renamedInputs)
circ.gateMap[nn] = &gate{value: &Constraint{Op: FUNC, Out: nn, Inputs: renamedInputs}}
return nn
}
addConstantsAndFunctions(constraint.V1)
addConstantsAndFunctions(constraint.V2)
return circ.Name + variableIndicationSign + constraint
circ.gateMap[constraint.Out] = &gate{value: constraint}
}
func (circ *Circuit) renameInputs(inputs []string) {
@ -185,6 +222,13 @@ func (circ *Circuit) renameInputs(inputs []string) {
return
}
func getContextFromVariable(in string) string {
if strings.Contains(in, variableIndicationSign) {
return strings.Split(in, variableIndicationSign)[0]
}
return ""
}
func composeNewFunction(fname string, inputs []string) string {
builder := strings.Builder{}
builder.WriteString(fname)

+ 1
- 1
circuitcompiler/circuit_test.go

@ -39,7 +39,7 @@ func TestCircuitParser(t *testing.T) {
//`
//parser := NewParser(strings.NewReader(flat))
//programm, err := parser.Parse()
//circuit := programm.getMainCircut()
//circuit := programm.getMainCircuit()
//assert.Nil(t, err)
//fmt.Println("\n unreduced")
//fmt.Println(flat)

+ 2
- 2
circuitcompiler/parser.go

@ -142,7 +142,7 @@ func addToArrayIfNotExist(arr []string, elem string) []string {
// Parse parses the lines and returns the compiled Circuit
func (p *Parser) Parse() (programm *Program, err error) {
programm = NewProgramm()
programm = NewProgram()
var circuit *Circuit
@ -154,7 +154,7 @@ func (p *Parser) Parse() (programm *Program, err error) {
if constraint.Op == FUNC {
circuit = programm.addFunction(constraint)
} else {
circuit.addConstraint(*constraint)
circuit.addConstraint(constraint)
}
}
//TODO

+ 2
- 2
r1csqap/r1csqap.go

@ -24,9 +24,9 @@ func Transpose(matrix [][]*big.Int) [][]*big.Int {
// ArrayOfBigZeros creates a *big.Int array with n elements to zero
func ArrayOfBigZeros(num int) []*big.Int {
bigZero := big.NewInt(int64(0))
var r []*big.Int
var r = make([]*big.Int, num, num)
for i := 0; i < num; i++ {
r = append(r, bigZero)
r[i] = bigZero
}
return r
}

Loading…
Cancel
Save