1
2
3
4 package p384
5
6 import (
7 "crypto/elliptic"
8 "crypto/rand"
9 "math/big"
10 "testing"
11
12 "github.com/cloudflare/circl/internal/test"
13 )
14
15 func TestFpCmov(t *testing.T) {
16 var x, y, z fp384
17 for _, b := range []int{-2, -1, 1, 2} {
18 _, _ = rand.Read(x[:])
19 _, _ = rand.Read(y[:])
20 z = x
21 fp384Cmov(&z, &y, b)
22 got := z
23 want := y
24 if got != want {
25 test.ReportError(t, got, want, b, x, y)
26 }
27 }
28 _, _ = rand.Read(x[:])
29 _, _ = rand.Read(y[:])
30 z = x
31 fp384Cmov(&z, &y, 0)
32 got := z
33 want := x
34 if got != want {
35 test.ReportError(t, got, want, 0, x, y)
36 }
37 }
38
39 func TestFpNegZero(t *testing.T) {
40 zero, x := &fp384{}, &fp384{}
41 fp384Neg(x, zero)
42 got := x.BigInt()
43 want := zero.BigInt()
44 if got.Cmp(want) != 0 {
45 test.ReportError(t, got, want, x)
46 }
47 }
48
49 func TestFpSetBigInt(t *testing.T) {
50 P := elliptic.P384().Params().P
51
52 neg := big.NewInt(-0xFF)
53 zero := big.NewInt(0)
54 one := big.NewInt(1)
55 two96 := new(big.Int).Lsh(one, 96)
56 two384 := new(big.Int).Lsh(one, 384)
57 two384two96 := new(big.Int).Sub(two384, two96)
58 two768 := new(big.Int).Lsh(one, 768)
59
60 for id, b := range []*big.Int{
61 neg, zero, one, two96, two384, two384two96, two768,
62 } {
63 var x fp384
64 x.SetBigInt(b)
65 got := x.BigInt()
66 if b.BitLen() > 384 || b.Sign() < 0 {
67 b.Mod(b, P)
68 }
69 want := b
70 if got.Cmp(want) != 0 {
71 test.ReportError(t, got, want, id)
72 }
73 }
74 }
75
76 func TestMulZero(t *testing.T) {
77 x, zero := &fp384{}, &fp384{}
78 _, _ = rand.Read(x[:])
79
80 fp384Mul(x, x, zero)
81 got := x.BigInt()
82 want := zero.BigInt()
83
84 if got.Cmp(want) != 0 {
85 test.ReportError(t, got, want, x)
86 }
87 }
88
89 func TestFp(t *testing.T) {
90 P := elliptic.P384().Params().P
91 x, y, z := &fp384{}, &fp384{}, &fp384{}
92 testTimes := 1 << 12
93 var bigR, bigR2, bigRinv big.Int
94 one := big.NewInt(1)
95 bigR.Lsh(one, 384).Mod(&bigR, P)
96 bigR2.Lsh(one, 2*384).Mod(&bigR2, P)
97 bigRinv.ModInverse(&bigR, P)
98
99 t.Run("Encode", func(t *testing.T) {
100 for i := 0; i < testTimes; i++ {
101 _, _ = rand.Read(x[:])
102 bigX := x.BigInt()
103
104 montEncode(z, x)
105 got := z.BigInt()
106
107 want := bigX.Mul(bigX, &bigR).Mod(bigX, P)
108 if got.Cmp(want) != 0 {
109 test.ReportError(t, got, want, x)
110 }
111 }
112 })
113 t.Run("Decode", func(t *testing.T) {
114 for i := 0; i < testTimes; i++ {
115 _, _ = rand.Read(x[:])
116 bigX := x.BigInt()
117
118 montDecode(z, x)
119 got := z.BigInt()
120
121 want := bigX.Mul(bigX, new(big.Int).ModInverse(&bigR, P)).Mod(bigX, P)
122 if got.Cmp(want) != 0 {
123 test.ReportError(t, got, want, x)
124 }
125 }
126 })
127 t.Run("Neg", func(t *testing.T) {
128 for i := 0; i < testTimes; i++ {
129 _, _ = rand.Read(x[:])
130 bigX := x.BigInt()
131
132 fp384Neg(z, x)
133 got := z.BigInt()
134
135 want := bigX.Neg(bigX).Mod(bigX, P)
136 if got.Cmp(want) != 0 {
137 test.ReportError(t, got, want, x)
138 }
139 }
140 })
141 t.Run("Add", func(t *testing.T) {
142 for i := 0; i < testTimes; i++ {
143 _, _ = rand.Read(x[:])
144 _, _ = rand.Read(y[:])
145 bigX := x.BigInt()
146 bigY := y.BigInt()
147
148 fp384Add(z, x, y)
149 got := z.BigInt()
150
151 want := bigX.Add(bigX, bigY)
152 want = want.Mod(want, P)
153 if got.Cmp(want) != 0 {
154 test.ReportError(t, got, want, x, y)
155 }
156 }
157 })
158 t.Run("Sub", func(t *testing.T) {
159 for i := 0; i < testTimes; i++ {
160 _, _ = rand.Read(x[:])
161 _, _ = rand.Read(y[:])
162 bigX := x.BigInt()
163 bigY := y.BigInt()
164
165 fp384Sub(z, x, y)
166 got := z.BigInt()
167
168 want := bigX.Sub(bigX, bigY)
169 want = want.Mod(want, P)
170 if got.Cmp(want) != 0 {
171 test.ReportError(t, got, want, x, y)
172 }
173 }
174 })
175 t.Run("Mul", func(t *testing.T) {
176 for i := 0; i < testTimes; i++ {
177 _, _ = rand.Read(x[:])
178 _, _ = rand.Read(y[:])
179 bigX := x.BigInt()
180 bigY := y.BigInt()
181
182 fp384Mul(z, x, y)
183 got := z.BigInt()
184
185 want := bigX.Mul(bigX, bigY).Mul(bigX, &bigRinv).Mod(bigX, P)
186 if got.Cmp(want) != 0 {
187 test.ReportError(t, got, want, x, y)
188 }
189 }
190 })
191 t.Run("Inv", func(t *testing.T) {
192 for i := 0; i < testTimes; i++ {
193 _, _ = rand.Read(x[:])
194 bigX := x.BigInt()
195
196 fp384Inv(z, x)
197 got := z.BigInt()
198
199 want := bigX.ModInverse(bigX, P).Mul(bigX, &bigR2).Mod(bigX, P)
200 if got.Cmp(want) != 0 {
201 test.ReportError(t, got, want, x)
202 }
203 }
204 })
205 }
206
207 func BenchmarkFp(b *testing.B) {
208 x, y, z := &fp384{}, &fp384{}, &fp384{}
209
210 b.Run("Add", func(b *testing.B) {
211 for i := 0; i < b.N; i++ {
212 fp384Add(z, x, y)
213 }
214 })
215
216 b.Run("Sub", func(b *testing.B) {
217 for i := 0; i < b.N; i++ {
218 fp384Sub(z, x, y)
219 }
220 })
221
222 b.Run("Mul", func(b *testing.B) {
223 for i := 0; i < b.N; i++ {
224 fp384Mul(z, x, y)
225 }
226 })
227
228 b.Run("Sqr", func(b *testing.B) {
229 for i := 0; i < b.N; i++ {
230 fp384Sqr(z, x)
231 }
232 })
233
234 b.Run("Inv", func(b *testing.B) {
235 for i := 0; i < b.N; i++ {
236 fp384Inv(z, x)
237 }
238 })
239 }
240
View as plain text