1 package ff
2
3 import (
4 "fmt"
5 "testing"
6
7 "github.com/cloudflare/circl/internal/test"
8 )
9
10 func randomFp2(t testing.TB) *Fp2 { return &Fp2{*randomFp(t), *randomFp(t)} }
11
12 func TestFp2(t *testing.T) {
13 const testTimes = 1 << 9
14 t.Run("no_alias", func(t *testing.T) {
15 var want, got Fp2
16 x := randomFp2(t)
17 got = *x
18 got.Sqr(&got)
19 want = *x
20 want.Mul(&want, &want)
21 if got.IsEqual(&want) == 0 {
22 test.ReportError(t, got, want, x)
23 }
24 })
25 t.Run("mul_inv", func(t *testing.T) {
26 var z Fp2
27 for i := 0; i < testTimes; i++ {
28 x := randomFp2(t)
29 y := randomFp2(t)
30
31
32 z.Inv(x)
33 z.Mul(&z, y)
34 z.Mul(&z, x)
35 z.Sub(&z, y)
36 got := z.IsZero()
37 want := 1
38 if got != want {
39 test.ReportError(t, got, want, x, y, z)
40 }
41 }
42 })
43 t.Run("mul_sqr", func(t *testing.T) {
44 var l0, l1, r0, r1 Fp2
45 for i := 0; i < testTimes; i++ {
46 x := randomFp2(t)
47 y := randomFp2(t)
48
49
50 l0.Add(x, y)
51 l1.Sub(x, y)
52 l0.Mul(&l0, &l1)
53 r0.Sqr(x)
54 r1.Sqr(y)
55 r0.Sub(&r0, &r1)
56 got := &l0
57 want := &r0
58 if got.IsEqual(want) == 0 {
59 test.ReportError(t, got, want, x, y)
60 }
61 }
62 })
63 t.Run("sqrt", func(t *testing.T) {
64 var r, notRoot, got Fp2
65
66 for i := 0; i < testTimes; i++ {
67 x := randomFp2(t)
68 x.Sqr(x)
69
70
71 isQR := r.Sqrt(x)
72 test.CheckOk(isQR == 1, fmt.Sprintf("should be a QR: %v", x), t)
73 rNeg := r
74 rNeg.Neg()
75
76 want := x
77 for _, root := range []*Fp2{&r, &rNeg} {
78 got.Sqr(root)
79 if got.IsEqual(want) == 0 {
80 test.ReportError(t, got, want, x, root)
81 }
82 }
83 }
84
85 var uPlus1 Fp2
86 uPlus1[0].SetUint64(1)
87 uPlus1[1].SetUint64(1)
88 for i := 0; i < testTimes; i++ {
89 want := randomFp2(t)
90 x := randomFp2(t)
91 x.Sqr(x)
92 x.Mul(x, &uPlus1)
93
94
95 got := want
96 isQR := got.Sqrt(x)
97 test.CheckOk(isQR == 0, fmt.Sprintf("shouldn't be a QR: %v", x), t)
98
99 if got.IsEqual(want) != 1 {
100 test.ReportError(t, got, want, x, notRoot)
101 }
102 }
103 })
104 t.Run("marshal", func(t *testing.T) {
105 var b Fp2
106 for i := 0; i < testTimes; i++ {
107 a := randomFp2(t)
108 s, err := a.MarshalBinary()
109 test.CheckNoErr(t, err, "MarshalBinary failed")
110 err = b.UnmarshalBinary(s)
111 test.CheckNoErr(t, err, "UnmarshalBinary failed")
112 if b.IsEqual(a) == 0 {
113 test.ReportError(t, a, b)
114 }
115 }
116 })
117 }
118
119 func BenchmarkFp2(b *testing.B) {
120 x := randomFp2(b)
121 y := randomFp2(b)
122 z := randomFp2(b)
123 b.Run("Add", func(b *testing.B) {
124 for i := 0; i < b.N; i++ {
125 z.Add(x, y)
126 }
127 })
128 b.Run("Mul", func(b *testing.B) {
129 for i := 0; i < b.N; i++ {
130 z.Mul(x, y)
131 }
132 })
133 b.Run("Sqr", func(b *testing.B) {
134 for i := 0; i < b.N; i++ {
135 z.Sqr(x)
136 }
137 })
138 b.Run("Inv", func(b *testing.B) {
139 for i := 0; i < b.N; i++ {
140 z.Inv(x)
141 }
142 })
143 }
144
View as plain text