field_test.go raw
1 // Copyright (c) 2013-2016 The btcsuite developers
2 // Copyright (c) 2013-2016 Dave Collins
3 // Use of this source code is governed by an ISC
4 // license that can be found in the LICENSE file.
5
6 package btcec
7
8 import (
9 "math/rand"
10 "testing"
11
12 "next.orly.dev/pkg/nostr/encoders/hex"
13 "next.orly.dev/pkg/lol/chk"
14 )
15
16 // TestIsZero ensures that checking if a field IsZero works as expected.
17 func TestIsZero(t *testing.T) {
18 f := new(FieldVal)
19 if !f.IsZero() {
20 t.Errorf(
21 "new field value is not zero - got %v (rawints %x)", f,
22 f.String(),
23 )
24 }
25 f.SetInt(1)
26 if f.IsZero() {
27 t.Errorf(
28 "field claims it's zero when it's not - got %v "+
29 "(raw rawints %x)", f, f.String(),
30 )
31 }
32 f.Zero()
33 if !f.IsZero() {
34 t.Errorf(
35 "field claims it's not zero when it is - got %v "+
36 "(raw rawints %x)", f, f.String(),
37 )
38 }
39 }
40
41 // TestStringer ensures the stringer returns the appropriate hex string.
42 func TestStringer(t *testing.T) {
43 tests := []struct {
44 in string
45 expected string
46 }{
47 {
48 "0",
49 "0000000000000000000000000000000000000000000000000000000000000000",
50 },
51 {
52 "1",
53 "0000000000000000000000000000000000000000000000000000000000000001",
54 },
55 {
56 "a",
57 "000000000000000000000000000000000000000000000000000000000000000a",
58 },
59 {
60 "b",
61 "000000000000000000000000000000000000000000000000000000000000000b",
62 },
63 {
64 "c",
65 "000000000000000000000000000000000000000000000000000000000000000c",
66 },
67 {
68 "d",
69 "000000000000000000000000000000000000000000000000000000000000000d",
70 },
71 {
72 "e",
73 "000000000000000000000000000000000000000000000000000000000000000e",
74 },
75 {
76 "f",
77 "000000000000000000000000000000000000000000000000000000000000000f",
78 },
79 {
80 "f0",
81 "00000000000000000000000000000000000000000000000000000000000000f0",
82 },
83 // 2^26-1
84 {
85 "3ffffff",
86 "0000000000000000000000000000000000000000000000000000000003ffffff",
87 },
88 // 2^32-1
89 {
90 "ffffffff",
91 "00000000000000000000000000000000000000000000000000000000ffffffff",
92 },
93 // 2^64-1
94 {
95 "ffffffffffffffff",
96 "000000000000000000000000000000000000000000000000ffffffffffffffff",
97 },
98 // 2^96-1
99 {
100 "ffffffffffffffffffffffff",
101 "0000000000000000000000000000000000000000ffffffffffffffffffffffff",
102 },
103 // 2^128-1
104 {
105 "ffffffffffffffffffffffffffffffff",
106 "00000000000000000000000000000000ffffffffffffffffffffffffffffffff",
107 },
108 // 2^160-1
109 {
110 "ffffffffffffffffffffffffffffffffffffffff",
111 "000000000000000000000000ffffffffffffffffffffffffffffffffffffffff",
112 },
113 // 2^192-1
114 {
115 "ffffffffffffffffffffffffffffffffffffffffffffffff",
116 "0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff",
117 },
118 // 2^224-1
119 {
120 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
121 "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
122 },
123 // 2^256-4294968273 (the btcec prime, so should result in 0)
124 {
125 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
126 "0000000000000000000000000000000000000000000000000000000000000000",
127 },
128 // 2^256-4294968274 (the secp256k1 prime+1, so should result in 1)
129 {
130 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
131 "0000000000000000000000000000000000000000000000000000000000000001",
132 },
133
134 // Invalid hex
135 {
136 "g",
137 "0000000000000000000000000000000000000000000000000000000000000000",
138 },
139 {
140 "1h",
141 "0000000000000000000000000000000000000000000000000000000000000000",
142 },
143 {
144 "i1",
145 "0000000000000000000000000000000000000000000000000000000000000000",
146 },
147 }
148 t.Logf("Running %d tests", len(tests))
149 for i, test := range tests {
150 f := setHex(test.in)
151 result := f.String()
152 if result != test.expected {
153 t.Errorf(
154 "FieldVal.String #%d wrong result\ngot: %v\n"+
155 "want: %v", i, result, test.expected,
156 )
157 continue
158 }
159 }
160 }
161
162 // TestNormalize ensures that normalizing the internal field words works as
163 // expected.
164 func TestNormalize(t *testing.T) {
165 tests := []struct {
166 raw [10]uint32 // Intentionally denormalized value
167 normalized [10]uint32 // Normalized form of the raw value
168 }{
169 {
170 [10]uint32{0x00000005, 0, 0, 0, 0, 0, 0, 0, 0, 0},
171 [10]uint32{0x00000005, 0, 0, 0, 0, 0, 0, 0, 0, 0},
172 },
173 // 2^26
174 {
175 [10]uint32{0x04000000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0},
176 [10]uint32{0x00000000, 0x1, 0, 0, 0, 0, 0, 0, 0, 0},
177 },
178 // 2^26 + 1
179 {
180 [10]uint32{0x04000001, 0x0, 0, 0, 0, 0, 0, 0, 0, 0},
181 [10]uint32{0x00000001, 0x1, 0, 0, 0, 0, 0, 0, 0, 0},
182 },
183 // 2^32 - 1
184 {
185 [10]uint32{0xffffffff, 0x00, 0, 0, 0, 0, 0, 0, 0, 0},
186 [10]uint32{0x03ffffff, 0x3f, 0, 0, 0, 0, 0, 0, 0, 0},
187 },
188 // 2^32
189 {
190 [10]uint32{0x04000000, 0x3f, 0, 0, 0, 0, 0, 0, 0, 0},
191 [10]uint32{0x00000000, 0x40, 0, 0, 0, 0, 0, 0, 0, 0},
192 },
193 // 2^32 + 1
194 {
195 [10]uint32{0x04000001, 0x3f, 0, 0, 0, 0, 0, 0, 0, 0},
196 [10]uint32{0x00000001, 0x40, 0, 0, 0, 0, 0, 0, 0, 0},
197 },
198 // 2^64 - 1
199 {
200 [10]uint32{0xffffffff, 0xffffffc0, 0xfc0, 0, 0, 0, 0, 0, 0, 0},
201 [10]uint32{0x03ffffff, 0x03ffffff, 0xfff, 0, 0, 0, 0, 0, 0, 0},
202 },
203 // 2^64
204 {
205 [10]uint32{0x04000000, 0x03ffffff, 0x0fff, 0, 0, 0, 0, 0, 0, 0},
206 [10]uint32{0x00000000, 0x00000000, 0x1000, 0, 0, 0, 0, 0, 0, 0},
207 },
208 // 2^64 + 1
209 {
210 [10]uint32{0x04000001, 0x03ffffff, 0x0fff, 0, 0, 0, 0, 0, 0, 0},
211 [10]uint32{0x00000001, 0x00000000, 0x1000, 0, 0, 0, 0, 0, 0, 0},
212 },
213 // 2^96 - 1
214 {
215 [10]uint32{
216 0xffffffff, 0xffffffc0, 0xffffffc0, 0x3ffc0, 0, 0, 0, 0,
217 0, 0,
218 },
219 [10]uint32{
220 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x3ffff, 0, 0, 0, 0,
221 0, 0,
222 },
223 },
224 // 2^96
225 {
226 [10]uint32{
227 0x04000000, 0x03ffffff, 0x03ffffff, 0x3ffff, 0, 0, 0, 0,
228 0, 0,
229 },
230 [10]uint32{
231 0x00000000, 0x00000000, 0x00000000, 0x40000, 0, 0, 0, 0,
232 0, 0,
233 },
234 },
235 // 2^128 - 1
236 {
237 [10]uint32{
238 0xffffffff, 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffc0,
239 0, 0, 0, 0, 0,
240 },
241 [10]uint32{
242 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0xffffff,
243 0, 0, 0, 0, 0,
244 },
245 },
246 // 2^128
247 {
248 [10]uint32{
249 0x04000000, 0x03ffffff, 0x03ffffff, 0x03ffffff,
250 0x0ffffff, 0, 0, 0, 0, 0,
251 },
252 [10]uint32{
253 0x00000000, 0x00000000, 0x00000000, 0x00000000,
254 0x1000000, 0, 0, 0, 0, 0,
255 },
256 },
257 // 2^256 - 4294968273 (secp256k1 prime)
258 {
259 [10]uint32{
260 0xfffffc2f, 0xffffff80, 0xffffffc0, 0xffffffc0,
261 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffffc0,
262 0xffffffc0, 0x3fffc0,
263 },
264 [10]uint32{
265 0x00000000, 0x00000000, 0x00000000, 0x00000000,
266 0x00000000, 0x00000000, 0x00000000, 0x00000000,
267 0x00000000, 0x000000,
268 },
269 },
270 // Prime larger than P where both first and second words are larger
271 // than P's first and second words
272 {
273 [10]uint32{
274 0xfffffc30, 0xffffff86, 0xffffffc0, 0xffffffc0,
275 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffffc0,
276 0xffffffc0, 0x3fffc0,
277 },
278 [10]uint32{
279 0x00000001, 0x00000006, 0x00000000, 0x00000000,
280 0x00000000, 0x00000000, 0x00000000, 0x00000000,
281 0x00000000, 0x000000,
282 },
283 },
284 // Prime larger than P where only the second word is larger
285 // than P's second words.
286 {
287 [10]uint32{
288 0xfffffc2a, 0xffffff87, 0xffffffc0, 0xffffffc0,
289 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffffc0,
290 0xffffffc0, 0x3fffc0,
291 },
292 [10]uint32{
293 0x03fffffb, 0x00000006, 0x00000000, 0x00000000,
294 0x00000000, 0x00000000, 0x00000000, 0x00000000,
295 0x00000000, 0x000000,
296 },
297 },
298 // 2^256 - 1
299 {
300 [10]uint32{
301 0xffffffff, 0xffffffc0, 0xffffffc0, 0xffffffc0,
302 0xffffffc0, 0xffffffc0, 0xffffffc0, 0xffffffc0,
303 0xffffffc0, 0x3fffc0,
304 },
305 [10]uint32{
306 0x000003d0, 0x00000040, 0x00000000, 0x00000000,
307 0x00000000, 0x00000000, 0x00000000, 0x00000000,
308 0x00000000, 0x000000,
309 },
310 },
311 // Prime with field representation such that the initial
312 // reduction does not result in a carry to bit 256.
313 //
314 // 2^256 - 4294968273 (secp256k1 prime)
315 {
316 [10]uint32{
317 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
318 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
319 0x03ffffff, 0x003fffff,
320 },
321 [10]uint32{
322 0x00000000, 0x00000000, 0x00000000, 0x00000000,
323 0x00000000, 0x00000000, 0x00000000, 0x00000000,
324 0x00000000, 0x00000000,
325 },
326 },
327 // Prime larger than P that reduces to a value which is still
328 // larger than P when it has a magnitude of 1 due to its first
329 // word and does not result in a carry to bit 256.
330 //
331 // 2^256 - 4294968272 (secp256k1 prime + 1)
332 {
333 [10]uint32{
334 0x03fffc30, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
335 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
336 0x03ffffff, 0x003fffff,
337 },
338 [10]uint32{
339 0x00000001, 0x00000000, 0x00000000, 0x00000000,
340 0x00000000, 0x00000000, 0x00000000, 0x00000000,
341 0x00000000, 0x00000000,
342 },
343 },
344 // Prime larger than P that reduces to a value which is still
345 // larger than P when it has a magnitude of 1 due to its second
346 // word and does not result in a carry to bit 256.
347 //
348 // 2^256 - 4227859409 (secp256k1 prime + 0x4000000)
349 {
350 [10]uint32{
351 0x03fffc2f, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
352 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
353 0x03ffffff, 0x003fffff,
354 },
355 [10]uint32{
356 0x00000000, 0x00000001, 0x00000000, 0x00000000,
357 0x00000000, 0x00000000, 0x00000000, 0x00000000,
358 0x00000000, 0x00000000,
359 },
360 },
361 // Prime larger than P that reduces to a value which is still
362 // larger than P when it has a magnitude of 1 due to a carry to
363 // bit 256, but would not be without the carry. These values
364 // come from the fact that P is 2^256 - 4294968273 and 977 is
365 // the low order word in the internal field representation.
366 //
367 // 2^256 * 5 - ((4294968273 - (977+1)) * 4)
368 {
369 [10]uint32{
370 0x03ffffff, 0x03fffeff, 0x03ffffff, 0x03ffffff,
371 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
372 0x03ffffff, 0x0013fffff,
373 },
374 [10]uint32{
375 0x00001314, 0x00000040, 0x00000000, 0x00000000,
376 0x00000000, 0x00000000, 0x00000000, 0x00000000,
377 0x00000000, 0x000000000,
378 },
379 },
380 // Prime larger than P that reduces to a value which is still
381 // larger than P when it has a magnitude of 1 due to both a
382 // carry to bit 256 and the first word.
383 {
384 [10]uint32{
385 0x03fffc30, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
386 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
387 0x07ffffff, 0x003fffff,
388 },
389 [10]uint32{
390 0x00000001, 0x00000000, 0x00000000, 0x00000000,
391 0x00000000, 0x00000000, 0x00000000, 0x00000000,
392 0x00000000, 0x00000001,
393 },
394 },
395 // Prime larger than P that reduces to a value which is still
396 // larger than P when it has a magnitude of 1 due to both a
397 // carry to bit 256 and the second word.
398 //
399 {
400 [10]uint32{
401 0x03fffc2f, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
402 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x3ffffff,
403 0x07ffffff, 0x003fffff,
404 },
405 [10]uint32{
406 0x00000000, 0x00000001, 0x00000000, 0x00000000,
407 0x00000000, 0x00000000, 0x00000000, 0x0000000,
408 0x00000000, 0x00000001,
409 },
410 },
411 // Prime larger than P that reduces to a value which is still
412 // larger than P when it has a magnitude of 1 due to a carry to
413 // bit 256 and the first and second words.
414 //
415 {
416 [10]uint32{
417 0x03fffc30, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
418 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
419 0x07ffffff, 0x003fffff,
420 },
421 [10]uint32{
422 0x00000001, 0x00000001, 0x00000000, 0x00000000,
423 0x00000000, 0x00000000, 0x00000000, 0x00000000,
424 0x00000000, 0x00000001,
425 },
426 },
427 }
428
429 t.Logf("Running %d tests", len(tests))
430 for range tests {
431 // TODO(roasbeef): can't access internal state
432 /*f := new(FieldVal)
433 f.n = test.raw
434 f.Normalize()
435 if !reflect.DeepEqual(f.n, test.normalized) {
436 t.Errorf("FieldVal.Normalize #%d wrong result\n"+
437 "got: %x\nwant: %x", i, f.n, test.normalized)
438 continue
439 }*/
440 }
441 }
442
443 // TestIsOdd ensures that checking if a field value IsOdd works as expected.
444 func TestIsOdd(t *testing.T) {
445 tests := []struct {
446 in string // hex encoded value
447 expected bool // expected oddness
448 }{
449 {"0", false},
450 {"1", true},
451 {"2", false},
452 // 2^32 - 1
453 {"ffffffff", true},
454 // 2^64 - 2
455 {"fffffffffffffffe", false},
456 // secp256k1 prime
457 {
458 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
459 true,
460 },
461 }
462
463 t.Logf("Running %d tests", len(tests))
464 for i, test := range tests {
465 f := setHex(test.in)
466 result := f.IsOdd()
467 if result != test.expected {
468 t.Errorf(
469 "FieldVal.IsOdd #%d wrong result\n"+
470 "got: %v\nwant: %v", i, result, test.expected,
471 )
472 continue
473 }
474 }
475 }
476
477 // TestEquals ensures that checking two field values for equality via Equals
478 // works as expected.
479 func TestEquals(t *testing.T) {
480 tests := []struct {
481 in1 string // hex encoded value
482 in2 string // hex encoded value
483 expected bool // expected equality
484 }{
485 {"0", "0", true},
486 {"0", "1", false},
487 {"1", "0", false},
488 // 2^32 - 1 == 2^32 - 1?
489 {"ffffffff", "ffffffff", true},
490 // 2^64 - 1 == 2^64 - 2?
491 {"ffffffffffffffff", "fffffffffffffffe", false},
492 // 0 == prime (mod prime)?
493 {
494 "0",
495 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
496 true,
497 },
498 // 1 == prime+1 (mod prime)?
499 {
500 "1",
501 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
502 true,
503 },
504 }
505
506 t.Logf("Running %d tests", len(tests))
507 for i, test := range tests {
508 f := setHex(test.in1).Normalize()
509 f2 := setHex(test.in2).Normalize()
510 result := f.Equals(f2)
511 if result != test.expected {
512 t.Errorf(
513 "FieldVal.Equals #%d wrong result\n"+
514 "got: %v\nwant: %v", i, result, test.expected,
515 )
516 continue
517 }
518 }
519 }
520
521 // TestNegate ensures that negating field values via Negate works as expected.
522 func TestNegate(t *testing.T) {
523 tests := []struct {
524 in string // hex encoded value
525 expected string // expected hex encoded value
526 }{
527 // secp256k1 prime (aka 0)
528 {"0", "0"},
529 {
530 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
531 "0",
532 },
533 {
534 "0",
535 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
536 },
537 // secp256k1 prime-1
538 {
539 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
540 "1",
541 },
542 {
543 "1",
544 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
545 },
546 // secp256k1 prime-2
547 {
548 "2",
549 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
550 },
551 {
552 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
553 "2",
554 },
555 // Random sampling
556 {
557 "b3d9aac9c5e43910b4385b53c7e78c21d4cd5f8e683c633aed04c233efc2e120",
558 "4c2655363a1bc6ef4bc7a4ac381873de2b32a07197c39cc512fb3dcb103d1b0f",
559 },
560 {
561 "f8a85984fee5a12a7c8dd08830d83423c937d77c379e4a958e447a25f407733f",
562 "757a67b011a5ed583722f77cf27cbdc36c82883c861b56a71bb85d90bf888f0",
563 },
564 {
565 "45ee6142a7fda884211e93352ed6cb2807800e419533be723a9548823ece8312",
566 "ba119ebd5802577bdee16ccad12934d7f87ff1be6acc418dc56ab77cc131791d",
567 },
568 {
569 "53c2a668f07e411a2e473e1c3b6dcb495dec1227af27673761d44afe5b43d22b",
570 "ac3d59970f81bee5d1b8c1e3c49234b6a213edd850d898c89e2bb500a4bc2a04",
571 },
572 }
573 t.Logf("Running %d tests", len(tests))
574 for i, test := range tests {
575 f := setHex(test.in).Normalize()
576 expected := setHex(test.expected).Normalize()
577 result := f.Negate(1).Normalize()
578 if !result.Equals(expected) {
579 t.Errorf(
580 "FieldVal.Negate #%d wrong result\n"+
581 "got: %v\nwant: %v", i, result, expected,
582 )
583 continue
584 }
585 }
586 }
587
588 // TestFieldAddInt ensures that adding an integer to field values via AddInt
589 // works as expected.
590 func TestFieldAddInt(t *testing.T) {
591 tests := []struct {
592 name string // test description
593 in1 string // hex encoded value
594 in2 uint16 // unsigned integer to add to the value above
595 expected string // expected hex encoded value
596 }{
597 {
598 name: "zero + one",
599 in1: "0",
600 in2: 1,
601 expected: "1",
602 }, {
603 name: "one + zero",
604 in1: "1",
605 in2: 0,
606 expected: "1",
607 }, {
608 name: "one + one",
609 in1: "1",
610 in2: 1,
611 expected: "2",
612 }, {
613 name: "secp256k1 prime-1 + 1",
614 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
615 in2: 1,
616 expected: "0",
617 }, {
618 name: "secp256k1 prime + 1",
619 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
620 in2: 1,
621 expected: "1",
622 }, {
623 name: "random sampling #1",
624 in1: "ff95ad9315aff04ab4af0ce673620c7145dc85d03bab5ba4b09ca2c4dec2d6c1",
625 in2: 0x10f,
626 expected: "ff95ad9315aff04ab4af0ce673620c7145dc85d03bab5ba4b09ca2c4dec2d7d0",
627 }, {
628 name: "random sampling #2",
629 in1: "44bdae6b772e7987941f1ba314e6a5b7804a4c12c00961b57d20f41deea9cecf",
630 in2: 0x3196,
631 expected: "44bdae6b772e7987941f1ba314e6a5b7804a4c12c00961b57d20f41deeaa0065",
632 }, {
633 name: "random sampling #3",
634 in1: "88c3ecae67b591935fb1f6a9499c35315ffad766adca665c50b55f7105122c9c",
635 in2: 0x966f,
636 expected: "88c3ecae67b591935fb1f6a9499c35315ffad766adca665c50b55f710512c30b",
637 }, {
638 name: "random sampling #4",
639 in1: "8523e9edf360ca32a95aae4e57fcde5a542b471d08a974d94ea0ee09a015e2a6",
640 in2: 0xc54,
641 expected: "8523e9edf360ca32a95aae4e57fcde5a542b471d08a974d94ea0ee09a015eefa",
642 },
643 }
644 for _, test := range tests {
645 f := setHex(test.in1).Normalize()
646 expected := setHex(test.expected).Normalize()
647 result := f.AddInt(test.in2).Normalize()
648 if !result.Equals(expected) {
649 t.Errorf(
650 "%s: wrong result -- got: %v -- want: %v", test.name,
651 result, expected,
652 )
653 continue
654 }
655 }
656 }
657
658 // TestFieldAdd ensures that adding two field values together via Add and Add2
659 // works as expected.
660 func TestFieldAdd(t *testing.T) {
661 tests := []struct {
662 name string // test description
663 in1 string // first hex encoded value
664 in2 string // second hex encoded value to add
665 expected string // expected hex encoded value
666 }{
667 {
668 name: "zero + one",
669 in1: "0",
670 in2: "1",
671 expected: "1",
672 }, {
673 name: "one + zero",
674 in1: "1",
675 in2: "0",
676 expected: "1",
677 }, {
678 name: "secp256k1 prime-1 + 1",
679 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
680 in2: "1",
681 expected: "0",
682 }, {
683 name: "secp256k1 prime + 1",
684 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
685 in2: "1",
686 expected: "1",
687 }, {
688 name: "random sampling #1",
689 in1: "2b2012f975404e5065b4292fb8bed0a5d315eacf24c74d8b27e73bcc5430edcc",
690 in2: "2c3cefa4e4753e8aeec6ac4c12d99da4d78accefda3b7885d4c6bab46c86db92",
691 expected: "575d029e59b58cdb547ad57bcb986e4aaaa0b7beff02c610fcadf680c0b7c95e",
692 }, {
693 name: "random sampling #2",
694 in1: "8131e8722fe59bb189692b96c9f38de92885730f1dd39ab025daffb94c97f79c",
695 in2: "ff5454b765f0aab5f0977dcc629becc84cabeb9def48e79c6aadb2622c490fa9",
696 expected: "80863d2995d646677a00a9632c8f7ab175315ead0d1c824c9088b21c78e10b16",
697 }, {
698 name: "random sampling #3",
699 in1: "c7c95e93d0892b2b2cdd77e80eb646ea61be7a30ac7e097e9f843af73fad5c22",
700 in2: "3afe6f91a74dfc1c7f15c34907ee981656c37236d946767dd53ccad9190e437c",
701 expected: "2c7ce2577d72747abf33b3116a4df00b881ec6785c47ffc74c105d158bba36f",
702 }, {
703 name: "random sampling #4",
704 in1: "fd1c26f6a23381e5d785ba889494ec059369b888ad8431cd67d8c934b580dbe1",
705 in2: "a475aa5a31dcca90ef5b53c097d9133d6b7117474b41e7877bb199590fc0489c",
706 expected: "a191d150d4104c76c6e10e492c6dff42fedacfcff8c61954e38a628ec541284e",
707 }, {
708 name: "random sampling #5",
709 in1: "ad82b8d1cc136e23e9fd77fe2c7db1fe5a2ecbfcbde59ab3529758334f862d28",
710 in2: "4d6a4e95d6d61f4f46b528bebe152d408fd741157a28f415639347a84f6f574b",
711 expected: "faed0767a2e98d7330b2a0bcea92df3eea060d12380e8ec8b62a9fdb9ef58473",
712 }, {
713 name: "random sampling #6",
714 in1: "f3f43a2540054a86e1df98547ec1c0e157b193e5350fb4a3c3ea214b228ac5e7",
715 in2: "25706572592690ea3ddc951a1b48b504a4c83dc253756e1b96d56fdfb3199522",
716 expected: "19649f97992bdb711fbc2d6e9a0a75e5fc79d1a7888522bf5abf912bd5a45eda",
717 }, {
718 name: "random sampling #7",
719 in1: "6915bb94eef13ff1bb9b2633d997e13b9b1157c713363cc0e891416d6734f5b8",
720 in2: "11f90d6ac6fe1c4e8900b1c85fb575c251ec31b9bc34b35ada0aea1c21eded22",
721 expected: "7b0ec8ffb5ef5c40449bd7fc394d56fdecfd8980cf6af01bc29c2b898922e2da",
722 }, {
723 name: "random sampling #8",
724 in1: "48b0c9eae622eed9335b747968544eb3e75cb2dc8128388f948aa30f88cabde4",
725 in2: "0989882b52f85f9d524a3a3061a0e01f46d597839d2ba637320f4b9510c8d2d5",
726 expected: "523a5216391b4e7685a5aea9c9f52ed32e324a601e53dec6c699eea4999390b9",
727 },
728 }
729 for _, test := range tests {
730 // Parse test hex.
731 f1 := setHex(test.in1).Normalize()
732 f2 := setHex(test.in2).Normalize()
733 expected := setHex(test.expected).Normalize()
734 // Ensure adding the two values with the result going to another
735 // variable produces the expected result.
736 result := new(FieldVal).Add2(f1, f2).Normalize()
737 if !result.Equals(expected) {
738 t.Errorf(
739 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
740 result, expected,
741 )
742 continue
743 }
744 // Ensure adding the value to an existing field value produces the
745 // expected result.
746 f1.Add(f2).Normalize()
747 if !f1.Equals(expected) {
748 t.Errorf(
749 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
750 f1, expected,
751 )
752 continue
753 }
754 }
755 }
756
757 // TestFieldMulInt ensures that multiplying an integer to field values via
758 // MulInt works as expected.
759 func TestFieldMulInt(t *testing.T) {
760 tests := []struct {
761 name string // test description
762 in1 string // hex encoded value
763 in2 uint8 // unsigned integer to multiply with value above
764 expected string // expected hex encoded value
765 }{
766 {
767 name: "zero * zero",
768 in1: "0",
769 in2: 0,
770 expected: "0",
771 }, {
772 name: "one * zero",
773 in1: "1",
774 in2: 0,
775 expected: "0",
776 }, {
777 name: "zero * one",
778 in1: "0",
779 in2: 1,
780 expected: "0",
781 }, {
782 name: "one * one",
783 in1: "1",
784 in2: 1,
785 expected: "1",
786 }, {
787 name: "secp256k1 prime-1 * 2",
788 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
789 in2: 2,
790 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
791 }, {
792 name: "secp256k1 prime * 3",
793 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
794 in2: 3,
795 expected: "0",
796 }, {
797 name: "secp256k1 prime-1 * 8",
798 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
799 in2: 8,
800 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc27",
801 }, {
802 // Random samples for first value. The second value is limited
803 // to 8 since that is the maximum int used in the elliptic curve
804 // calculations.
805 name: "random sampling #1",
806 in1: "b75674dc9180d306c692163ac5e089f7cef166af99645c0c23568ab6d967288a",
807 in2: 6,
808 expected: "4c06bd2b6904f228a76c8560a3433bced9a8681d985a2848d407404d186b0280",
809 }, {
810 name: "random sampling #2",
811 in1: "54873298ac2b5ba8591c125ae54931f5ea72040aee07b208d6135476fb5b9c0e",
812 in2: 3,
813 expected: "fd9597ca048212f90b543710afdb95e1bf560c20ca17161a8239fd64f212d42a",
814 }, {
815 name: "random sampling #3",
816 in1: "7c30fbd363a74c17e1198f56b090b59bbb6c8755a74927a6cba7a54843506401",
817 in2: 5,
818 expected: "6cf4eb20f2447c77657fccb172d38c0aa91ea4ac446dc641fa463a6b5091fba7",
819 }, {
820 name: "random sampling #3",
821 in1: "fb4529be3e027a3d1587d8a500b72f2d312e3577340ef5175f96d113be4c2ceb",
822 in2: 8,
823 expected: "da294df1f013d1e8ac3ec52805b979698971abb9a077a8bafcb688a4f261820f",
824 },
825 }
826 for _, test := range tests {
827 f := setHex(test.in1).Normalize()
828 expected := setHex(test.expected).Normalize()
829 result := f.MulInt(test.in2).Normalize()
830 if !result.Equals(expected) {
831 t.Errorf(
832 "%s: wrong result -- got: %v -- want: %v", test.name,
833 result, expected,
834 )
835 continue
836 }
837 }
838 }
839
840 // TestFieldMul ensures that multiplying two field values via Mul and Mul2 works
841 // as expected.
842 func TestFieldMul(t *testing.T) {
843 tests := []struct {
844 name string // test description
845 in1 string // first hex encoded value
846 in2 string // second hex encoded value to multiply with
847 expected string // expected hex encoded value
848 }{
849 {
850 name: "zero * zero",
851 in1: "0",
852 in2: "0",
853 expected: "0",
854 }, {
855 name: "one * zero",
856 in1: "1",
857 in2: "0",
858 expected: "0",
859 }, {
860 name: "zero * one",
861 in1: "0",
862 in2: "1",
863 expected: "0",
864 }, {
865 name: "one * one",
866 in1: "1",
867 in2: "1",
868 expected: "1",
869 }, {
870 name: "slightly over prime",
871 in1: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1ffff",
872 in2: "1000",
873 expected: "1ffff3d1",
874 }, {
875 name: "secp256k1 prime-1 * 2",
876 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
877 in2: "2",
878 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
879 }, {
880 name: "secp256k1 prime * 3",
881 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
882 in2: "3",
883 expected: "0",
884 }, {
885 name: "secp256k1 prime * 3",
886 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
887 in2: "8",
888 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc27",
889 }, {
890 name: "random sampling #1",
891 in1: "cfb81753d5ef499a98ecc04c62cb7768c2e4f1740032946db1c12e405248137e",
892 in2: "58f355ad27b4d75fb7db0442452e732c436c1f7c5a7c4e214fa9cc031426a7d3",
893 expected: "1018cd2d7c2535235b71e18db9cd98027386328d2fa6a14b36ec663c4c87282b",
894 }, {
895 name: "random sampling #2",
896 in1: "26e9d61d1cdf3920e9928e85fa3df3e7556ef9ab1d14ec56d8b4fc8ed37235bf",
897 in2: "2dfc4bbe537afee979c644f8c97b31e58be5296d6dbc460091eae630c98511cf",
898 expected: "da85f48da2dc371e223a1ae63bd30b7e7ee45ae9b189ac43ff357e9ef8cf107a",
899 }, {
900 name: "random sampling #3",
901 in1: "5db64ed5afb71646c8b231585d5b2bf7e628590154e0854c4c29920b999ff351",
902 in2: "279cfae5eea5d09ade8e6a7409182f9de40981bc31c84c3d3dfe1d933f152e9a",
903 expected: "2c78fbae91792dd0b157abe3054920049b1879a7cc9d98cfda927d83be411b37",
904 }, {
905 name: "random sampling #4",
906 in1: "b66dfc1f96820b07d2bdbd559c19319a3a73c97ceb7b3d662f4fe75ecb6819e6",
907 in2: "bf774aba43e3e49eb63a6e18037d1118152568f1a3ac4ec8b89aeb6ff8008ae1",
908 expected: "c4f016558ca8e950c21c3f7fc15f640293a979c7b01754ee7f8b3340d4902ebb",
909 },
910 }
911 for _, test := range tests {
912 f1 := setHex(test.in1).Normalize()
913 f2 := setHex(test.in2).Normalize()
914 expected := setHex(test.expected).Normalize()
915 // Ensure multiplying the two values with the result going to another
916 // variable produces the expected result.
917 result := new(FieldVal).Mul2(f1, f2).Normalize()
918 if !result.Equals(expected) {
919 t.Errorf(
920 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
921 result, expected,
922 )
923 continue
924 }
925 // Ensure multiplying the value to an existing field value produces the
926 // expected result.
927 f1.Mul(f2).Normalize()
928 if !f1.Equals(expected) {
929 t.Errorf(
930 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
931 f1, expected,
932 )
933 continue
934 }
935 }
936 }
937
938 // TestFieldSquare ensures that squaring field values via Square and SqualVal
939 // works as expected.
940 func TestFieldSquare(t *testing.T) {
941 tests := []struct {
942 name string // test description
943 in string // hex encoded value
944 expected string // expected hex encoded value
945 }{
946 {
947 name: "zero",
948 in: "0",
949 expected: "0",
950 }, {
951 name: "secp256k1 prime (direct val in with 0 out)",
952 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
953 expected: "0",
954 }, {
955 name: "secp256k1 prime (0 in with direct val out)",
956 in: "0",
957 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
958 }, {
959 name: "secp256k1 prime - 1",
960 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
961 expected: "1",
962 }, {
963 name: "secp256k1 prime - 2",
964 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
965 expected: "4",
966 }, {
967 name: "random sampling #1",
968 in: "b0ba920360ea8436a216128047aab9766d8faf468895eb5090fc8241ec758896",
969 expected: "133896b0b69fda8ce9f648b9a3af38f345290c9eea3cbd35bafcadf7c34653d3",
970 }, {
971 name: "random sampling #2",
972 in: "c55d0d730b1d0285a1599995938b042a756e6e8857d390165ffab480af61cbd5",
973 expected: "cd81758b3f5877cbe7e5b0a10cebfa73bcbf0957ca6453e63ee8954ab7780bee",
974 }, {
975 name: "random sampling #3",
976 in: "e89c1f9a70d93651a1ba4bca5b78658f00de65a66014a25544d3365b0ab82324",
977 expected: "39ffc7a43e5dbef78fd5d0354fb82c6d34f5a08735e34df29da14665b43aa1f",
978 }, {
979 name: "random sampling #4",
980 in: "7dc26186079d22bcbe1614aa20ae627e62d72f9be7ad1e99cac0feb438956f05",
981 expected: "bf86bcfc4edb3d81f916853adfda80c07c57745b008b60f560b1912f95bce8ae",
982 },
983 }
984 for _, test := range tests {
985 f := setHex(test.in).Normalize()
986 expected := setHex(test.expected).Normalize()
987 // Ensure squaring the value with the result going to another variable
988 // produces the expected result.
989 result := new(FieldVal).SquareVal(f).Normalize()
990 if !result.Equals(expected) {
991 t.Errorf(
992 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
993 result, expected,
994 )
995 continue
996 }
997 // Ensure self squaring an existing field value produces the expected
998 // result.
999 f.Square().Normalize()
1000 if !f.Equals(expected) {
1001 t.Errorf(
1002 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
1003 f, expected,
1004 )
1005 continue
1006 }
1007 }
1008 }
1009
1010 // TestInverse ensures that finding the multiplicative inverse via Inverse works
1011 // as expected.
1012 func TestInverse(t *testing.T) {
1013 tests := []struct {
1014 in string // hex encoded value
1015 expected string // expected hex encoded value
1016 }{
1017 // secp256k1 prime (aka 0)
1018 {"0", "0"},
1019 {
1020 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1021 "0",
1022 },
1023 {
1024 "0",
1025 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1026 },
1027 // secp256k1 prime-1
1028 {
1029 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1030 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1031 },
1032 // secp256k1 prime-2
1033 {
1034 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
1035 "7fffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffe17",
1036 },
1037 // Random sampling
1038 {
1039 "16fb970147a9acc73654d4be233cc48b875ce20a2122d24f073d29bd28805aca",
1040 "987aeb257b063df0c6d1334051c47092b6d8766c4bf10c463786d93f5bc54354",
1041 },
1042 {
1043 "69d1323ce9f1f7b3bd3c7320b0d6311408e30281e273e39a0d8c7ee1c8257919",
1044 "49340981fa9b8d3dad72de470b34f547ed9179c3953797d0943af67806f4bb6",
1045 },
1046 {
1047 "e0debf988ae098ecda07d0b57713e97c6d213db19753e8c95aa12a2fc1cc5272",
1048 "64f58077b68af5b656b413ea366863f7b2819f8d27375d9c4d9804135ca220c2",
1049 },
1050 {
1051 "dcd394f91f74c2ba16aad74a22bb0ed47fe857774b8f2d6c09e28bfb14642878",
1052 "fb848ec64d0be572a63c38fe83df5e7f3d032f60bf8c969ef67d36bf4ada22a9",
1053 },
1054 }
1055 t.Logf("Running %d tests", len(tests))
1056 for i, test := range tests {
1057 f := setHex(test.in).Normalize()
1058 expected := setHex(test.expected).Normalize()
1059 result := f.Inverse().Normalize()
1060 if !result.Equals(expected) {
1061 t.Errorf(
1062 "FieldVal.Inverse #%d wrong result\n"+
1063 "got: %v\nwant: %v", i, result, expected,
1064 )
1065 continue
1066 }
1067 }
1068 }
1069
1070 // randFieldVal returns a field value created from a random value generated by
1071 // the passed rng.
1072 func randFieldVal(t *testing.T, rng *rand.Rand) *FieldVal {
1073 t.Helper()
1074 var buf [32]byte
1075 if _, err := rng.Read(buf[:]); chk.T(err) {
1076 t.Fatalf("failed to read random: %v", err)
1077 }
1078 // Create and return both a big integer and a field value.
1079 var fv FieldVal
1080 fv.SetBytes(&buf)
1081 return &fv
1082 }
1083
1084 // TestFieldSquareRoot ensures that calculating the square root of field values
1085 // via SquareRootVal works as expected for edge cases.
1086 func TestFieldSquareRoot(t *testing.T) {
1087 tests := []struct {
1088 name string // test description
1089 in string // hex encoded value
1090 valid bool // whether or not the value has a square root
1091 want string // expected hex encoded value
1092 }{
1093 {
1094 name: "secp256k1 prime (as 0 in and out)",
1095 in: "0",
1096 valid: true,
1097 want: "0",
1098 }, {
1099 name: "secp256k1 prime (direct val with 0 out)",
1100 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1101 valid: true,
1102 want: "0",
1103 }, {
1104 name: "secp256k1 prime (as 0 in direct val out)",
1105 in: "0",
1106 valid: true,
1107 want: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1108 }, {
1109 name: "secp256k1 prime-1",
1110 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1111 valid: false,
1112 want: "0000000000000000000000000000000000000000000000000000000000000001",
1113 }, {
1114 name: "secp256k1 prime-2",
1115 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
1116 valid: false,
1117 want: "210c790573632359b1edb4302c117d8a132654692c3feeb7de3a86ac3f3b53f7",
1118 }, {
1119 name: "(secp256k1 prime-2)^2",
1120 in: "0000000000000000000000000000000000000000000000000000000000000004",
1121 valid: true,
1122 want: "0000000000000000000000000000000000000000000000000000000000000002",
1123 }, {
1124 name: "value 1",
1125 in: "0000000000000000000000000000000000000000000000000000000000000001",
1126 valid: true,
1127 want: "0000000000000000000000000000000000000000000000000000000000000001",
1128 }, {
1129 name: "value 2",
1130 in: "0000000000000000000000000000000000000000000000000000000000000002",
1131 valid: true,
1132 want: "210c790573632359b1edb4302c117d8a132654692c3feeb7de3a86ac3f3b53f7",
1133 }, {
1134 name: "random sampling 1",
1135 in: "16fb970147a9acc73654d4be233cc48b875ce20a2122d24f073d29bd28805aca",
1136 valid: false,
1137 want: "6a27dcfca440cf7930a967be533b9620e397f122787c53958aaa7da7ad3d89a4",
1138 }, {
1139 name: "square of random sampling 1",
1140 in: "f4a8c3738ace0a1c3abf77737ae737f07687b5e24c07a643398298bd96893a18",
1141 valid: true,
1142 want: "e90468feb8565338c9ab2b41dcc33b7478a31df5dedd2db0f8c2d641d77fa165",
1143 }, {
1144 name: "random sampling 2",
1145 in: "69d1323ce9f1f7b3bd3c7320b0d6311408e30281e273e39a0d8c7ee1c8257919",
1146 valid: true,
1147 want: "61f4a7348274a52d75dfe176b8e3aaff61c1c833b6678260ba73def0fb2ad148",
1148 }, {
1149 name: "random sampling 3",
1150 in: "e0debf988ae098ecda07d0b57713e97c6d213db19753e8c95aa12a2fc1cc5272",
1151 valid: false,
1152 want: "6e1cc9c311d33d901670135244f994b1ea39501f38002269b34ce231750cfbac",
1153 }, {
1154 name: "random sampling 4",
1155 in: "dcd394f91f74c2ba16aad74a22bb0ed47fe857774b8f2d6c09e28bfb14642878",
1156 valid: true,
1157 want: "72b22fe6f173f8bcb21898806142ed4c05428601256eafce5d36c1b08fb82bab",
1158 },
1159 }
1160 for _, test := range tests {
1161 input := setHex(test.in).Normalize()
1162 want := setHex(test.want).Normalize()
1163 // Calculate the square root and enusre the validity flag matches the
1164 // expected value.
1165 var result FieldVal
1166 isValid := result.SquareRootVal(input)
1167 if isValid != test.valid {
1168 t.Errorf(
1169 "%s: mismatched validity -- got %v, want %v", test.name,
1170 isValid, test.valid,
1171 )
1172 continue
1173 }
1174 // Ensure the calculated result matches the expected value.
1175 result.Normalize()
1176 if !result.Equals(want) {
1177 t.Errorf(
1178 "%s: d wrong result\ngot: %v\nwant: %v", test.name, result,
1179 want,
1180 )
1181 continue
1182 }
1183 }
1184 }
1185
1186 // hexToBytes converts the passed hex string into bytes and will panic if there
1187 // is an error. This is only provided for the hard-coded constants so errors in
1188 // the source code can be detected. It will only (and must only) be called with
1189 // hard-coded values.
1190 func hexToBytes(s string) []byte {
1191 b, err := hex.Dec(s)
1192 if err != nil {
1193 panic("invalid hex in source file: " + s)
1194 }
1195 return b
1196 }
1197