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