arnaucube
arnaucube/go-iden3-cryptoPublic Self-hosted repository
go-iden3-crypto/babyjub/babyjub_test.go
babyjub/babyjub_test.goRaw
  1package babyjub
  2
  3import (
  4	"encoding/hex"
  5	"math/big"
  6	"math/rand"
  7	"testing"
  8
  9	"github.com/iden3/go-iden3-crypto/constants"
 10	"github.com/iden3/go-iden3-crypto/utils"
 11	"github.com/stretchr/testify/assert"
 12)
 13
 14func TestAdd1(t *testing.T) {
 15	a := &Point{X: big.NewInt(0), Y: big.NewInt(1)}
 16	b := &Point{X: big.NewInt(0), Y: big.NewInt(1)}
 17
 18	c := NewPoint().Projective().Add(a.Projective(), b.Projective())
 19	// fmt.Printf("%v = 2 * %v", *c, *a)
 20	assert.Equal(t, "0", c.X.String())
 21	assert.Equal(t, "1", c.Y.String())
 22}
 23
 24func TestAdd2(t *testing.T) {
 25	aX := utils.NewIntFromString(
 26		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
 27	aY := utils.NewIntFromString(
 28		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
 29	a := &Point{X: aX, Y: aY}
 30
 31	bX := utils.NewIntFromString(
 32		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
 33	bY := utils.NewIntFromString(
 34		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
 35	b := &Point{X: bX, Y: bY}
 36
 37	c := NewPoint().Projective().Add(a.Projective(), b.Projective()).Affine()
 38	// fmt.Printf("%v = 2 * %v", *c, *a)
 39	assert.Equal(t,
 40		"6890855772600357754907169075114257697580319025794532037257385534741338397365",
 41		c.X.String())
 42	assert.Equal(t,
 43		"4338620300185947561074059802482547481416142213883829469920100239455078257889",
 44		c.Y.String())
 45
 46	d := NewPointProjective().Add(c.Projective(), c.Projective()).Affine()
 47	assert.Equal(t,
 48		"2f6458832049e917c95867185a96621336df33e13c98e81d1ef4928cdbb77772",
 49		hex.EncodeToString(d.X.Bytes()))
 50
 51	// Projective
 52	aP := a.Projective()
 53	bP := b.Projective()
 54	cP := NewPointProjective().Add(aP, bP)
 55	c2 := cP.Affine()
 56	assert.Equal(t, c, c2)
 57}
 58
 59func TestAdd3(t *testing.T) {
 60	aX := utils.NewIntFromString(
 61		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
 62	aY := utils.NewIntFromString(
 63		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
 64	a := &Point{X: aX, Y: aY}
 65
 66	bX := utils.NewIntFromString(
 67		"16540640123574156134436876038791482806971768689494387082833631921987005038935")
 68	bY := utils.NewIntFromString(
 69		"20819045374670962167435360035096875258406992893633759881276124905556507972311")
 70	b := &Point{X: bX, Y: bY}
 71
 72	c := NewPoint().Projective().Add(a.Projective(), b.Projective()).Affine()
 73	// fmt.Printf("%v = 2 * %v", *c, *a)
 74	assert.Equal(t,
 75		"7916061937171219682591368294088513039687205273691143098332585753343424131937",
 76		c.X.String())
 77	assert.Equal(t,
 78		"14035240266687799601661095864649209771790948434046947201833777492504781204499",
 79		c.Y.String())
 80}
 81
 82func TestAdd4(t *testing.T) {
 83	aX := utils.NewIntFromString(
 84		"0")
 85	aY := utils.NewIntFromString(
 86		"1")
 87	a := &Point{X: aX, Y: aY}
 88
 89	bX := utils.NewIntFromString(
 90		"16540640123574156134436876038791482806971768689494387082833631921987005038935")
 91	bY := utils.NewIntFromString(
 92		"20819045374670962167435360035096875258406992893633759881276124905556507972311")
 93	b := &Point{X: bX, Y: bY}
 94
 95	c := NewPoint().Projective().Add(a.Projective(), b.Projective()).Affine()
 96	// fmt.Printf("%v = 2 * %v", *c, *a)
 97	assert.Equal(t,
 98		"16540640123574156134436876038791482806971768689494387082833631921987005038935",
 99		c.X.String())
100	assert.Equal(t,
101		"20819045374670962167435360035096875258406992893633759881276124905556507972311",
102		c.Y.String())
103}
104
105func TestInCurve1(t *testing.T) {
106	p := &Point{X: big.NewInt(0), Y: big.NewInt(1)}
107	assert.Equal(t, true, p.InCurve())
108}
109
110func TestInCurve2(t *testing.T) {
111	p := &Point{X: big.NewInt(1), Y: big.NewInt(0)}
112	assert.Equal(t, false, p.InCurve())
113}
114
115func TestMul0(t *testing.T) {
116	x := utils.NewIntFromString(
117		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
118	y := utils.NewIntFromString(
119		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
120	p := &Point{X: x, Y: y}
121	s := utils.NewIntFromString("3")
122
123	r2 := NewPoint().Projective().Add(p.Projective(), p.Projective()).Affine()
124	r2 = NewPoint().Projective().Add(r2.Projective(), p.Projective()).Affine()
125	r := NewPoint().Mul(s, p)
126	assert.Equal(t, r2.X.String(), r.X.String())
127	assert.Equal(t, r2.Y.String(), r.Y.String())
128
129	assert.Equal(t,
130		"19372461775513343691590086534037741906533799473648040012278229434133483800898",
131		r.X.String())
132	assert.Equal(t,
133		"9458658722007214007257525444427903161243386465067105737478306991484593958249",
134		r.Y.String())
135}
136
137func TestMul1(t *testing.T) {
138	x := utils.NewIntFromString(
139		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
140	y := utils.NewIntFromString(
141		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
142	p := &Point{X: x, Y: y}
143	s := utils.NewIntFromString(
144		"14035240266687799601661095864649209771790948434046947201833777492504781204499")
145	r := NewPoint().Mul(s, p)
146	assert.Equal(t,
147		"17070357974431721403481313912716834497662307308519659060910483826664480189605",
148		r.X.String())
149	assert.Equal(t,
150		"4014745322800118607127020275658861516666525056516280575712425373174125159339",
151		r.Y.String())
152}
153
154func TestMul2(t *testing.T) {
155	x := utils.NewIntFromString(
156		"6890855772600357754907169075114257697580319025794532037257385534741338397365")
157	y := utils.NewIntFromString(
158		"4338620300185947561074059802482547481416142213883829469920100239455078257889")
159	p := &Point{X: x, Y: y}
160	s := utils.NewIntFromString(
161		"20819045374670962167435360035096875258406992893633759881276124905556507972311")
162	r := NewPoint().Mul(s, p)
163	assert.Equal(t,
164		"13563888653650925984868671744672725781658357821216877865297235725727006259983",
165		r.X.String())
166	assert.Equal(t,
167		"8442587202676550862664528699803615547505326611544120184665036919364004251662",
168		r.Y.String())
169}
170
171func TestInCurve3(t *testing.T) {
172	x := utils.NewIntFromString(
173		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
174	y := utils.NewIntFromString(
175		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
176	p := &Point{X: x, Y: y}
177	assert.Equal(t, true, p.InCurve())
178}
179
180func TestInCurve4(t *testing.T) {
181	x := utils.NewIntFromString(
182		"6890855772600357754907169075114257697580319025794532037257385534741338397365")
183	y := utils.NewIntFromString(
184		"4338620300185947561074059802482547481416142213883829469920100239455078257889")
185	p := &Point{X: x, Y: y}
186	assert.Equal(t, true, p.InCurve())
187}
188
189func TestInSubGroup1(t *testing.T) {
190	x := utils.NewIntFromString(
191		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
192	y := utils.NewIntFromString(
193		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
194	p := &Point{X: x, Y: y}
195	assert.Equal(t, true, p.InSubGroup())
196}
197
198func TestInSubGroup2(t *testing.T) {
199	x := utils.NewIntFromString(
200		"6890855772600357754907169075114257697580319025794532037257385534741338397365")
201	y := utils.NewIntFromString(
202		"4338620300185947561074059802482547481416142213883829469920100239455078257889")
203	p := &Point{X: x, Y: y}
204	assert.Equal(t, true, p.InSubGroup())
205}
206
207func TestPointFromSignAndy(t *testing.T) {
208	x := utils.NewIntFromString(
209		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
210	y := utils.NewIntFromString(
211		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
212	p := &Point{X: x, Y: y}
213
214	sign := PointCoordSign(p.X)
215	p2, err := PointFromSignAndY(sign, p.Y)
216	assert.Equal(t, nil, err)
217	assert.Equal(t, p.X.String(), p2.X.String())
218	assert.Equal(t, p.Y.String(), p2.Y.String())
219}
220
221func TestPackAndUnpackSignY(t *testing.T) {
222	x := utils.NewIntFromString(
223		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
224	y := utils.NewIntFromString(
225		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
226	p := &Point{X: x, Y: y}
227	pComp := p.Compress()
228
229	s, y := UnpackSignY(pComp)
230
231	pComp2 := PackSignY(s, y)
232	assert.Equal(t, pComp, pComp2)
233
234	emptyPointComp := [32]byte{}
235	s, y = UnpackSignY(emptyPointComp)
236
237	pComp2 = PackSignY(s, y)
238	assert.Equal(t, emptyPointComp, pComp2)
239}
240
241func TestCompressDecompress1(t *testing.T) {
242	x := utils.NewIntFromString(
243		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
244	y := utils.NewIntFromString(
245		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
246	p := &Point{X: x, Y: y}
247
248	buf := p.Compress()
249	assert.Equal(t,
250		"53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85",
251		hex.EncodeToString(buf[:]))
252
253	p2, err := NewPoint().Decompress(buf)
254	assert.Equal(t, nil, err)
255	assert.Equal(t, p.X.String(), p2.X.String())
256	assert.Equal(t, p.Y.String(), p2.Y.String())
257}
258
259func TestCompressDecompress2(t *testing.T) {
260	x := utils.NewIntFromString(
261		"6890855772600357754907169075114257697580319025794532037257385534741338397365")
262	y := utils.NewIntFromString(
263		"4338620300185947561074059802482547481416142213883829469920100239455078257889")
264	p := &Point{X: x, Y: y}
265
266	buf := p.Compress()
267	assert.Equal(t,
268		"e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709",
269		hex.EncodeToString(buf[:]))
270
271	p2, err := NewPoint().Decompress(buf)
272	assert.Equal(t, nil, err)
273	assert.Equal(t, p.X.String(), p2.X.String())
274	assert.Equal(t, p.Y.String(), p2.Y.String())
275}
276
277func TestCompressDecompressRnd(t *testing.T) {
278	for i := 0; i < 64; i++ {
279		p1 := NewPoint().Mul(big.NewInt(int64(i)), B8)
280		buf := p1.Compress()
281		p2, err := NewPoint().Decompress(buf)
282		assert.Equal(t, nil, err)
283		assert.Equal(t, p1.X.Bytes(), p2.X.Bytes())
284		assert.Equal(t, p1.Y.Bytes(), p2.Y.Bytes())
285	}
286}
287
288func BenchmarkBabyjub(b *testing.B) {
289	const n = 256
290
291	rnd := rand.New(rand.NewSource(42)) //nolint:gosec
292
293	var badpoints [n]*Point
294	for i := 0; i < n; i++ {
295		x := new(big.Int).Rand(rnd, constants.Q)
296		y := new(big.Int).Rand(rnd, constants.Q)
297		badpoints[i] = &Point{X: x, Y: y}
298	}
299
300	var points [n]*Point
301	var pointsProj [n]*PointProjective
302	baseX := utils.NewIntFromString(
303		"17777552123799933955779906779655732241715742912184938656739573121738514868268")
304	baseY := utils.NewIntFromString(
305		"2626589144620713026669568689430873010625803728049924121243784502389097019475")
306	base := &Point{X: baseX, Y: baseY}
307	for i := 0; i < n; i++ {
308		s := new(big.Int).Rand(rnd, constants.Q)
309		points[i] = NewPoint().Mul(s, base)
310		pointsProj[i] = NewPoint().Mul(s, base).Projective()
311	}
312
313	var scalars [n]*big.Int
314	for i := 0; i < n; i++ {
315		scalars[i] = new(big.Int).Rand(rnd, constants.Q)
316	}
317
318	b.Run("AddConst", func(b *testing.B) {
319		p0 := &Point{X: big.NewInt(0), Y: big.NewInt(1)}
320		p1 := &Point{X: big.NewInt(0), Y: big.NewInt(1)}
321		p0Proj := p0.Projective()
322		p1Proj := p1.Projective()
323
324		p2 := NewPoint().Projective()
325		for i := 0; i < b.N; i++ {
326			p2.Add(p0Proj, p1Proj)
327		}
328	})
329
330	b.Run("AddRnd", func(b *testing.B) {
331		res := NewPoint().Projective()
332		for i := 0; i < b.N; i++ {
333			res.Add(pointsProj[i%(n/2)], pointsProj[i%(n/2)+1])
334		}
335	})
336
337	b.Run("MulRnd", func(b *testing.B) {
338		res := NewPoint()
339		for i := 0; i < b.N; i++ {
340			res.Mul(scalars[i%n], points[i%n])
341		}
342	})
343
344	b.Run("Compress", func(b *testing.B) {
345		for i := 0; i < b.N; i++ {
346			points[i%n].Compress()
347		}
348	})
349
350	b.Run("InCurve", func(b *testing.B) {
351		for i := 0; i < b.N; i++ {
352			badpoints[i%n].InCurve()
353		}
354	})
355
356	b.Run("InSubGroup", func(b *testing.B) {
357		for i := 0; i < b.N; i++ {
358			points[i%n].InCurve()
359		}
360	})
361}