1 package ff_test
2
3 import (
4 "bytes"
5 "crypto/rand"
6 "math/big"
7 "testing"
8
9 "github.com/cloudflare/circl/ecc/bls12381/ff"
10 "github.com/cloudflare/circl/internal/test"
11 )
12
13 func randomScalar(t testing.TB) *ff.Scalar {
14 t.Helper()
15 s := new(ff.Scalar)
16 err := s.Random(rand.Reader)
17 if err != nil {
18 t.Error(err)
19 }
20 return s
21 }
22
23 func TestScalar(t *testing.T) {
24 const testTimes = 1 << 10
25 t.Run("marshal", func(t *testing.T) {
26 for i := 0; i < testTimes; i++ {
27 var y ff.Scalar
28 x := randomScalar(t)
29
30 bytes, err := x.MarshalBinary()
31 if err != nil {
32 test.ReportError(t, x, y, x)
33 }
34 err = y.UnmarshalBinary(bytes)
35 if err != nil {
36 test.ReportError(t, x, y, x)
37 }
38 if x.IsEqual(&y) == 0 {
39 test.ReportError(t, x, y, x)
40 }
41 }
42 })
43 t.Run("no_alias", func(t *testing.T) {
44 var want, got ff.Scalar
45 x := randomScalar(t)
46 got.Set(x)
47 got.Sqr(&got)
48 want.Set(x)
49 want.Mul(&want, &want)
50 if got.IsEqual(&want) == 0 {
51 test.ReportError(t, got, want, x)
52 }
53 })
54 t.Run("mul_inv", func(t *testing.T) {
55 var z ff.Scalar
56 for i := 0; i < testTimes; i++ {
57 x := randomScalar(t)
58 y := randomScalar(t)
59
60 z.Inv(x)
61 z.Mul(&z, y)
62 z.Mul(&z, x)
63 z.Sub(&z, y)
64 got := z.IsZero()
65 want := 1
66 if got != want {
67 test.ReportError(t, got, want, x, y)
68 }
69 }
70 })
71 t.Run("mul_sqr", func(t *testing.T) {
72 var l0, l1, r0, r1 ff.Scalar
73 for i := 0; i < testTimes; i++ {
74 x := randomScalar(t)
75 y := randomScalar(t)
76
77
78 l0.Add(x, y)
79 l1.Sub(x, y)
80 l0.Mul(&l0, &l1)
81 r0.Sqr(x)
82 r1.Sqr(y)
83 r0.Sub(&r0, &r1)
84 got := &l0
85 want := &r0
86 if got.IsEqual(want) == 0 {
87 test.ReportError(t, got, want, x, y)
88 }
89 }
90 })
91 t.Run("bytes", func(t *testing.T) {
92 var data [100]byte
93 _, _ = rand.Read(data[:])
94
95 var a, b ff.Scalar
96 var bigA, bigOrder big.Int
97 bigOrder.SetBytes(ff.ScalarOrder())
98
99 for i := 0; i < 100; i++ {
100 a.SetBytes(data[:i])
101
102 bigA.SetBytes(data[:i])
103 bigA.Mod(&bigA, &bigOrder)
104 bytesA := bigA.Bytes()
105 b.SetBytes(bytesA)
106
107 if a.IsEqual(&b) == 0 {
108 test.ReportError(t, a, b)
109 }
110
111 got, err := a.MarshalBinary()
112 test.CheckNoErr(t, err, "MarshalBinary failed")
113 want, err := b.MarshalBinary()
114 test.CheckNoErr(t, err, "MarshalBinary failed")
115
116 if !bytes.Equal(got, want) {
117 test.ReportError(t, got, want)
118 }
119 }
120 })
121 }
122
123 func BenchmarkScalar(b *testing.B) {
124 x := randomScalar(b)
125 y := randomScalar(b)
126 z := randomScalar(b)
127
128 b.Run("Add", func(b *testing.B) {
129 for i := 0; i < b.N; i++ {
130 z.Add(x, y)
131 }
132 })
133 b.Run("Mul", func(b *testing.B) {
134 for i := 0; i < b.N; i++ {
135 z.Mul(x, y)
136 }
137 })
138 b.Run("Sqr", func(b *testing.B) {
139 for i := 0; i < b.N; i++ {
140 z.Sqr(x)
141 }
142 })
143 b.Run("Inv", func(b *testing.B) {
144 for i := 0; i < b.N; i++ {
145 z.Inv(x)
146 }
147 })
148 }
149
View as plain text