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 TestCompressDecompress1(t *testing.T) {
222 x := utils.NewIntFromString(
223 "17777552123799933955779906779655732241715742912184938656739573121738514868268")
224 y := utils.NewIntFromString(
225 "2626589144620713026669568689430873010625803728049924121243784502389097019475")
226 p := &Point{X: x, Y: y}
227
228 buf := p.Compress()
229 assert.Equal(t,
230 "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85",
231 hex.EncodeToString(buf[:]))
232
233 p2, err := NewPoint().Decompress(buf)
234 assert.Equal(t, nil, err)
235 assert.Equal(t, p.X.String(), p2.X.String())
236 assert.Equal(t, p.Y.String(), p2.Y.String())
237}
238
239func TestCompressDecompress2(t *testing.T) {
240 x := utils.NewIntFromString(
241 "6890855772600357754907169075114257697580319025794532037257385534741338397365")
242 y := utils.NewIntFromString(
243 "4338620300185947561074059802482547481416142213883829469920100239455078257889")
244 p := &Point{X: x, Y: y}
245
246 buf := p.Compress()
247 assert.Equal(t,
248 "e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709",
249 hex.EncodeToString(buf[:]))
250
251 p2, err := NewPoint().Decompress(buf)
252 assert.Equal(t, nil, err)
253 assert.Equal(t, p.X.String(), p2.X.String())
254 assert.Equal(t, p.Y.String(), p2.Y.String())
255}
256
257func TestCompressDecompressRnd(t *testing.T) {
258 for i := 0; i < 64; i++ {
259 p1 := NewPoint().Mul(big.NewInt(int64(i)), B8)
260 buf := p1.Compress()
261 p2, err := NewPoint().Decompress(buf)
262 assert.Equal(t, nil, err)
263 assert.Equal(t, p1.X.Bytes(), p2.X.Bytes())
264 assert.Equal(t, p1.Y.Bytes(), p2.Y.Bytes())
265 }
266}
267
268func BenchmarkBabyjub(b *testing.B) {
269 const n = 256
270
271 rnd := rand.New(rand.NewSource(42)) //nolint:gosec
272
273 var badpoints [n]*Point
274 for i := 0; i < n; i++ {
275 x := new(big.Int).Rand(rnd, constants.Q)
276 y := new(big.Int).Rand(rnd, constants.Q)
277 badpoints[i] = &Point{X: x, Y: y}
278 }
279
280 var points [n]*Point
281 var pointsProj [n]*PointProjective
282 baseX := utils.NewIntFromString(
283 "17777552123799933955779906779655732241715742912184938656739573121738514868268")
284 baseY := utils.NewIntFromString(
285 "2626589144620713026669568689430873010625803728049924121243784502389097019475")
286 base := &Point{X: baseX, Y: baseY}
287 for i := 0; i < n; i++ {
288 s := new(big.Int).Rand(rnd, constants.Q)
289 points[i] = NewPoint().Mul(s, base)
290 pointsProj[i] = NewPoint().Mul(s, base).Projective()
291 }
292
293 var scalars [n]*big.Int
294 for i := 0; i < n; i++ {
295 scalars[i] = new(big.Int).Rand(rnd, constants.Q)
296 }
297
298 b.Run("AddConst", func(b *testing.B) {
299 p0 := &Point{X: big.NewInt(0), Y: big.NewInt(1)}
300 p1 := &Point{X: big.NewInt(0), Y: big.NewInt(1)}
301 p0Proj := p0.Projective()
302 p1Proj := p1.Projective()
303
304 p2 := NewPoint().Projective()
305 for i := 0; i < b.N; i++ {
306 p2.Add(p0Proj, p1Proj)
307 }
308 })
309
310 b.Run("AddRnd", func(b *testing.B) {
311 res := NewPoint().Projective()
312 for i := 0; i < b.N; i++ {
313 res.Add(pointsProj[i%(n/2)], pointsProj[i%(n/2)+1])
314 }
315 })
316
317 b.Run("MulRnd", func(b *testing.B) {
318 res := NewPoint()
319 for i := 0; i < b.N; i++ {
320 res.Mul(scalars[i%n], points[i%n])
321 }
322 })
323
324 b.Run("Compress", func(b *testing.B) {
325 for i := 0; i < b.N; i++ {
326 points[i%n].Compress()
327 }
328 })
329
330 b.Run("InCurve", func(b *testing.B) {
331 for i := 0; i < b.N; i++ {
332 badpoints[i%n].InCurve()
333 }
334 })
335
336 b.Run("InSubGroup", func(b *testing.B) {
337 for i := 0; i < b.N; i++ {
338 points[i%n].InCurve()
339 }
340 })
341}