arnaucube
arnaucube/go-snarkPublic Self-hosted repository
go-snark/snark_test.go
snark_test.goRaw
  1package snark
  2
  3import (
  4	"fmt"
  5	"math/big"
  6	"strings"
  7	"testing"
  8
  9	"github.com/arnaucube/go-snark/bn128"
 10	"github.com/arnaucube/go-snark/circuitcompiler"
 11	"github.com/arnaucube/go-snark/fields"
 12	"github.com/arnaucube/go-snark/r1csqap"
 13	"github.com/stretchr/testify/assert"
 14)
 15
 16func TestZkFromFlatCircuitCode(t *testing.T) {
 17	bn, err := bn128.NewBn128()
 18	assert.Nil(t, err)
 19
 20	// new Finite Field
 21	fqR := fields.NewFq(bn.R)
 22
 23	// new Polynomial Field
 24	pf := r1csqap.NewPolynomialField(fqR)
 25
 26	// compile circuit and get the R1CS
 27	flatCode := `
 28	func test(x):
 29		aux = x*x
 30		y = aux*x
 31		z = x + y
 32		out = z + 5
 33	`
 34	fmt.Print("\nflat code of the circuit:")
 35	fmt.Println(flatCode)
 36
 37	// parse the code
 38	parser := circuitcompiler.NewParser(strings.NewReader(flatCode))
 39	circuit, err := parser.Parse()
 40	assert.Nil(t, err)
 41	fmt.Println("\ncircuit data:", circuit)
 42
 43	b3 := big.NewInt(int64(3))
 44	inputs := []*big.Int{b3}
 45	// wittness
 46	w := circuit.CalculateWitness(inputs)
 47	fmt.Println("\nwitness", w)
 48
 49	// flat code to R1CS
 50	fmt.Println("\ngenerating R1CS from flat code")
 51	a, b, c := circuit.GenerateR1CS()
 52	fmt.Println("\nR1CS:")
 53	fmt.Println("a:", a)
 54	fmt.Println("b:", b)
 55	fmt.Println("c:", c)
 56
 57	alphas, betas, gammas, zx := pf.R1CSToQAP(a, b, c)
 58
 59	ax, bx, cx, px := pf.CombinePolynomials(w, alphas, betas, gammas)
 60
 61	hx := pf.DivisorPolinomial(px, zx)
 62
 63	// hx==px/zx so px==hx*zx
 64	assert.Equal(t, px, pf.Mul(hx, zx))
 65
 66	// p(x) = a(x) * b(x) - c(x) == h(x) * z(x)
 67	abc := pf.Sub(pf.Mul(ax, bx), cx)
 68	assert.Equal(t, abc, px)
 69	hz := pf.Mul(hx, zx)
 70	assert.Equal(t, abc, hz)
 71
 72	div, rem := pf.Div(px, zx)
 73	assert.Equal(t, hx, div)
 74	assert.Equal(t, rem, r1csqap.ArrayOfBigZeros(4))
 75
 76	// calculate trusted setup
 77	setup, err := GenerateTrustedSetup(bn, fqR, pf, len(w), *circuit, alphas, betas, gammas, zx)
 78	assert.Nil(t, err)
 79	fmt.Println("\nt:", setup.Toxic.T)
 80
 81	// piA = g1 * A(t), piB = g2 * B(t), piC = g1 * C(t), piH = g1 * H(t)
 82	proof, err := GenerateProofs(bn, fqR, *circuit, setup, hx, w)
 83	assert.Nil(t, err)
 84
 85	assert.True(t, VerifyProof(bn, *circuit, setup, proof))
 86}
 87
 88func TestZkFromHardcodedR1CS(t *testing.T) {
 89	bn, err := bn128.NewBn128()
 90	assert.Nil(t, err)
 91
 92	// new Finite Field
 93	fqR := fields.NewFq(bn.R)
 94
 95	// new Polynomial Field
 96	pf := r1csqap.NewPolynomialField(fqR)
 97
 98	b0 := big.NewInt(int64(0))
 99	b1 := big.NewInt(int64(1))
100	b3 := big.NewInt(int64(3))
101	b5 := big.NewInt(int64(5))
102	b9 := big.NewInt(int64(9))
103	b27 := big.NewInt(int64(27))
104	b30 := big.NewInt(int64(30))
105	b35 := big.NewInt(int64(35))
106	a := [][]*big.Int{
107		[]*big.Int{b0, b1, b0, b0, b0, b0},
108		[]*big.Int{b0, b0, b0, b1, b0, b0},
109		[]*big.Int{b0, b1, b0, b0, b1, b0},
110		[]*big.Int{b5, b0, b0, b0, b0, b1},
111	}
112	b := [][]*big.Int{
113		[]*big.Int{b0, b1, b0, b0, b0, b0},
114		[]*big.Int{b0, b1, b0, b0, b0, b0},
115		[]*big.Int{b1, b0, b0, b0, b0, b0},
116		[]*big.Int{b1, b0, b0, b0, b0, b0},
117	}
118	c := [][]*big.Int{
119		[]*big.Int{b0, b0, b0, b1, b0, b0},
120		[]*big.Int{b0, b0, b0, b0, b1, b0},
121		[]*big.Int{b0, b0, b0, b0, b0, b1},
122		[]*big.Int{b0, b0, b1, b0, b0, b0},
123	}
124	alphas, betas, gammas, zx := pf.R1CSToQAP(a, b, c)
125
126	// wittness = 1, 3, 35, 9, 27, 30
127	w := []*big.Int{b1, b3, b35, b9, b27, b30}
128	circuit := circuitcompiler.Circuit{
129		NVars:    6,
130		NPublic:  0,
131		NSignals: len(w),
132	}
133	ax, bx, cx, px := pf.CombinePolynomials(w, alphas, betas, gammas)
134
135	hx := pf.DivisorPolinomial(px, zx)
136
137	// hx==px/zx so px==hx*zx
138	assert.Equal(t, px, pf.Mul(hx, zx))
139
140	// p(x) = a(x) * b(x) - c(x) == h(x) * z(x)
141	abc := pf.Sub(pf.Mul(ax, bx), cx)
142	assert.Equal(t, abc, px)
143	hz := pf.Mul(hx, zx)
144	assert.Equal(t, abc, hz)
145
146	div, rem := pf.Div(px, zx)
147	assert.Equal(t, hx, div)
148	assert.Equal(t, rem, r1csqap.ArrayOfBigZeros(4))
149
150	// calculate trusted setup
151	setup, err := GenerateTrustedSetup(bn, fqR, pf, len(w), circuit, alphas, betas, gammas, zx)
152	assert.Nil(t, err)
153	fmt.Println("t", setup.Toxic.T)
154
155	// piA = g1 * A(t), piB = g2 * B(t), piC = g1 * C(t), piH = g1 * H(t)
156	proof, err := GenerateProofs(bn, fqR, circuit, setup, hx, w)
157	assert.Nil(t, err)
158
159	assert.True(t, VerifyProof(bn, circuit, setup, proof))
160}