arnaucube
arnaucube/go-snarkPublic Self-hosted repository
go-snark/circuitcompiler/circuit_test.go
circuitcompiler/circuit_test.goRaw
  1package circuitcompiler
  2
  3import (
  4	"bufio"
  5	"math/big"
  6	"os"
  7	"strings"
  8	"testing"
  9
 10	"github.com/stretchr/testify/assert"
 11)
 12
 13func TestCircuitParser(t *testing.T) {
 14	// y = x^3 + x + 5
 15	flat := `
 16	func main(private s0, public s1):
 17		s2 = s0 * s0
 18		s3 = s2 * s0
 19		s4 = s3 + s0
 20		s5 = s4 + 5
 21		equals(s1, s5)
 22		out = 1 * 1
 23	`
 24	parser := NewParser(strings.NewReader(flat))
 25	circuit, err := parser.Parse()
 26	assert.Nil(t, err)
 27
 28	// flat code to R1CS
 29	a, b, c := circuit.GenerateR1CS()
 30	assert.Equal(t, "s0", circuit.PrivateInputs[0])
 31	assert.Equal(t, "s1", circuit.PublicInputs[0])
 32
 33	assert.Equal(t, []string{"one", "s1", "s0", "s2", "s3", "s4", "s5", "out"}, circuit.Signals)
 34
 35	// expected result
 36	b0 := big.NewInt(int64(0))
 37	b1 := big.NewInt(int64(1))
 38	b5 := big.NewInt(int64(5))
 39	aExpected := [][]*big.Int{
 40		[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
 41		[]*big.Int{b0, b0, b0, b1, b0, b0, b0, b0},
 42		[]*big.Int{b0, b0, b1, b0, b1, b0, b0, b0},
 43		[]*big.Int{b5, b0, b0, b0, b0, b1, b0, b0},
 44		[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
 45		[]*big.Int{b0, b1, b0, b0, b0, b0, b0, b0},
 46		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
 47	}
 48	bExpected := [][]*big.Int{
 49		[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
 50		[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
 51		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
 52		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
 53		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
 54		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
 55		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
 56	}
 57	cExpected := [][]*big.Int{
 58		[]*big.Int{b0, b0, b0, b1, b0, b0, b0, b0},
 59		[]*big.Int{b0, b0, b0, b0, b1, b0, b0, b0},
 60		[]*big.Int{b0, b0, b0, b0, b0, b1, b0, b0},
 61		[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
 62		[]*big.Int{b0, b1, b0, b0, b0, b0, b0, b0},
 63		[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
 64		[]*big.Int{b0, b0, b0, b0, b0, b0, b0, b1},
 65	}
 66
 67	assert.Equal(t, aExpected, a)
 68	assert.Equal(t, bExpected, b)
 69	assert.Equal(t, cExpected, c)
 70
 71	b3 := big.NewInt(int64(3))
 72	privateInputs := []*big.Int{b3}
 73	b35 := big.NewInt(int64(35))
 74	publicInputs := []*big.Int{b35}
 75	// Calculate Witness
 76	w, err := circuit.CalculateWitness(privateInputs, publicInputs)
 77	assert.Nil(t, err)
 78	b9 := big.NewInt(int64(9))
 79	b27 := big.NewInt(int64(27))
 80	b30 := big.NewInt(int64(30))
 81	wExpected := []*big.Int{b1, b35, b3, b9, b27, b30, b35, b1}
 82	assert.Equal(t, wExpected, w)
 83
 84	// circuitJson, _ := json.Marshal(circuit)
 85	// fmt.Println("circuit:", string(circuitJson))
 86
 87	assert.Equal(t, circuit.NPublic, 1)
 88	assert.Equal(t, len(circuit.PublicInputs), 1)
 89	assert.Equal(t, len(circuit.PrivateInputs), 1)
 90}
 91
 92func TestCircuitWithFuncCallsParser(t *testing.T) {
 93	// y = x^3 + x + 5
 94	code := `
 95		func exp3(private a):
 96			b = a * a
 97			c = a * b
 98			return c
 99		func sum(private a, private b):
100			c = a + b
101			return c
102
103		func main(private s0, public s1):
104			s3 = exp3(s0)
105			s4 = sum(s3, s0)
106			s5 = s4 + 5
107			equals(s1, s5)
108			out = 1 * 1
109	`
110	parser := NewParser(strings.NewReader(code))
111	circuit, err := parser.Parse()
112	assert.Nil(t, err)
113
114	// flat code to R1CS
115	a, b, c := circuit.GenerateR1CS()
116	assert.Equal(t, "s0", circuit.PrivateInputs[0])
117	assert.Equal(t, "s1", circuit.PublicInputs[0])
118
119	assert.Equal(t, []string{"one", "s1", "s0", "b0", "s3", "s4", "s5", "out"}, circuit.Signals)
120
121	// expected result
122	b0 := big.NewInt(int64(0))
123	b1 := big.NewInt(int64(1))
124	b5 := big.NewInt(int64(5))
125	aExpected := [][]*big.Int{
126		[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
127		[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
128		[]*big.Int{b0, b0, b1, b0, b1, b0, b0, b0},
129		[]*big.Int{b5, b0, b0, b0, b0, b1, b0, b0},
130		[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
131		[]*big.Int{b0, b1, b0, b0, b0, b0, b0, b0},
132		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
133	}
134	bExpected := [][]*big.Int{
135		[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
136		[]*big.Int{b0, b0, b0, b1, b0, b0, b0, b0},
137		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
138		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
139		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
140		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
141		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
142	}
143	cExpected := [][]*big.Int{
144		[]*big.Int{b0, b0, b0, b1, b0, b0, b0, b0},
145		[]*big.Int{b0, b0, b0, b0, b1, b0, b0, b0},
146		[]*big.Int{b0, b0, b0, b0, b0, b1, b0, b0},
147		[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
148		[]*big.Int{b0, b1, b0, b0, b0, b0, b0, b0},
149		[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
150		[]*big.Int{b0, b0, b0, b0, b0, b0, b0, b1},
151	}
152
153	assert.Equal(t, aExpected, a)
154	assert.Equal(t, bExpected, b)
155	assert.Equal(t, cExpected, c)
156
157	b3 := big.NewInt(int64(3))
158	privateInputs := []*big.Int{b3}
159	b35 := big.NewInt(int64(35))
160	publicInputs := []*big.Int{b35}
161	// Calculate Witness
162	w, err := circuit.CalculateWitness(privateInputs, publicInputs)
163	assert.Nil(t, err)
164	b9 := big.NewInt(int64(9))
165	b27 := big.NewInt(int64(27))
166	b30 := big.NewInt(int64(30))
167	wExpected := []*big.Int{b1, b35, b3, b9, b27, b30, b35, b1}
168	assert.Equal(t, wExpected, w)
169
170	// circuitJson, _ := json.Marshal(circuit)
171	// fmt.Println("circuit:", string(circuitJson))
172
173	assert.Equal(t, circuit.NPublic, 1)
174	assert.Equal(t, len(circuit.PublicInputs), 1)
175	assert.Equal(t, len(circuit.PrivateInputs), 1)
176}
177
178func TestCircuitFromFileWithImports(t *testing.T) {
179	circuitFile, err := os.Open("./circuit-test-1.circuit")
180	assert.Nil(t, err)
181
182	parser := NewParser(bufio.NewReader(circuitFile))
183	circuit, err := parser.Parse()
184	assert.Nil(t, err)
185
186	// flat code to R1CS
187	a, b, c := circuit.GenerateR1CS()
188	assert.Equal(t, "s0", circuit.PrivateInputs[0])
189	assert.Equal(t, "s1", circuit.PublicInputs[0])
190
191	assert.Equal(t, []string{"one", "s1", "s0", "b0", "s3", "s4", "s5", "out"}, circuit.Signals)
192
193	// expected result
194	b0 := big.NewInt(int64(0))
195	b1 := big.NewInt(int64(1))
196	b5 := big.NewInt(int64(5))
197	aExpected := [][]*big.Int{
198		[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
199		[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
200		[]*big.Int{b0, b0, b1, b0, b1, b0, b0, b0},
201		[]*big.Int{b5, b0, b0, b0, b0, b1, b0, b0},
202		[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
203		[]*big.Int{b0, b1, b0, b0, b0, b0, b0, b0},
204		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
205	}
206	bExpected := [][]*big.Int{
207		[]*big.Int{b0, b0, b1, b0, b0, b0, b0, b0},
208		[]*big.Int{b0, b0, b0, b1, b0, b0, b0, b0},
209		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
210		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
211		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
212		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
213		[]*big.Int{b1, b0, b0, b0, b0, b0, b0, b0},
214	}
215	cExpected := [][]*big.Int{
216		[]*big.Int{b0, b0, b0, b1, b0, b0, b0, b0},
217		[]*big.Int{b0, b0, b0, b0, b1, b0, b0, b0},
218		[]*big.Int{b0, b0, b0, b0, b0, b1, b0, b0},
219		[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
220		[]*big.Int{b0, b1, b0, b0, b0, b0, b0, b0},
221		[]*big.Int{b0, b0, b0, b0, b0, b0, b1, b0},
222		[]*big.Int{b0, b0, b0, b0, b0, b0, b0, b1},
223	}
224
225	assert.Equal(t, aExpected, a)
226	assert.Equal(t, bExpected, b)
227	assert.Equal(t, cExpected, c)
228
229	b3 := big.NewInt(int64(3))
230	privateInputs := []*big.Int{b3}
231	b35 := big.NewInt(int64(35))
232	publicInputs := []*big.Int{b35}
233	// Calculate Witness
234	w, err := circuit.CalculateWitness(privateInputs, publicInputs)
235	assert.Nil(t, err)
236	b9 := big.NewInt(int64(9))
237	b27 := big.NewInt(int64(27))
238	b30 := big.NewInt(int64(30))
239	wExpected := []*big.Int{b1, b35, b3, b9, b27, b30, b35, b1}
240	assert.Equal(t, wExpected, w)
241
242	// circuitJson, _ := json.Marshal(circuit)
243	// fmt.Println("circuit:", string(circuitJson))
244
245	assert.Equal(t, circuit.NPublic, 1)
246	assert.Equal(t, len(circuit.PublicInputs), 1)
247	assert.Equal(t, len(circuit.PrivateInputs), 1)
248}