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