1 package p384_test
2
3 import (
4 "crypto/elliptic"
5 "crypto/rand"
6 "fmt"
7 "testing"
8
9 "github.com/cloudflare/circl/ecc/p384"
10 "github.com/cloudflare/circl/internal/test"
11 )
12
13 func TestIsOnCurveTrue(t *testing.T) {
14 CirclCurve := p384.P384()
15 k := make([]byte, 384/8)
16 for i := 0; i < 128; i++ {
17 _, _ = rand.Read(k)
18 x, y := elliptic.P384().ScalarBaseMult(k)
19
20 got := CirclCurve.IsOnCurve(x, y)
21 want := true
22 if got != want {
23 test.ReportError(t, got, want, k)
24 }
25
26 x = x.Neg(x)
27 got = CirclCurve.IsOnCurve(x, y)
28 want = false
29 if got != want {
30 test.ReportError(t, got, want, k)
31 }
32 }
33 }
34
35 func TestAffine(t *testing.T) {
36 const testTimes = 1 << 7
37 CirclCurve := p384.P384()
38 StdCurve := elliptic.P384()
39 params := StdCurve.Params()
40
41 t.Run("Addition", func(t *testing.T) {
42 for i := 0; i < testTimes; i++ {
43 K1, _ := rand.Int(rand.Reader, params.N)
44 K2, _ := rand.Int(rand.Reader, params.N)
45 X1, Y1 := StdCurve.ScalarBaseMult(K1.Bytes())
46 X2, Y2 := StdCurve.ScalarBaseMult(K2.Bytes())
47 wantX, wantY := StdCurve.Add(X1, Y1, X2, Y2)
48 gotX, gotY := CirclCurve.Add(X1, Y1, X2, Y2)
49
50 if gotX.Cmp(wantX) != 0 {
51 test.ReportError(t, gotX, wantX, K1, K2)
52 }
53 if gotY.Cmp(wantY) != 0 {
54 test.ReportError(t, gotY, wantY)
55 }
56 }
57 })
58
59 t.Run("Double", func(t *testing.T) {
60 for i := 0; i < testTimes; i++ {
61 k, _ := rand.Int(rand.Reader, params.N)
62 x, y := StdCurve.ScalarBaseMult(k.Bytes())
63 wantX, wantY := StdCurve.Double(x, y)
64
65 gotX, gotY := CirclCurve.Double(x, y)
66
67 if gotX.Cmp(wantX) != 0 {
68 test.ReportError(t, gotX, wantX, k)
69 }
70 if gotY.Cmp(wantY) != 0 {
71 test.ReportError(t, gotY, wantY)
72 }
73 }
74 })
75 }
76
77 func TestScalarBaseMult(t *testing.T) {
78 const testTimes = 1 << 6
79 CirclCurve := p384.P384()
80 StdCurve := elliptic.P384()
81
82 t.Run("0P", func(t *testing.T) {
83 k := make([]byte, 500)
84 for i := 0; i < len(k); i += 20 {
85 gotX, gotY := CirclCurve.ScalarBaseMult(k[:i])
86 wantX, wantY := StdCurve.ScalarBaseMult(k[:i])
87 if gotX.Cmp(wantX) != 0 {
88 test.ReportError(t, gotX, wantX, k[:i])
89 }
90 if gotY.Cmp(wantY) != 0 {
91 test.ReportError(t, gotY, wantY)
92 }
93 }
94 })
95
96 t.Run("kP", func(t *testing.T) {
97 k := make([]byte, 48)
98 for i := 0; i < testTimes; i++ {
99 _, _ = rand.Read(k)
100 gotX, gotY := CirclCurve.ScalarBaseMult(k)
101 wantX, wantY := StdCurve.ScalarBaseMult(k)
102 if gotX.Cmp(wantX) != 0 {
103 test.ReportError(t, gotX, wantX, k)
104 }
105 if gotY.Cmp(wantY) != 0 {
106 test.ReportError(t, gotY, wantY)
107 }
108 }
109 })
110
111 t.Run("kSmall", func(t *testing.T) {
112 k := make([]byte, 16)
113 for i := 0; i < testTimes; i++ {
114 _, _ = rand.Read(k)
115 gotX, gotY := CirclCurve.ScalarBaseMult(k)
116 wantX, wantY := StdCurve.ScalarBaseMult(k)
117 if gotX.Cmp(wantX) != 0 {
118 test.ReportError(t, gotX, wantX, k)
119 }
120 if gotY.Cmp(wantY) != 0 {
121 test.ReportError(t, gotY, wantY)
122 }
123 }
124 })
125
126 t.Run("kLarge", func(t *testing.T) {
127 k := make([]byte, 384)
128 for i := 0; i < testTimes; i++ {
129 _, _ = rand.Read(k)
130 gotX, gotY := CirclCurve.ScalarBaseMult(k)
131 wantX, wantY := StdCurve.ScalarBaseMult(k)
132 if gotX.Cmp(wantX) != 0 {
133 test.ReportError(t, gotX, wantX, k)
134 }
135 if gotY.Cmp(wantY) != 0 {
136 test.ReportError(t, gotY, wantY)
137 }
138 }
139 })
140 }
141
142 func TestScalarMult(t *testing.T) {
143 const testTimes = 1 << 6
144 CirclCurve := p384.P384()
145 StdCurve := elliptic.P384()
146 params := StdCurve.Params()
147
148 t.Run("k=0", func(t *testing.T) {
149 k := []byte{0x0}
150 gotX, gotY := CirclCurve.ScalarMult(params.Gx, params.Gy, k)
151 got := CirclCurve.IsAtInfinity(gotX, gotY)
152 want := true
153 if got != want {
154 test.ReportError(t, got, want)
155 }
156 })
157
158 t.Run("random k", func(t *testing.T) {
159 for i := 0; i < testTimes; i++ {
160 k, _ := rand.Int(rand.Reader, params.N)
161 gotX, gotY := CirclCurve.ScalarMult(params.Gx, params.Gy, k.Bytes())
162 wantX, wantY := StdCurve.ScalarMult(params.Gx, params.Gy, k.Bytes())
163
164 if gotX.Cmp(wantX) != 0 {
165 test.ReportError(t, gotX, wantX, k)
166 }
167 if gotY.Cmp(wantY) != 0 {
168 test.ReportError(t, gotY, wantY)
169 }
170 }
171 })
172
173 t.Run("wrong P", func(t *testing.T) {
174 for i := 0; i < testTimes; i++ {
175 k, _ := rand.Int(rand.Reader, params.N)
176 x, _ := rand.Int(rand.Reader, params.P)
177 y, _ := rand.Int(rand.Reader, params.P)
178
179 got := CirclCurve.IsOnCurve(x, y) && CirclCurve.IsOnCurve(CirclCurve.ScalarMult(x, y, k.Bytes()))
180 want := StdCurve.IsOnCurve(x, y) && StdCurve.IsOnCurve(StdCurve.ScalarMult(x, y, k.Bytes()))
181
182 if got != want {
183 test.ReportError(t, got, want, k, x, y)
184 }
185 }
186 })
187 }
188
189 func TestCombinedMult(t *testing.T) {
190 const testTimes = 1 << 7
191 CirclCurve := p384.P384()
192 StdCurve := elliptic.P384()
193 params := StdCurve.Params()
194
195 for i := 0; i < testTimes; i++ {
196 K, _ := rand.Int(rand.Reader, params.N)
197 X, Y := StdCurve.ScalarBaseMult(K.Bytes())
198
199 K1, _ := rand.Int(rand.Reader, params.N)
200 K2, _ := rand.Int(rand.Reader, params.N)
201 x1, y1 := StdCurve.ScalarBaseMult(K1.Bytes())
202 x2, y2 := StdCurve.ScalarMult(X, Y, K2.Bytes())
203 wantX, wantY := StdCurve.Add(x1, y1, x2, y2)
204
205 gotX, gotY := CirclCurve.CombinedMult(X, Y, K1.Bytes(), K2.Bytes())
206 if gotX.Cmp(wantX) != 0 {
207 test.ReportError(t, gotX, wantX, K, K1, K2)
208 }
209 if gotY.Cmp(wantY) != 0 {
210 test.ReportError(t, gotY, wantY)
211 }
212 }
213 }
214
215 func BenchmarkScalarMult(b *testing.B) {
216 curve := p384.P384()
217 params := curve.Params()
218
219 K, _ := rand.Int(rand.Reader, params.N)
220 M, _ := rand.Int(rand.Reader, params.N)
221 N, _ := rand.Int(rand.Reader, params.N)
222 k := K.Bytes()
223 m := M.Bytes()
224 n := N.Bytes()
225
226 b.Run("kG", func(b *testing.B) {
227 for i := 0; i < b.N; i++ {
228 curve.ScalarBaseMult(k)
229 }
230 })
231 b.Run("kP", func(b *testing.B) {
232 for i := 0; i < b.N; i++ {
233 curve.ScalarMult(params.Gx, params.Gy, k)
234 }
235 })
236 b.Run("kG+lP", func(b *testing.B) {
237 for i := 0; i < b.N; i++ {
238 _, _ = curve.CombinedMult(params.Gx, params.Gy, m, n)
239 }
240 })
241 }
242
243 func Example_p384() {
244
245
246 circl := p384.P384()
247 stdlib := elliptic.P384()
248
249 params := circl.Params()
250 K, _ := rand.Int(rand.Reader, params.N)
251 k := K.Bytes()
252
253 x1, y1 := circl.ScalarBaseMult(k)
254 x2, y2 := stdlib.ScalarBaseMult(k)
255 fmt.Printf("%v, %v", x1.Cmp(x2) == 0, y1.Cmp(y2) == 0)
256
257 }
258
View as plain text