1
2
3
4
5 package edwards25519
6
7 import (
8 "crypto/internal/fips140/edwards25519/field"
9 "encoding/hex"
10 "reflect"
11 "testing"
12 )
13
14 var B = NewGeneratorPoint()
15 var I = NewIdentityPoint()
16
17 func checkOnCurve(t *testing.T, points ...*Point) {
18 t.Helper()
19 for i, p := range points {
20 var XX, YY, ZZ, ZZZZ field.Element
21 XX.Square(&p.x)
22 YY.Square(&p.y)
23 ZZ.Square(&p.z)
24 ZZZZ.Square(&ZZ)
25
26
27
28
29 var lhs, rhs field.Element
30 lhs.Subtract(&YY, &XX).Multiply(&lhs, &ZZ)
31 rhs.Multiply(d, &XX).Multiply(&rhs, &YY).Add(&rhs, &ZZZZ)
32 if lhs.Equal(&rhs) != 1 {
33 t.Errorf("X, Y, and Z do not specify a point on the curve\nX = %v\nY = %v\nZ = %v", p.x, p.y, p.z)
34 }
35
36 lhs.Multiply(&p.x, &p.y)
37 rhs.Multiply(&p.z, &p.t)
38 if lhs.Equal(&rhs) != 1 {
39 t.Errorf("point %d is not valid\nX = %v\nY = %v\nZ = %v", i, p.x, p.y, p.z)
40 }
41 }
42 }
43
44 func TestGenerator(t *testing.T) {
45
46
47 x := "1ad5258f602d56c9b2a7259560c72c695cdcd6fd31e2a4c0fe536ecdd3366921"
48 y := "5866666666666666666666666666666666666666666666666666666666666666"
49 if got := hex.EncodeToString(B.x.Bytes()); got != x {
50 t.Errorf("wrong B.x: got %s, expected %s", got, x)
51 }
52 if got := hex.EncodeToString(B.y.Bytes()); got != y {
53 t.Errorf("wrong B.y: got %s, expected %s", got, y)
54 }
55 if B.z.Equal(feOne) != 1 {
56 t.Errorf("wrong B.z: got %v, expected 1", B.z)
57 }
58
59 checkOnCurve(t, B)
60 }
61
62 func TestAddSubNegOnBasePoint(t *testing.T) {
63 checkLhs, checkRhs := &Point{}, &Point{}
64
65 checkLhs.Add(B, B)
66 tmpP2 := new(projP2).FromP3(B)
67 tmpP1xP1 := new(projP1xP1).Double(tmpP2)
68 checkRhs.fromP1xP1(tmpP1xP1)
69 if checkLhs.Equal(checkRhs) != 1 {
70 t.Error("B + B != [2]B")
71 }
72 checkOnCurve(t, checkLhs, checkRhs)
73
74 checkLhs.Subtract(B, B)
75 Bneg := new(Point).Negate(B)
76 checkRhs.Add(B, Bneg)
77 if checkLhs.Equal(checkRhs) != 1 {
78 t.Error("B - B != B + (-B)")
79 }
80 if I.Equal(checkLhs) != 1 {
81 t.Error("B - B != 0")
82 }
83 if I.Equal(checkRhs) != 1 {
84 t.Error("B + (-B) != 0")
85 }
86 checkOnCurve(t, checkLhs, checkRhs, Bneg)
87 }
88
89 func TestComparable(t *testing.T) {
90 if reflect.TypeOf(Point{}).Comparable() {
91 t.Error("Point is unexpectedly comparable")
92 }
93 }
94
95 func TestInvalidEncodings(t *testing.T) {
96
97 invalid := "efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"
98 p := NewGeneratorPoint()
99 if out, err := p.SetBytes(decodeHex(invalid)); err == nil {
100 t.Error("expected error for invalid point")
101 } else if out != nil {
102 t.Error("SetBytes did not return nil on an invalid encoding")
103 } else if p.Equal(B) != 1 {
104 t.Error("the Point was modified while decoding an invalid encoding")
105 }
106 checkOnCurve(t, p)
107 }
108
109 func TestNonCanonicalPoints(t *testing.T) {
110 type test struct {
111 name string
112 encoding, canonical string
113 }
114 tests := []test{
115
116
117 {
118 "y=1,sign-",
119 "0100000000000000000000000000000000000000000000000000000000000080",
120 "0100000000000000000000000000000000000000000000000000000000000000",
121 },
122 {
123 "y=p+1,sign-",
124 "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
125 "0100000000000000000000000000000000000000000000000000000000000000",
126 },
127 {
128 "y=p-1,sign-",
129 "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
130 "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
131 },
132
133
134 {
135 "y=p,sign+",
136 "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
137 "0000000000000000000000000000000000000000000000000000000000000000",
138 },
139 {
140 "y=p,sign-",
141 "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
142 "0000000000000000000000000000000000000000000000000000000000000080",
143 },
144 {
145 "y=p+1,sign+",
146 "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
147 "0100000000000000000000000000000000000000000000000000000000000000",
148 },
149
150
151 {
152 "y=p+3,sign+",
153 "f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
154 "0300000000000000000000000000000000000000000000000000000000000000",
155 },
156 {
157 "y=p+3,sign-",
158 "f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
159 "0300000000000000000000000000000000000000000000000000000000000080",
160 },
161 {
162 "y=p+4,sign+",
163 "f1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
164 "0400000000000000000000000000000000000000000000000000000000000000",
165 },
166 {
167 "y=p+4,sign-",
168 "f1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
169 "0400000000000000000000000000000000000000000000000000000000000080",
170 },
171 {
172 "y=p+5,sign+",
173 "f2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
174 "0500000000000000000000000000000000000000000000000000000000000000",
175 },
176 {
177 "y=p+5,sign-",
178 "f2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
179 "0500000000000000000000000000000000000000000000000000000000000080",
180 },
181 {
182 "y=p+6,sign+",
183 "f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
184 "0600000000000000000000000000000000000000000000000000000000000000",
185 },
186 {
187 "y=p+6,sign-",
188 "f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
189 "0600000000000000000000000000000000000000000000000000000000000080",
190 },
191
192
193 {
194 "y=p+9,sign+",
195 "f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
196 "0900000000000000000000000000000000000000000000000000000000000000",
197 },
198 {
199 "y=p+9,sign-",
200 "f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
201 "0900000000000000000000000000000000000000000000000000000000000080",
202 },
203 {
204 "y=p+10,sign+",
205 "f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
206 "0a00000000000000000000000000000000000000000000000000000000000000",
207 },
208 {
209 "y=p+10,sign-",
210 "f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
211 "0a00000000000000000000000000000000000000000000000000000000000080",
212 },
213
214
215
216 {
217 "y=p+14,sign+",
218 "fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
219 "0e00000000000000000000000000000000000000000000000000000000000000",
220 },
221 {
222 "y=p+14,sign-",
223 "fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
224 "0e00000000000000000000000000000000000000000000000000000000000080",
225 },
226 {
227 "y=p+15,sign+",
228 "fcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
229 "0f00000000000000000000000000000000000000000000000000000000000000",
230 },
231 {
232 "y=p+15,sign-",
233 "fcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
234 "0f00000000000000000000000000000000000000000000000000000000000080",
235 },
236 {
237 "y=p+16,sign+",
238 "fdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
239 "1000000000000000000000000000000000000000000000000000000000000000",
240 },
241 {
242 "y=p+16,sign-",
243 "fdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
244 "1000000000000000000000000000000000000000000000000000000000000080",
245 },
246
247 {
248 "y=p+18,sign+",
249 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
250 "1200000000000000000000000000000000000000000000000000000000000000",
251 },
252 {
253 "y=p+18,sign-",
254 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
255 "1200000000000000000000000000000000000000000000000000000000000080",
256 },
257 }
258 for _, tt := range tests {
259 t.Run(tt.name, func(t *testing.T) {
260 p1, err := new(Point).SetBytes(decodeHex(tt.encoding))
261 if err != nil {
262 t.Fatalf("error decoding non-canonical point: %v", err)
263 }
264 p2, err := new(Point).SetBytes(decodeHex(tt.canonical))
265 if err != nil {
266 t.Fatalf("error decoding canonical point: %v", err)
267 }
268 if p1.Equal(p2) != 1 {
269 t.Errorf("equivalent points are not equal: %v, %v", p1, p2)
270 }
271 if encoding := hex.EncodeToString(p1.Bytes()); encoding != tt.canonical {
272 t.Errorf("re-encoding does not match canonical; got %q, expected %q", encoding, tt.canonical)
273 }
274 checkOnCurve(t, p1, p2)
275 })
276 }
277 }
278
279 func decodeHex(s string) []byte {
280 b, err := hex.DecodeString(s)
281 if err != nil {
282 panic(err)
283 }
284 return b
285 }
286
287 func BenchmarkEncodingDecoding(b *testing.B) {
288 p := new(Point).Set(dalekScalarBasepoint)
289 for i := 0; i < b.N; i++ {
290 buf := p.Bytes()
291 _, err := p.SetBytes(buf)
292 if err != nil {
293 b.Fatal(err)
294 }
295 }
296 }
297
View as plain text