1 package fourq
2
3 import (
4 "crypto/rand"
5 "math/big"
6 "testing"
7
8 "github.com/cloudflare/circl/internal/conv"
9 "github.com/cloudflare/circl/internal/test"
10 )
11
12 func (P *pointR1) random() {
13 var k [Size]byte
14 _, _ = rand.Read(k[:])
15 P.ScalarBaseMult(&k)
16 }
17
18 func TestPointAddition(t *testing.T) {
19 const testTimes = 1 << 10
20 var P, Q pointR1
21 _16P := &pointR1{}
22 S := &pointR2{}
23 for i := 0; i < testTimes; i++ {
24 P.random()
25 _16P.copy(&P)
26 S.FromR1(&P)
27
28 for j := 0; j < 4; j++ {
29 _16P.double()
30 }
31
32 Q.SetIdentity()
33 for j := 0; j < 16; j++ {
34 Q.add(S)
35 }
36 got := _16P.isEqual(&Q)
37 want := true
38 if got != want {
39 test.ReportError(t, got, want, P)
40 }
41 }
42 }
43
44 func TestOddMultiples(t *testing.T) {
45 const testTimes = 1 << 10
46 var P, Q, R pointR1
47 var Tab [8]pointR2
48 for i := 0; i < testTimes; i++ {
49 P.random()
50
51 P.oddMultiples(&Tab)
52
53 Q.SetIdentity()
54 for j := range Tab {
55 Q.add(&Tab[j])
56 }
57
58 for j := 0; j < 6; j++ {
59 R.double()
60 }
61 got := Q.isEqual(&R)
62 want := true
63 if got != want {
64 test.ReportError(t, got, want, P)
65 }
66 }
67 }
68
69 func TestScalarMult(t *testing.T) {
70 const testTimes = 1 << 10
71 var P, Q, G pointR1
72 var k [Size]byte
73
74 t.Run("0P=0", func(t *testing.T) {
75 for i := 0; i < testTimes; i++ {
76 P.random()
77 Q.ScalarMult(&k, &P)
78 got := Q.IsIdentity()
79 want := true
80 if got != want {
81 test.ReportError(t, got, want, P)
82 }
83 }
84 })
85 t.Run("order*P=0", func(t *testing.T) {
86 conv.BigInt2BytesLe(k[:], conv.Uint64Le2BigInt(orderGenerator[:]))
87 for i := 0; i < testTimes; i++ {
88 P.random()
89 Q.ScalarMult(&k, &P)
90 got := Q.IsIdentity()
91 want := true
92 if got != want {
93 test.ReportError(t, got, want, P)
94 }
95 }
96 })
97 t.Run("cofactor*P=clear(P)", func(t *testing.T) {
98 conv.BigInt2BytesLe(k[:], big.NewInt(392))
99 for i := 0; i < testTimes; i++ {
100 P.random()
101 Q.ScalarMult(&k, &P)
102 P.ClearCofactor()
103 got := Q.isEqual(&P)
104 want := true
105 if got != want {
106 test.ReportError(t, got, want, P)
107 }
108 }
109 })
110 t.Run("mult", func(t *testing.T) {
111 G.X = genX
112 G.Y = genY
113 for i := 0; i < testTimes; i++ {
114 _, _ = rand.Read(k[:])
115 P.ScalarMult(&k, &G)
116 Q.ScalarBaseMult(&k)
117 got := Q.isEqual(&P)
118 want := true
119 if got != want {
120 test.ReportError(t, got, want, k)
121 }
122 }
123 })
124 }
125
126 func TestScalar(t *testing.T) {
127 const testTimes = 1 << 12
128 var xx [5]uint64
129 two256 := big.NewInt(1)
130 two256.Lsh(two256, 256)
131 two64 := big.NewInt(1)
132 two64.Lsh(two64, 64)
133 bigOrder := conv.Uint64Le2BigInt(orderGenerator[:])
134
135 t.Run("subYdiv16", func(t *testing.T) {
136 want := new(big.Int)
137 for i := 0; i < testTimes; i++ {
138 bigX, _ := rand.Int(rand.Reader, two256)
139 conv.BigInt2Uint64Le(xx[:], bigX)
140 x := xx
141 bigY, _ := rand.Int(rand.Reader, two64)
142 y := bigY.Int64()
143 bigY.SetInt64(y)
144
145 subYDiv16(&x, y)
146 got := conv.Uint64Le2BigInt(x[:])
147
148 want.Sub(bigX, bigY).Rsh(want, 4)
149
150 if got.Cmp(want) != 0 {
151 test.ReportError(t, got, want, bigX, y)
152 }
153 }
154 })
155
156 t.Run("div2subY", func(t *testing.T) {
157 want := new(big.Int)
158 for i := 0; i < testTimes; i++ {
159 bigX, _ := rand.Int(rand.Reader, two256)
160 conv.BigInt2Uint64Le(xx[:], bigX)
161 x := xx
162 bigY, _ := rand.Int(rand.Reader, two64)
163 y := bigY.Int64()
164 bigY.SetInt64(y)
165
166 div2subY(&x, y)
167 got := conv.Uint64Le2BigInt(x[:])
168
169 want.Rsh(bigX, 1).Sub(want, bigY)
170
171 if got.Cmp(want) != 0 {
172 test.ReportError(t, got, want, bigX, y)
173 }
174 }
175 })
176
177 t.Run("condAddOrderN", func(t *testing.T) {
178 for i := 0; i < testTimes; i++ {
179 bigX, _ := rand.Int(rand.Reader, two256)
180 conv.BigInt2Uint64Le(xx[:], bigX)
181 x := xx
182
183 condAddOrderN(&x)
184 got := conv.Uint64Le2BigInt(x[:])
185
186 want := bigX
187 if want.Bit(0) == 0 {
188 want.Add(want, bigOrder)
189 }
190
191 if got.Cmp(want) != 0 {
192 test.ReportError(t, got, want, x)
193 }
194 }
195 })
196
197 t.Run("recode", func(t *testing.T) {
198 var k [32]byte
199 var d [65]int8
200 got := new(big.Int)
201 for i := 0; i < testTimes; i++ {
202 _, _ = rand.Read(k[:])
203
204 recodeScalar(&d, &k)
205 got.SetInt64(0)
206 for j := len(d) - 1; j >= 0; j-- {
207 got.Lsh(got, 4).Add(got, big.NewInt(int64(d[j])))
208 }
209
210 want := conv.BytesLe2BigInt(k[:])
211 if want.Bit(0) == 0 {
212 want.Add(want, bigOrder)
213 }
214
215 if got.Cmp(want) != 0 {
216 test.ReportError(t, got, want, k)
217 }
218 }
219 })
220 }
221
222 func BenchmarkPoint(b *testing.B) {
223 var P, R pointR1
224 var Q pointR2
225 var k [Size]byte
226
227 _, _ = rand.Read(k[:])
228
229 P.random()
230 R.random()
231 Q.FromR1(&R)
232 R.random()
233
234 b.Run("affine", func(b *testing.B) {
235 for i := 0; i < b.N; i++ {
236 P.ToAffine()
237 }
238 })
239 b.Run("double", func(b *testing.B) {
240 for i := 0; i < b.N; i++ {
241 P.double()
242 }
243 })
244 b.Run("add", func(b *testing.B) {
245 for i := 0; i < b.N; i++ {
246 P.add(&Q)
247 }
248 })
249 b.Run("scmulBase", func(b *testing.B) {
250 for i := 0; i < b.N; i++ {
251 P.ScalarBaseMult(&k)
252 }
253 })
254 b.Run("scmul", func(b *testing.B) {
255 for i := 0; i < b.N; i++ {
256 P.ScalarMult(&k, &R)
257 }
258 })
259 }
260
View as plain text