arnaucube
arnaucube/go-snarkPublic Self-hosted repository
go-snark/r1csqap/r1csqap_test.go
r1csqap/r1csqap_test.goRaw
  1package r1csqap
  2
  3import (
  4	"bytes"
  5	"math/big"
  6	"testing"
  7
  8	"github.com/arnaucube/go-snark/fields"
  9	"github.com/stretchr/testify/assert"
 10)
 11
 12func TestTranspose(t *testing.T) {
 13	b0 := big.NewInt(int64(0))
 14	b1 := big.NewInt(int64(1))
 15	bFive := big.NewInt(int64(5))
 16	a := [][]*big.Int{
 17		[]*big.Int{b0, b1, b0, b0, b0, b0},
 18		[]*big.Int{b0, b0, b0, b1, b0, b0},
 19		[]*big.Int{b0, b1, b0, b0, b1, b0},
 20		[]*big.Int{bFive, b0, b0, b0, b0, b1},
 21	}
 22	aT := Transpose(a)
 23	assert.Equal(t, aT, [][]*big.Int{
 24		[]*big.Int{b0, b0, b0, bFive},
 25		[]*big.Int{b1, b0, b1, b0},
 26		[]*big.Int{b0, b0, b0, b0},
 27		[]*big.Int{b0, b1, b0, b0},
 28		[]*big.Int{b0, b0, b1, b0},
 29		[]*big.Int{b0, b0, b0, b1},
 30	})
 31}
 32
 33func neg(a *big.Int) *big.Int {
 34	return new(big.Int).Neg(a)
 35}
 36
 37func TestPol(t *testing.T) {
 38	b0 := big.NewInt(int64(0))
 39	b1 := big.NewInt(int64(1))
 40	b2 := big.NewInt(int64(2))
 41	b3 := big.NewInt(int64(3))
 42	b4 := big.NewInt(int64(4))
 43	b5 := big.NewInt(int64(5))
 44	b6 := big.NewInt(int64(6))
 45	b16 := big.NewInt(int64(16))
 46
 47	a := []*big.Int{b1, b0, b5}
 48	b := []*big.Int{b3, b0, b1}
 49
 50	// new Finite Field
 51	r, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
 52	assert.True(nil, ok)
 53	f := fields.NewFq(r)
 54
 55	// new Polynomial Field
 56	pf := NewPolynomialField(f)
 57
 58	// polynomial multiplication
 59	o := pf.Mul(a, b)
 60	assert.Equal(t, o, []*big.Int{b3, b0, b16, b0, b5})
 61
 62	// polynomial division
 63	quo, rem := pf.Div(a, b)
 64	assert.Equal(t, quo[0].Int64(), int64(5))
 65	assert.Equal(t, new(big.Int).Sub(rem[0], r).Int64(), int64(-14)) // check the rem result without modulo
 66
 67	c := []*big.Int{neg(b4), b0, neg(b2), b1}
 68	d := []*big.Int{neg(b3), b1}
 69	quo2, rem2 := pf.Div(c, d)
 70	assert.Equal(t, quo2, []*big.Int{b3, b1, b1})
 71	assert.Equal(t, rem2[0].Int64(), int64(5))
 72
 73	// polynomial addition
 74	o = pf.Add(a, b)
 75	assert.Equal(t, o, []*big.Int{b4, b0, b6})
 76
 77	// polynomial subtraction
 78	o1 := pf.Sub(a, b)
 79	o2 := pf.Sub(b, a)
 80	o = pf.Add(o1, o2)
 81	assert.True(t, bytes.Equal(b0.Bytes(), o[0].Bytes()))
 82	assert.True(t, bytes.Equal(b0.Bytes(), o[1].Bytes()))
 83	assert.True(t, bytes.Equal(b0.Bytes(), o[2].Bytes()))
 84
 85	c = []*big.Int{b5, b6, b1}
 86	d = []*big.Int{b1, b3}
 87	o = pf.Sub(c, d)
 88	assert.Equal(t, o, []*big.Int{b4, b3, b1})
 89
 90	// NewPolZeroAt
 91	o = pf.NewPolZeroAt(3, 4, b4)
 92	assert.Equal(t, pf.Eval(o, big.NewInt(3)), b4)
 93	o = pf.NewPolZeroAt(2, 4, b3)
 94	assert.Equal(t, pf.Eval(o, big.NewInt(2)), b3)
 95}
 96
 97func TestLagrangeInterpolation(t *testing.T) {
 98	// new Finite Field
 99	r, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
100	assert.True(nil, ok)
101	f := fields.NewFq(r)
102	// new Polynomial Field
103	pf := NewPolynomialField(f)
104
105	b0 := big.NewInt(int64(0))
106	b5 := big.NewInt(int64(5))
107	a := []*big.Int{b0, b0, b0, b5}
108	alpha := pf.LagrangeInterpolation(a)
109
110	assert.Equal(t, pf.Eval(alpha, big.NewInt(int64(4))), b5)
111	aux := pf.Eval(alpha, big.NewInt(int64(3))).Int64()
112	assert.Equal(t, aux, int64(0))
113
114}
115
116func TestR1CSToQAP(t *testing.T) {
117	// new Finite Field
118	r, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
119	assert.True(nil, ok)
120	f := fields.NewFq(r)
121	// new Polynomial Field
122	pf := NewPolynomialField(f)
123
124	b0 := big.NewInt(int64(0))
125	b1 := big.NewInt(int64(1))
126	b3 := big.NewInt(int64(3))
127	b5 := big.NewInt(int64(5))
128	b9 := big.NewInt(int64(9))
129	b27 := big.NewInt(int64(27))
130	b30 := big.NewInt(int64(30))
131	b35 := big.NewInt(int64(35))
132	a := [][]*big.Int{
133		[]*big.Int{b0, b1, b0, b0, b0, b0},
134		[]*big.Int{b0, b0, b0, b1, b0, b0},
135		[]*big.Int{b0, b1, b0, b0, b1, b0},
136		[]*big.Int{b5, b0, b0, b0, b0, b1},
137	}
138	b := [][]*big.Int{
139		[]*big.Int{b0, b1, b0, b0, b0, b0},
140		[]*big.Int{b0, b1, b0, b0, b0, b0},
141		[]*big.Int{b1, b0, b0, b0, b0, b0},
142		[]*big.Int{b1, b0, b0, b0, b0, b0},
143	}
144	c := [][]*big.Int{
145		[]*big.Int{b0, b0, b0, b1, b0, b0},
146		[]*big.Int{b0, b0, b0, b0, b1, b0},
147		[]*big.Int{b0, b0, b0, b0, b0, b1},
148		[]*big.Int{b0, b0, b1, b0, b0, b0},
149	}
150	alphas, betas, gammas, zx := pf.R1CSToQAP(a, b, c)
151	// fmt.Println(alphas)
152	// fmt.Println(betas)
153	// fmt.Println(gammas)
154	// fmt.Print("Z(x): ")
155	// fmt.Println(zx)
156
157	w := []*big.Int{b1, b3, b35, b9, b27, b30}
158	ax, bx, cx, px := pf.CombinePolynomials(w, alphas, betas, gammas)
159	// fmt.Println(ax)
160	// fmt.Println(bx)
161	// fmt.Println(cx)
162	// fmt.Println(px)
163
164	hx := pf.DivisorPolynomial(px, zx)
165	// fmt.Println(hx)
166
167	// hx==px/zx so px==hx*zx
168	assert.Equal(t, px, pf.Mul(hx, zx))
169
170	// p(x) = a(x) * b(x) - c(x) == h(x) * z(x)
171	abc := pf.Sub(pf.Mul(ax, bx), cx)
172	assert.Equal(t, abc, px)
173	hz := pf.Mul(hx, zx)
174	assert.Equal(t, abc, hz)
175
176}