1// Copyright 2020 ConsenSys Software Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Code generated by consensys/gnark-crypto DO NOT EDIT
16
17package fptower
18
19import (
20	"crypto/rand"
21	"testing"
22
23	"github.com/consensys/gnark-crypto/ecc/bls12-377/fp"
24	"github.com/leanovate/gopter"
25	"github.com/leanovate/gopter/prop"
26)
27
28// ------------------------------------------------------------
29// tests
30
31func TestE2ReceiverIsOperand(t *testing.T) {
32
33	parameters := gopter.DefaultTestParameters()
34	parameters.MinSuccessfulTests = 100
35
36	properties := gopter.NewProperties(parameters)
37
38	genA := GenE2()
39	genB := GenE2()
40	genfp := GenFp()
41
42	properties.Property("[BLS12-377] Having the receiver as operand (addition) should output the same result", prop.ForAll(
43		func(a, b *E2) bool {
44			var c, d E2
45			d.Set(a)
46			c.Add(a, b)
47			a.Add(a, b)
48			b.Add(&d, b)
49			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
50		},
51		genA,
52		genB,
53	))
54
55	properties.Property("[BLS12-377] Having the receiver as operand (sub) should output the same result", prop.ForAll(
56		func(a, b *E2) bool {
57			var c, d E2
58			d.Set(a)
59			c.Sub(a, b)
60			a.Sub(a, b)
61			b.Sub(&d, b)
62			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
63		},
64		genA,
65		genB,
66	))
67
68	properties.Property("[BLS12-377] Having the receiver as operand (mul) should output the same result", prop.ForAll(
69		func(a, b *E2) bool {
70			var c, d E2
71			d.Set(a)
72			c.Mul(a, b)
73			a.Mul(a, b)
74			b.Mul(&d, b)
75			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
76		},
77		genA,
78		genB,
79	))
80
81	properties.Property("[BLS12-377] Having the receiver as operand (square) should output the same result", prop.ForAll(
82		func(a *E2) bool {
83			var b E2
84			b.Square(a)
85			a.Square(a)
86			return a.Equal(&b)
87		},
88		genA,
89	))
90
91	properties.Property("[BLS12-377] Having the receiver as operand (neg) should output the same result", prop.ForAll(
92		func(a *E2) bool {
93			var b E2
94			b.Neg(a)
95			a.Neg(a)
96			return a.Equal(&b)
97		},
98		genA,
99	))
100
101	properties.Property("[BLS12-377] Having the receiver as operand (double) should output the same result", prop.ForAll(
102		func(a *E2) bool {
103			var b E2
104			b.Double(a)
105			a.Double(a)
106			return a.Equal(&b)
107		},
108		genA,
109	))
110
111	properties.Property("[BLS12-377] Having the receiver as operand (mul by non residue) should output the same result", prop.ForAll(
112		func(a *E2) bool {
113			var b E2
114			b.MulByNonResidue(a)
115			a.MulByNonResidue(a)
116			return a.Equal(&b)
117		},
118		genA,
119	))
120
121	properties.Property("[BLS12-377] Having the receiver as operand (mul by non residue inverse) should output the same result", prop.ForAll(
122		func(a *E2) bool {
123			var b E2
124			b.MulByNonResidueInv(a)
125			a.MulByNonResidueInv(a)
126			return a.Equal(&b)
127		},
128		genA,
129	))
130
131	properties.Property("[BLS12-377] Having the receiver as operand (Inverse) should output the same result", prop.ForAll(
132		func(a *E2) bool {
133			var b E2
134			b.Inverse(a)
135			a.Inverse(a)
136			return a.Equal(&b)
137		},
138		genA,
139	))
140
141	properties.Property("[BLS12-377] Having the receiver as operand (Conjugate) should output the same result", prop.ForAll(
142		func(a *E2) bool {
143			var b E2
144			b.Conjugate(a)
145			a.Conjugate(a)
146			return a.Equal(&b)
147		},
148		genA,
149	))
150
151	properties.Property("[BLS12-377] Having the receiver as operand (mul by element) should output the same result", prop.ForAll(
152		func(a *E2, b fp.Element) bool {
153			var c E2
154			c.MulByElement(a, &b)
155			a.MulByElement(a, &b)
156			return a.Equal(&c)
157		},
158		genA,
159		genfp,
160	))
161
162	properties.Property("[BLS12-377] Having the receiver as operand (Sqrt) should output the same result", prop.ForAll(
163		func(a *E2) bool {
164			var b, c, d, s E2
165
166			s.Square(a)
167			a.Set(&s)
168			b.Set(&s)
169
170			a.Sqrt(a)
171			b.Sqrt(&b)
172
173			c.Square(a)
174			d.Square(&b)
175			return c.Equal(&d)
176		},
177		genA,
178	))
179
180	properties.TestingRun(t, gopter.ConsoleReporter(false))
181
182	if supportAdx {
183		t.Log("disabling ADX")
184		supportAdx = false
185		properties.TestingRun(t, gopter.ConsoleReporter(false))
186		supportAdx = true
187	}
188}
189
190func TestE2MulMaxed(t *testing.T) {
191	// let's pick a and b, with maxed A0 and A1
192	var a, b E2
193	fpMaxValue := fp.Element{
194		9586122913090633729,
195		1660523435060625408,
196		2230234197602682880,
197		1883307231910630287,
198		14284016967150029115,
199		121098312706494698,
200	}
201	fpMaxValue[0]--
202
203	a.A0 = fpMaxValue
204	a.A1 = fpMaxValue
205	b.A0 = fpMaxValue
206	b.A1 = fpMaxValue
207
208	// [BN254] mul & inverse should leave an element invariant", prop.ForAll(
209	var c, d E2
210	d.Inverse(&b)
211	c.Set(&a)
212	c.Mul(&c, &b).Mul(&c, &d)
213	if !c.Equal(&a) {
214		t.Fatal("mul with max fp failed")
215	}
216}
217
218func TestE2Ops(t *testing.T) {
219
220	parameters := gopter.DefaultTestParameters()
221	parameters.MinSuccessfulTests = 100
222
223	properties := gopter.NewProperties(parameters)
224
225	genA := GenE2()
226	genB := GenE2()
227	genfp := GenFp()
228
229	properties.Property("[BLS12-377] sub & add should leave an element invariant", prop.ForAll(
230		func(a, b *E2) bool {
231			var c E2
232			c.Set(a)
233			c.Add(&c, b).Sub(&c, b)
234			return c.Equal(a)
235		},
236		genA,
237		genB,
238	))
239
240	properties.Property("[BLS12-377] mul & inverse should leave an element invariant", prop.ForAll(
241		func(a, b *E2) bool {
242			var c, d E2
243			d.Inverse(b)
244			c.Set(a)
245			c.Mul(&c, b).Mul(&c, &d)
246			return c.Equal(a)
247		},
248		genA,
249		genB,
250	))
251
252	properties.Property("[BLS12-377] inverse twice should leave an element invariant", prop.ForAll(
253		func(a *E2) bool {
254			var b E2
255			b.Inverse(a).Inverse(&b)
256			return a.Equal(&b)
257		},
258		genA,
259	))
260
261	properties.Property("[BLS12-377] neg twice should leave an element invariant", prop.ForAll(
262		func(a *E2) bool {
263			var b E2
264			b.Neg(a).Neg(&b)
265			return a.Equal(&b)
266		},
267		genA,
268	))
269
270	properties.Property("[BLS12-377] square and mul should output the same result", prop.ForAll(
271		func(a *E2) bool {
272			var b, c E2
273			b.Mul(a, a)
274			c.Square(a)
275			return b.Equal(&c)
276		},
277		genA,
278	))
279
280	properties.Property("[BLS12-377] MulByElement MulByElement inverse should leave an element invariant", prop.ForAll(
281		func(a *E2, b fp.Element) bool {
282			var c E2
283			var d fp.Element
284			d.Inverse(&b)
285			c.MulByElement(a, &b).MulByElement(&c, &d)
286			return c.Equal(a)
287		},
288		genA,
289		genfp,
290	))
291
292	properties.Property("[BLS12-377] Double and mul by 2 should output the same result", prop.ForAll(
293		func(a *E2) bool {
294			var b E2
295			var c fp.Element
296			c.SetUint64(2)
297			b.Double(a)
298			a.MulByElement(a, &c)
299			return a.Equal(&b)
300		},
301		genA,
302	))
303
304	properties.Property("[BLS12-377] Mulbynonres mulbynonresinv should leave the element invariant", prop.ForAll(
305		func(a *E2) bool {
306			var b E2
307			b.MulByNonResidue(a).MulByNonResidueInv(&b)
308			return a.Equal(&b)
309		},
310		genA,
311	))
312
313	properties.Property("[BLS12-377] a + pi(a), a-pi(a) should be real", prop.ForAll(
314		func(a *E2) bool {
315			var b, c, d E2
316			var e, f fp.Element
317			b.Conjugate(a)
318			c.Add(a, &b)
319			d.Sub(a, &b)
320			e.Double(&a.A0)
321			f.Double(&a.A1)
322			return c.A1.IsZero() && d.A0.IsZero() && e.Equal(&c.A0) && f.Equal(&d.A1)
323		},
324		genA,
325	))
326
327	properties.Property("[BLS12-377] Legendre on square should output 1", prop.ForAll(
328		func(a *E2) bool {
329			var b E2
330			b.Square(a)
331			c := b.Legendre()
332			return c == 1
333		},
334		genA,
335	))
336
337	properties.Property("[BLS12-377] square(sqrt) should leave an element invariant", prop.ForAll(
338		func(a *E2) bool {
339			var b, c, d, e E2
340			b.Square(a)
341			c.Sqrt(&b)
342			d.Square(&c)
343			e.Neg(a)
344			return (c.Equal(a) || c.Equal(&e)) && d.Equal(&b)
345		},
346		genA,
347	))
348
349	properties.Property("[BLS12-377] Cmp and LexicographicallyLargest should be consistant", prop.ForAll(
350		func(a *E2) bool {
351			var negA E2
352			negA.Neg(a)
353			cmpResult := a.Cmp(&negA)
354			lResult := a.LexicographicallyLargest()
355			if lResult && cmpResult == 1 {
356				return true
357			}
358			if !lResult && cmpResult != 1 {
359				return true
360			}
361			return false
362		},
363		genA,
364	))
365
366	properties.TestingRun(t, gopter.ConsoleReporter(false))
367
368	if supportAdx {
369		t.Log("disabling ADX")
370		supportAdx = false
371		properties.TestingRun(t, gopter.ConsoleReporter(false))
372		supportAdx = true
373	}
374}
375
376// ------------------------------------------------------------
377// benches
378
379func BenchmarkE2Add(b *testing.B) {
380	var a, c E2
381	a.SetRandom()
382	c.SetRandom()
383	b.ResetTimer()
384	for i := 0; i < b.N; i++ {
385		a.Add(&a, &c)
386	}
387}
388
389func BenchmarkE2Sub(b *testing.B) {
390	var a, c E2
391	a.SetRandom()
392	c.SetRandom()
393	b.ResetTimer()
394	for i := 0; i < b.N; i++ {
395		a.Sub(&a, &c)
396	}
397}
398
399func BenchmarkE2Mul(b *testing.B) {
400	var a, c E2
401	a.SetRandom()
402	c.SetRandom()
403	b.ResetTimer()
404	for i := 0; i < b.N; i++ {
405		a.Mul(&a, &c)
406	}
407}
408
409func BenchmarkE2MulByElement(b *testing.B) {
410	var a E2
411	var c fp.Element
412	c.SetRandom()
413	a.SetRandom()
414	b.ResetTimer()
415	for i := 0; i < b.N; i++ {
416		a.MulByElement(&a, &c)
417	}
418}
419
420func BenchmarkE2Square(b *testing.B) {
421	var a E2
422	a.SetRandom()
423	b.ResetTimer()
424	for i := 0; i < b.N; i++ {
425		a.Square(&a)
426	}
427}
428
429func BenchmarkE2Sqrt(b *testing.B) {
430	var a E2
431	a.SetRandom()
432	b.ResetTimer()
433	for i := 0; i < b.N; i++ {
434		a.Sqrt(&a)
435	}
436}
437
438func BenchmarkE2Exp(b *testing.B) {
439	var x E2
440	x.SetRandom()
441	b1, _ := rand.Int(rand.Reader, fp.Modulus())
442	b.ResetTimer()
443	for i := 0; i < b.N; i++ {
444		x.Exp(x, b1)
445	}
446}
447
448func BenchmarkE2Inverse(b *testing.B) {
449	var a E2
450	a.SetRandom()
451	b.ResetTimer()
452	for i := 0; i < b.N; i++ {
453		a.Inverse(&a)
454	}
455}
456
457func BenchmarkE2MulNonRes(b *testing.B) {
458	var a E2
459	a.SetRandom()
460	b.ResetTimer()
461	for i := 0; i < b.N; i++ {
462		a.MulByNonResidue(&a)
463	}
464}
465
466func BenchmarkE2MulNonResInv(b *testing.B) {
467	var a E2
468	a.SetRandom()
469	b.ResetTimer()
470	for i := 0; i < b.N; i++ {
471		a.MulByNonResidueInv(&a)
472	}
473}
474
475func BenchmarkE2Conjugate(b *testing.B) {
476	var a E2
477	a.SetRandom()
478	b.ResetTimer()
479	for i := 0; i < b.N; i++ {
480		a.Conjugate(&a)
481	}
482}
483