field_test.go raw
1 // Copyright (c) 2013-2016 The btcsuite developers
2 // Copyright (c) 2015-2022 The Decred developers
3 // Copyright (c) 2013-2022 Dave Collins
4 // Use of this source code is governed by an ISC
5 // license that can be found in the LICENSE file.
6
7 package secp256k1
8
9 import (
10 "fmt"
11 "math/big"
12 "math/rand"
13 "reflect"
14 "testing"
15 "time"
16
17 "next.orly.dev/pkg/nostr/encoders/hex"
18 "next.orly.dev/pkg/nostr/utils"
19 "next.orly.dev/pkg/lol/chk"
20 )
21
22 // SetHex decodes the passed big-endian hex string into the internal field value
23 // representation. Only the first 32-bytes are used.
24 //
25 // This is NOT constant time.
26 //
27 // The field value is returned to support chaining. This enables syntax like:
28 // f := new(FieldVal).SetHex("0abc").Add(1) so that f = 0x0abc + 1
29 func (f *FieldVal) SetHex(hexString string) *FieldVal {
30 if len(hexString)%2 != 0 {
31 hexString = "0" + hexString
32 }
33 bytes, _ := hex.Dec(hexString)
34 f.SetByteSlice(bytes)
35 return f
36 }
37
38 // randFieldVal returns a field value created from a random value generated by
39 // the passed rng.
40 func randFieldVal(t *testing.T, rng *rand.Rand) *FieldVal {
41 t.Helper()
42 var buf [32]byte
43 if _, err := rng.Read(buf[:]); chk.T(err) {
44 t.Fatalf("failed to read random: %v", err)
45 }
46 // Create and return a field value.
47 var fv FieldVal
48 fv.SetBytes(&buf)
49 return &fv
50 }
51
52 // randIntAndFieldVal returns a big integer and a field value both created from
53 // the same random value generated by the passed rng.
54 func randIntAndFieldVal(t *testing.T, rng *rand.Rand) (*big.Int, *FieldVal) {
55 t.Helper()
56 var buf [32]byte
57 if _, err := rng.Read(buf[:]); chk.T(err) {
58 t.Fatalf("failed to read random: %v", err)
59 }
60 // Create and return both a big integer and a field value.
61 bigIntVal := new(big.Int).SetBytes(buf[:])
62 bigIntVal.Mod(bigIntVal, curveParams.N)
63 var fv FieldVal
64 fv.SetBytes(&buf)
65 return bigIntVal, &fv
66 }
67
68 // TestFieldSetInt ensures that setting a field value to various native
69 // integers works as expected.
70 func TestFieldSetInt(t *testing.T) {
71 tests := []struct {
72 name string // test description
73 in uint16 // test value
74 expected [10]uint32 // expected raw ints
75 }{
76 {
77 name: "one",
78 in: 1,
79 expected: [10]uint32{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
80 }, {
81 name: "five",
82 in: 5,
83 expected: [10]uint32{5, 0, 0, 0, 0, 0, 0, 0, 0, 0},
84 }, {
85 name: "2^16 - 1",
86 in: 65535,
87 expected: [10]uint32{65535, 0, 0, 0, 0, 0, 0, 0, 0, 0},
88 },
89 }
90 for _, test := range tests {
91 f := new(FieldVal).SetInt(test.in)
92 if !reflect.DeepEqual(f.n, test.expected) {
93 t.Errorf(
94 "%s: wrong result\ngot: %v\nwant: %v", test.name, f.n,
95 test.expected,
96 )
97 continue
98 }
99 }
100 }
101
102 // TestFieldSetBytes ensures that setting a field value to a 256-bit big-endian
103 // unsigned integer via both the slice and array methods works as expected for
104 // edge cases. Random cases are tested via the various other tests.
105 func TestFieldSetBytes(t *testing.T) {
106 tests := []struct {
107 name string // test description
108 in string // hex encoded test value
109 expected [10]uint32 // expected raw ints
110 overflow bool // expected overflow result
111 }{
112 {
113 name: "zero",
114 in: "00",
115 expected: [10]uint32{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
116 overflow: false,
117 }, {
118 name: "field prime",
119 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
120 expected: [10]uint32{
121 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x03ffffff, 0x03ffffff,
122 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x003fffff,
123 },
124 overflow: true,
125 }, {
126 name: "field prime - 1",
127 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
128 expected: [10]uint32{
129 0x03fffc2e, 0x03ffffbf, 0x03ffffff, 0x03ffffff, 0x03ffffff,
130 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x003fffff,
131 },
132 overflow: false,
133 }, {
134 name: "field prime + 1 (overflow in word zero)",
135 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
136 expected: [10]uint32{
137 0x03fffc30, 0x03ffffbf, 0x03ffffff, 0x03ffffff, 0x03ffffff,
138 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x003fffff,
139 },
140 overflow: true,
141 }, {
142 name: "field prime first 32 bits",
143 in: "fffffc2f",
144 expected: [10]uint32{
145 0x03fffc2f, 0x00000003f, 0x00000000, 0x00000000, 0x00000000,
146 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
147 },
148 overflow: false,
149 }, {
150 name: "field prime word zero",
151 in: "03fffc2f",
152 expected: [10]uint32{
153 0x03fffc2f, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
154 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
155 },
156 overflow: false,
157 }, {
158 name: "field prime first 64 bits",
159 in: "fffffffefffffc2f",
160 expected: [10]uint32{
161 0x03fffc2f, 0x03ffffbf, 0x00000fff, 0x00000000, 0x00000000,
162 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
163 },
164 overflow: false,
165 }, {
166 name: "field prime word zero and one",
167 in: "0ffffefffffc2f",
168 expected: [10]uint32{
169 0x03fffc2f, 0x03ffffbf, 0x00000000, 0x00000000, 0x00000000,
170 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
171 },
172 overflow: false,
173 }, {
174 name: "field prime first 96 bits",
175 in: "fffffffffffffffefffffc2f",
176 expected: [10]uint32{
177 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x0003ffff, 0x00000000,
178 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
179 },
180 overflow: false,
181 }, {
182 name: "field prime word zero, one, and two",
183 in: "3ffffffffffefffffc2f",
184 expected: [10]uint32{
185 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x00000000, 0x00000000,
186 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
187 },
188 overflow: false,
189 }, {
190 name: "overflow in word one (prime + 1<<26)",
191 in: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff03fffc2f",
192 expected: [10]uint32{
193 0x03fffc2f, 0x03ffffc0, 0x03ffffff, 0x03ffffff, 0x03ffffff,
194 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x003fffff,
195 },
196 overflow: true,
197 }, {
198 name: "(field prime - 1) * 2 NOT mod P, truncated >32 bytes",
199 in: "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff85c",
200 expected: [10]uint32{
201 0x01fffff8, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
202 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x00007fff,
203 },
204 overflow: false,
205 }, {
206 name: "2^256 - 1",
207 in: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
208 expected: [10]uint32{
209 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
210 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x003fffff,
211 },
212 overflow: true,
213 }, {
214 name: "alternating bits",
215 in: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
216 expected: [10]uint32{
217 0x01a5a5a5, 0x01696969, 0x025a5a5a, 0x02969696, 0x01a5a5a5,
218 0x01696969, 0x025a5a5a, 0x02969696, 0x01a5a5a5, 0x00296969,
219 },
220 overflow: false,
221 }, {
222 name: "alternating bits 2",
223 in: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
224 expected: [10]uint32{
225 0x025a5a5a, 0x02969696, 0x01a5a5a5, 0x01696969, 0x025a5a5a,
226 0x02969696, 0x01a5a5a5, 0x01696969, 0x025a5a5a, 0x00169696,
227 },
228 overflow: false,
229 },
230 }
231 for _, test := range tests {
232 inBytes := hexToBytes(test.in)
233 // Ensure setting the bytes via the slice method works as expected.
234 var f FieldVal
235 overflow := f.SetByteSlice(inBytes)
236 if !reflect.DeepEqual(f.n, test.expected) {
237 t.Errorf(
238 "%s: unexpected result\ngot: %x\nwant: %x", test.name, f.n,
239 test.expected,
240 )
241 continue
242 }
243 // Ensure the setting the bytes via the slice method produces the
244 // expected overflow result.
245 if overflow != test.overflow {
246 t.Errorf(
247 "%s: unexpected overflow -- got: %v, want: %v", test.name,
248 overflow, test.overflow,
249 )
250 continue
251 }
252 // Ensure setting the bytes via the array method works as expected.
253 var f2 FieldVal
254 var b32 [32]byte
255 truncatedInBytes := inBytes
256 if len(truncatedInBytes) > 32 {
257 truncatedInBytes = truncatedInBytes[:32]
258 }
259 copy(b32[32-len(truncatedInBytes):], truncatedInBytes)
260 overflow = f2.SetBytes(&b32) != 0
261 if !reflect.DeepEqual(f2.n, test.expected) {
262 t.Errorf(
263 "%s: unexpected result\ngot: %x\nwant: %x", test.name,
264 f2.n, test.expected,
265 )
266 continue
267 }
268 // Ensure the setting the bytes via the array method produces the
269 // expected overflow result.
270 if overflow != test.overflow {
271 t.Errorf(
272 "%s: unexpected overflow -- got: %v, want: %v", test.name,
273 overflow, test.overflow,
274 )
275 continue
276 }
277 }
278 }
279
280 // TestFieldBytes ensures that retrieving the bytes for a 256-bit big-endian
281 // unsigned integer via the various methods works as expected for edge cases.
282 // Random cases are tested via the various other tests.
283 func TestFieldBytes(t *testing.T) {
284 tests := []struct {
285 name string // test description
286 in string // hex encoded test value
287 expected string // expected hex encoded bytes
288 }{
289 {
290 name: "zero",
291 in: "0",
292 expected: "0000000000000000000000000000000000000000000000000000000000000000",
293 }, {
294 name: "field prime (aka 0)",
295 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
296 expected: "0000000000000000000000000000000000000000000000000000000000000000",
297 }, {
298 name: "field prime - 1",
299 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
300 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
301 }, {
302 name: "field prime + 1 (aka 1, overflow in word zero)",
303 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
304 expected: "0000000000000000000000000000000000000000000000000000000000000001",
305 }, {
306 name: "field prime first 32 bits",
307 in: "fffffc2f",
308 expected: "00000000000000000000000000000000000000000000000000000000fffffc2f",
309 }, {
310 name: "field prime word zero",
311 in: "03fffc2f",
312 expected: "0000000000000000000000000000000000000000000000000000000003fffc2f",
313 }, {
314 name: "field prime first 64 bits",
315 in: "fffffffefffffc2f",
316 expected: "000000000000000000000000000000000000000000000000fffffffefffffc2f",
317 }, {
318 name: "field prime word zero and one",
319 in: "0ffffefffffc2f",
320 expected: "000000000000000000000000000000000000000000000000000ffffefffffc2f",
321 }, {
322 name: "field prime first 96 bits",
323 in: "fffffffffffffffefffffc2f",
324 expected: "0000000000000000000000000000000000000000fffffffffffffffefffffc2f",
325 }, {
326 name: "field prime word zero, one, and two",
327 in: "3ffffffffffefffffc2f",
328 expected: "000000000000000000000000000000000000000000003ffffffffffefffffc2f",
329 }, {
330 name: "overflow in word one (prime + 1<<26)",
331 in: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff03fffc2f",
332 expected: "0000000000000000000000000000000000000000000000000000000004000000",
333 }, {
334 name: "2^256 - 1",
335 in: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
336 expected: "00000000000000000000000000000000000000000000000000000001000003d0",
337 }, {
338 name: "alternating bits",
339 in: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
340 expected: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
341 }, {
342 name: "alternating bits 2",
343 in: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
344 expected: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
345 },
346 }
347 for _, test := range tests {
348 f := new(FieldVal).SetHex(test.in).Normalize()
349 expected := hexToBytes(test.expected)
350 // Ensure getting the bytes works as expected.
351 gotBytes := f.Bytes()
352 if !utils.FastEqual(gotBytes[:], expected) {
353 t.Errorf(
354 "%s: unexpected result\ngot: %x\nwant: %x", test.name,
355 *gotBytes, expected,
356 )
357 continue
358 }
359 // Ensure getting the bytes directly into an array works as expected.
360 var b32 [32]byte
361 f.PutBytes(&b32)
362 if !utils.FastEqual(b32[:], expected) {
363 t.Errorf(
364 "%s: unexpected result\ngot: %x\nwant: %x", test.name,
365 b32, expected,
366 )
367 continue
368 }
369 // Ensure getting the bytes directly into a slice works as expected.
370 var buffer [64]byte
371 f.PutBytesUnchecked(buffer[:])
372 if !utils.FastEqual(buffer[:32], expected) {
373 t.Errorf(
374 "%s: unexpected result\ngot: %x\nwant: %x", test.name,
375 buffer[:32], expected,
376 )
377 continue
378 }
379 }
380 }
381
382 // TestFieldZero ensures that zeroing a field value works as expected.
383 func TestFieldZero(t *testing.T) {
384 var f FieldVal
385 f.SetHex("a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5")
386 f.Zero()
387 for idx, rawInt := range f.n {
388 if rawInt != 0 {
389 t.Errorf(
390 "internal integer at index #%d is not zero - got %d", idx,
391 rawInt,
392 )
393 }
394 }
395 }
396
397 // TestFieldIsZero ensures that checking if a field is zero via IsZero and
398 // IsZeroBit works as expected.
399 func TestFieldIsZero(t *testing.T) {
400 f := new(FieldVal)
401 if !f.IsZero() {
402 t.Errorf("new field value is not zero - got %v (rawints %x)", f, f.n)
403 }
404 if f.IsZeroBit() != 1 {
405 t.Errorf("new field value is not zero - got %v (rawints %x)", f, f.n)
406 }
407 f.SetInt(1)
408 if f.IsZero() {
409 t.Errorf("claims zero for nonzero field - got %v (rawints %x)", f, f.n)
410 }
411 if f.IsZeroBit() == 1 {
412 t.Errorf("claims zero for nonzero field - got %v (rawints %x)", f, f.n)
413 }
414 f.Zero()
415 if !f.IsZero() {
416 t.Errorf("claims nonzero for zero field - got %v (rawints %x)", f, f.n)
417 }
418 if f.IsZeroBit() != 1 {
419 t.Errorf("claims nonzero for zero field - got %v (rawints %x)", f, f.n)
420 }
421 f.SetInt(1)
422 f.Zero()
423 if !f.IsZero() {
424 t.Errorf("claims zero for nonzero field - got %v (rawints %x)", f, f.n)
425 }
426 if f.IsZeroBit() != 1 {
427 t.Errorf("claims zero for nonzero field - got %v (rawints %x)", f, f.n)
428 }
429 }
430
431 // TestFieldIsOne ensures that checking if a field is one via IsOne and IsOneBit
432 // works as expected.
433 func TestFieldIsOne(t *testing.T) {
434 tests := []struct {
435 name string // test description
436 in string // hex encoded test value
437 normalize bool // whether or not to normalize the test value
438 expected bool // expected result
439 }{
440 {
441 name: "zero",
442 in: "0",
443 normalize: true,
444 expected: false,
445 }, {
446 name: "one",
447 in: "1",
448 normalize: true,
449 expected: true,
450 }, {
451 name: "secp256k1 prime NOT normalized (would be 0)",
452 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
453 normalize: false,
454 expected: false,
455 }, {
456 name: "secp256k1 prime normalized (aka 0)",
457 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
458 normalize: true,
459 expected: false,
460 }, {
461 name: "secp256k1 prime + 1 normalized (aka 1)",
462 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
463 normalize: true,
464 expected: true,
465 }, {
466 name: "secp256k1 prime + 1 NOT normalized (would be 1)",
467 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
468 normalize: false,
469 expected: false,
470 }, {
471 name: "2^26 (one bit in second internal field word",
472 in: "4000000",
473 normalize: false,
474 expected: false,
475 }, {
476 name: "2^52 (one bit in third internal field word",
477 in: "10000000000000",
478 normalize: false,
479 expected: false,
480 }, {
481 name: "2^78 (one bit in fourth internal field word",
482 in: "40000000000000000000",
483 normalize: false,
484 expected: false,
485 }, {
486 name: "2^104 (one bit in fifth internal field word",
487 in: "100000000000000000000000000",
488 normalize: false,
489 expected: false,
490 }, {
491 name: "2^130 (one bit in sixth internal field word",
492 in: "400000000000000000000000000000000",
493 normalize: false,
494 expected: false,
495 }, {
496 name: "2^156 (one bit in seventh internal field word",
497 in: "1000000000000000000000000000000000000000",
498 normalize: false,
499 expected: false,
500 }, {
501 name: "2^182 (one bit in eighth internal field word",
502 in: "4000000000000000000000000000000000000000000000",
503 normalize: false,
504 expected: false,
505 }, {
506 name: "2^208 (one bit in ninth internal field word",
507 in: "10000000000000000000000000000000000000000000000000000",
508 normalize: false,
509 expected: false,
510 }, {
511 name: "2^234 (one bit in tenth internal field word",
512 in: "40000000000000000000000000000000000000000000000000000000000",
513 normalize: false,
514 expected: false,
515 },
516 }
517 for _, test := range tests {
518 f := new(FieldVal).SetHex(test.in)
519 if test.normalize {
520 f.Normalize()
521 }
522 result := f.IsOne()
523 if result != test.expected {
524 t.Errorf(
525 "%s: wrong result -- got: %v, want: %v", test.name, result,
526 test.expected,
527 )
528 continue
529 }
530 result2 := f.IsOneBit() == 1
531 if result2 != test.expected {
532 t.Errorf(
533 "%s: wrong result -- got: %v, want: %v", test.name,
534 result2, test.expected,
535 )
536 continue
537 }
538 }
539 }
540
541 // TestFieldStringer ensures the stringer returns the appropriate hex string.
542 func TestFieldStringer(t *testing.T) {
543 tests := []struct {
544 name string // test description
545 in string // hex encoded test value
546 expected string // expected result
547 }{
548 {
549 name: "zero",
550 in: "0",
551 expected: "0000000000000000000000000000000000000000000000000000000000000000",
552 }, {
553 name: "one",
554 in: "1",
555 expected: "0000000000000000000000000000000000000000000000000000000000000001",
556 }, {
557 name: "ten",
558 in: "a",
559 expected: "000000000000000000000000000000000000000000000000000000000000000a",
560 }, {
561 name: "eleven",
562 in: "b",
563 expected: "000000000000000000000000000000000000000000000000000000000000000b",
564 }, {
565 name: "twelve",
566 in: "c",
567 expected: "000000000000000000000000000000000000000000000000000000000000000c",
568 }, {
569 name: "thirteen",
570 in: "d",
571 expected: "000000000000000000000000000000000000000000000000000000000000000d",
572 }, {
573 name: "fourteen",
574 in: "e",
575 expected: "000000000000000000000000000000000000000000000000000000000000000e",
576 }, {
577 name: "fifteen",
578 in: "f",
579 expected: "000000000000000000000000000000000000000000000000000000000000000f",
580 }, {
581 name: "240",
582 in: "f0",
583 expected: "00000000000000000000000000000000000000000000000000000000000000f0",
584 }, {
585 name: "2^26 - 1",
586 in: "3ffffff",
587 expected: "0000000000000000000000000000000000000000000000000000000003ffffff",
588 }, {
589 name: "2^32 - 1",
590 in: "ffffffff",
591 expected: "00000000000000000000000000000000000000000000000000000000ffffffff",
592 }, {
593 name: "2^64 - 1",
594 in: "ffffffffffffffff",
595 expected: "000000000000000000000000000000000000000000000000ffffffffffffffff",
596 }, {
597 name: "2^96 - 1",
598 in: "ffffffffffffffffffffffff",
599 expected: "0000000000000000000000000000000000000000ffffffffffffffffffffffff",
600 }, {
601 name: "2^128 - 1",
602 in: "ffffffffffffffffffffffffffffffff",
603 expected: "00000000000000000000000000000000ffffffffffffffffffffffffffffffff",
604 }, {
605 name: "2^160 - 1",
606 in: "ffffffffffffffffffffffffffffffffffffffff",
607 expected: "000000000000000000000000ffffffffffffffffffffffffffffffffffffffff",
608 }, {
609 name: "2^192 - 1",
610 in: "ffffffffffffffffffffffffffffffffffffffffffffffff",
611 expected: "0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff",
612 }, {
613 name: "2^224 - 1",
614 in: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
615 expected: "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
616 }, {
617 name: "2^256-4294968273 (the secp256k1 prime, so should result in 0)",
618 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
619 expected: "0000000000000000000000000000000000000000000000000000000000000000",
620 }, {
621 name: "2^256-4294968274 (the secp256k1 prime+1, so should result in 1)",
622 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
623 expected: "0000000000000000000000000000000000000000000000000000000000000001",
624 }, {
625 name: "invalid hex g",
626 in: "g",
627 expected: "0000000000000000000000000000000000000000000000000000000000000000",
628 }, {
629 name: "invalid hex 1h",
630 in: "1h",
631 expected: "0000000000000000000000000000000000000000000000000000000000000000",
632 }, {
633 name: "invalid hex i1",
634 in: "i1",
635 expected: "0000000000000000000000000000000000000000000000000000000000000000",
636 },
637 }
638 for _, test := range tests {
639 f := new(FieldVal).SetHex(test.in)
640 result := f.String()
641 if result != test.expected {
642 t.Errorf(
643 "%s: wrong result\ngot: %v\nwant: %v", test.name, result,
644 test.expected,
645 )
646 continue
647 }
648 }
649 }
650
651 // TestFieldNormalize ensures that normalizing the internal field words works as
652 // expected.
653 func TestFieldNormalize(t *testing.T) {
654 tests := []struct {
655 name string // test description
656 raw [10]uint32 // Intentionally denormalized value
657 normalized [10]uint32 // Normalized form of the raw value
658 }{
659 {
660 name: "5",
661 raw: [10]uint32{0x00000005, 0, 0, 0, 0, 0, 0, 0, 0, 0},
662 normalized: [10]uint32{0x00000005, 0, 0, 0, 0, 0, 0, 0, 0, 0},
663 }, {
664 name: "2^26",
665 raw: [10]uint32{0x04000000, 0x0, 0, 0, 0, 0, 0, 0, 0, 0},
666 normalized: [10]uint32{0x00000000, 0x1, 0, 0, 0, 0, 0, 0, 0, 0},
667 }, {
668 name: "2^26 + 1",
669 raw: [10]uint32{0x04000001, 0x0, 0, 0, 0, 0, 0, 0, 0, 0},
670 normalized: [10]uint32{0x00000001, 0x1, 0, 0, 0, 0, 0, 0, 0, 0},
671 }, {
672 name: "2^32 - 1",
673 raw: [10]uint32{0xffffffff, 0x00, 0, 0, 0, 0, 0, 0, 0, 0},
674 normalized: [10]uint32{0x03ffffff, 0x3f, 0, 0, 0, 0, 0, 0, 0, 0},
675 }, {
676 name: "2^32",
677 raw: [10]uint32{0x04000000, 0x3f, 0, 0, 0, 0, 0, 0, 0, 0},
678 normalized: [10]uint32{0x00000000, 0x40, 0, 0, 0, 0, 0, 0, 0, 0},
679 }, {
680 name: "2^32 + 1",
681 raw: [10]uint32{0x04000001, 0x3f, 0, 0, 0, 0, 0, 0, 0, 0},
682 normalized: [10]uint32{0x00000001, 0x40, 0, 0, 0, 0, 0, 0, 0, 0},
683 }, {
684 name: "2^64 - 1",
685 raw: [10]uint32{
686 0xffffffff, 0xffffffc0, 0xfc0, 0, 0, 0, 0, 0, 0,
687 0,
688 },
689 normalized: [10]uint32{
690 0x03ffffff, 0x03ffffff, 0xfff, 0, 0, 0, 0, 0, 0,
691 0,
692 },
693 }, {
694 name: "2^64",
695 raw: [10]uint32{
696 0x04000000, 0x03ffffff, 0x0fff, 0, 0, 0, 0, 0, 0,
697 0,
698 },
699 normalized: [10]uint32{
700 0x00000000, 0x00000000, 0x1000, 0, 0, 0, 0, 0, 0,
701 0,
702 },
703 }, {
704 name: "2^64 + 1",
705 raw: [10]uint32{
706 0x04000001, 0x03ffffff, 0x0fff, 0, 0, 0, 0, 0, 0,
707 0,
708 },
709 normalized: [10]uint32{
710 0x00000001, 0x00000000, 0x1000, 0, 0, 0, 0, 0, 0,
711 0,
712 },
713 }, {
714 name: "2^96 - 1",
715 raw: [10]uint32{
716 0xffffffff, 0xffffffc0, 0xffffffc0, 0x3ffc0, 0,
717 0, 0, 0, 0, 0,
718 },
719 normalized: [10]uint32{
720 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x3ffff, 0,
721 0, 0, 0, 0, 0,
722 },
723 }, {
724 name: "2^96",
725 raw: [10]uint32{
726 0x04000000, 0x03ffffff, 0x03ffffff, 0x3ffff, 0,
727 0, 0, 0, 0, 0,
728 },
729 normalized: [10]uint32{
730 0x00000000, 0x00000000, 0x00000000, 0x40000, 0,
731 0, 0, 0, 0, 0,
732 },
733 }, {
734 name: "2^128 - 1",
735 raw: [10]uint32{
736 0xffffffff, 0xffffffc0, 0xffffffc0, 0xffffffc0,
737 0xffffc0, 0, 0, 0, 0, 0,
738 },
739 normalized: [10]uint32{
740 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
741 0xffffff, 0, 0, 0, 0, 0,
742 },
743 }, {
744 name: "2^128",
745 raw: [10]uint32{
746 0x04000000, 0x03ffffff, 0x03ffffff, 0x03ffffff,
747 0x0ffffff, 0, 0, 0, 0, 0,
748 },
749 normalized: [10]uint32{
750 0x00000000, 0x00000000, 0x00000000, 0x00000000,
751 0x1000000, 0, 0, 0, 0, 0,
752 },
753 }, {
754 name: "2^256 - 4294968273 (secp256k1 prime)",
755 raw: [10]uint32{
756 0xfffffc2f, 0xffffff80, 0xffffffc0, 0xffffffc0,
757 0xffffffc0, 0xffffffc0, 0xffffffc0,
758 0xffffffc0, 0xffffffc0, 0x3fffc0,
759 },
760 normalized: [10]uint32{
761 0x00000000, 0x00000000, 0x00000000, 0x00000000,
762 0x00000000, 0x00000000, 0x00000000,
763 0x00000000, 0x00000000, 0x000000,
764 },
765 }, {
766 // Value larger than P where both first and second words are larger than
767 // P's first and second words
768 name: "Value > P with 1st and 2nd words > P's 1st and 2nd words",
769 raw: [10]uint32{
770 0xfffffc30, 0xffffff86, 0xffffffc0, 0xffffffc0,
771 0xffffffc0, 0xffffffc0, 0xffffffc0,
772 0xffffffc0, 0xffffffc0, 0x3fffc0,
773 },
774 normalized: [10]uint32{
775 0x00000001, 0x00000006, 0x00000000, 0x00000000,
776 0x00000000, 0x00000000, 0x00000000,
777 0x00000000, 0x00000000, 0x000000,
778 },
779 }, {
780 // Value larger than P where only the second word is larger than P's
781 // second word.
782 name: "Value > P with 2nd word > P's 2nd word",
783 raw: [10]uint32{
784 0xfffffc2a, 0xffffff87, 0xffffffc0, 0xffffffc0,
785 0xffffffc0, 0xffffffc0, 0xffffffc0,
786 0xffffffc0, 0xffffffc0, 0x3fffc0,
787 },
788 normalized: [10]uint32{
789 0x03fffffb, 0x00000006, 0x00000000, 0x00000000,
790 0x00000000, 0x00000000, 0x00000000,
791 0x00000000, 0x00000000, 0x000000,
792 },
793 }, {
794 name: "2^256 - 1",
795 raw: [10]uint32{
796 0xffffffff, 0xffffffc0, 0xffffffc0, 0xffffffc0,
797 0xffffffc0, 0xffffffc0, 0xffffffc0,
798 0xffffffc0, 0xffffffc0, 0x3fffc0,
799 },
800 normalized: [10]uint32{
801 0x000003d0, 0x00000040, 0x00000000, 0x00000000,
802 0x00000000, 0x00000000, 0x00000000,
803 0x00000000, 0x00000000, 0x000000,
804 },
805 }, {
806 // Prime with field representation such that the initial reduction does
807 // not result in a carry to bit 256.
808 //
809 // 2^256 - 4294968273 (secp256k1 prime)
810 name: "2^256 - 4294968273 (secp256k1 prime)",
811 raw: [10]uint32{
812 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
813 0x03ffffff, 0x03ffffff, 0x03ffffff,
814 0x03ffffff, 0x03ffffff, 0x003fffff,
815 },
816 normalized: [10]uint32{
817 0x00000000, 0x00000000, 0x00000000, 0x00000000,
818 0x00000000, 0x00000000, 0x00000000,
819 0x00000000, 0x00000000, 0x00000000,
820 },
821 }, {
822 // Value larger than P that reduces to a value which is still larger
823 // than P when it has a magnitude of 1 due to its first word and does
824 // not result in a carry to bit 256.
825 //
826 // 2^256 - 4294968272 (secp256k1 prime + 1)
827 name: "2^256 - 4294968272 (secp256k1 prime + 1)",
828 raw: [10]uint32{
829 0x03fffc30, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
830 0x03ffffff, 0x03ffffff, 0x03ffffff,
831 0x03ffffff, 0x03ffffff, 0x003fffff,
832 },
833 normalized: [10]uint32{
834 0x00000001, 0x00000000, 0x00000000, 0x00000000,
835 0x00000000, 0x00000000, 0x00000000,
836 0x00000000, 0x00000000, 0x00000000,
837 },
838 }, {
839 // Value larger than P that reduces to a value which is still larger
840 // than P when it has a magnitude of 1 due to its second word and does
841 // not result in a carry to bit 256.
842 //
843 // 2^256 - 4227859409 (secp256k1 prime + 0x4000000)
844 name: "2^256 - 4227859409 (secp256k1 prime + 0x4000000)",
845 raw: [10]uint32{
846 0x03fffc2f, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
847 0x03ffffff, 0x03ffffff, 0x03ffffff,
848 0x03ffffff, 0x03ffffff, 0x003fffff,
849 },
850 normalized: [10]uint32{
851 0x00000000, 0x00000001, 0x00000000, 0x00000000,
852 0x00000000, 0x00000000, 0x00000000,
853 0x00000000, 0x00000000, 0x00000000,
854 },
855 }, {
856 // Value larger than P that reduces to a value which is still larger
857 // than P when it has a magnitude of 1 due to a carry to bit 256, but
858 // would not be without the carry. These values come from the fact that
859 // P is 2^256 - 4294968273 and 977 is the low order word in the internal
860 // field representation.
861 //
862 // 2^256 * 5 - ((4294968273 - (977+1)) * 4)
863 name: "2^256 * 5 - ((4294968273 - (977+1)) * 4)",
864 raw: [10]uint32{
865 0x03ffffff, 0x03fffeff, 0x03ffffff, 0x03ffffff,
866 0x03ffffff, 0x03ffffff, 0x03ffffff,
867 0x03ffffff, 0x03ffffff, 0x0013fffff,
868 },
869 normalized: [10]uint32{
870 0x00001314, 0x00000040, 0x00000000, 0x00000000,
871 0x00000000, 0x00000000, 0x00000000,
872 0x00000000, 0x00000000, 0x000000000,
873 },
874 }, {
875 // Value larger than P that reduces to a value which is still larger
876 // than P when it has a magnitude of 1 due to both a carry to bit 256
877 // and the first word.
878 name: "Value > P with redux > P at mag 1 due to 1st word and carry to bit 256",
879 raw: [10]uint32{
880 0x03fffc30, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
881 0x03ffffff, 0x03ffffff, 0x03ffffff,
882 0x03ffffff, 0x07ffffff, 0x003fffff,
883 },
884 normalized: [10]uint32{
885 0x00000001, 0x00000000, 0x00000000, 0x00000000,
886 0x00000000, 0x00000000, 0x00000000,
887 0x00000000, 0x00000000, 0x00000001,
888 },
889 }, {
890 // Value larger than P that reduces to a value which is still larger
891 // than P when it has a magnitude of 1 due to both a carry to bit 256
892 // and the second word.
893 name: "Value > P with redux > P at mag 1 due to 2nd word and carry to bit 256",
894 raw: [10]uint32{
895 0x03fffc2f, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
896 0x03ffffff, 0x03ffffff, 0x03ffffff,
897 0x3ffffff, 0x07ffffff, 0x003fffff,
898 },
899 normalized: [10]uint32{
900 0x00000000, 0x00000001, 0x00000000, 0x00000000,
901 0x00000000, 0x00000000, 0x00000000,
902 0x0000000, 0x00000000, 0x00000001,
903 },
904 }, {
905 // Value larger than P that reduces to a value which is still larger
906 // than P when it has a magnitude of 1 due to a carry to bit 256 and the
907 // first and second words.
908 name: "Value > P with redux > P at mag 1 due to 1st and 2nd words and carry to bit 256",
909 raw: [10]uint32{
910 0x03fffc30, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
911 0x03ffffff, 0x03ffffff, 0x03ffffff,
912 0x03ffffff, 0x07ffffff, 0x003fffff,
913 },
914 normalized: [10]uint32{
915 0x00000001, 0x00000001, 0x00000000, 0x00000000,
916 0x00000000, 0x00000000, 0x00000000,
917 0x00000000, 0x00000000, 0x00000001,
918 },
919 }, {
920 // ---------------------------------------------------------------------
921 // There are 3 main conditions that must be true if the final reduction
922 // is needed after the initial reduction to magnitude 1 when there was
923 // NOT a carry to bit 256 (in other words when the original value was <
924 // 2^256):
925 // 1) The final word of the reduced value is equal to the one of P
926 // 2) The 3rd through 9th words are equal to those of P
927 // 3) Either:
928 // - The 2nd word is greater than the one of P; or
929 // - The 2nd word is equal to that of P AND the 1st word is greater
930 //
931 // Therefore the eight possible combinations of those 3 main conditions
932 // can be thought of in binary where each bit starting from the left
933 // corresponds to the aforementioned conditions as such:
934 // 000, 001, 010, 011, 100, 101, 110, 111
935 //
936 // For example, combination 6 is when both conditons 1 and 2 are true,
937 // but condition 3 is NOT true.
938 //
939 // The following tests hit each of these combinations and refer to each
940 // by its decimal equivalent for ease of reference.
941 //
942 // NOTE: The final combination (7) is already tested above since it only
943 // happens when the original value is already the normalized
944 // representation of P.
945 // ---------------------------------------------------------------------
946 name: "Value < 2^256 final reduction combination 0",
947 raw: [10]uint32{
948 0x03fff85e, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
949 0x03ffffff, 0x03ffffff, 0x03ffffff,
950 0x03ffffff, 0x03fffffe, 0x003ffffe,
951 },
952 normalized: [10]uint32{
953 0x03fff85e, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
954 0x03ffffff, 0x03ffffff, 0x03ffffff,
955 0x03ffffff, 0x03fffffe, 0x003ffffe,
956 },
957 }, {
958 name: "Value < 2^256 final reduction combination 1 via 2nd word",
959 raw: [10]uint32{
960 0x03fff85e, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
961 0x03ffffff, 0x03ffffff, 0x03ffffff,
962 0x03ffffff, 0x03fffffe, 0x003ffffe,
963 },
964 normalized: [10]uint32{
965 0x03fff85e, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
966 0x03ffffff, 0x03ffffff, 0x03ffffff,
967 0x03ffffff, 0x03fffffe, 0x003ffffe,
968 },
969 }, {
970 name: "Value < 2^256 final reduction combination 1 via 1st word",
971 raw: [10]uint32{
972 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
973 0x03ffffff, 0x03ffffff, 0x03ffffff,
974 0x03ffffff, 0x03fffffe, 0x003ffffe,
975 },
976 normalized: [10]uint32{
977 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
978 0x03ffffff, 0x03ffffff, 0x03ffffff,
979 0x03ffffff, 0x03fffffe, 0x003ffffe,
980 },
981 }, {
982 name: "Value < 2^256 final reduction combination 2",
983 raw: [10]uint32{
984 0x03fff85e, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
985 0x03ffffff, 0x03ffffff, 0x03ffffff,
986 0x03ffffff, 0x03ffffff, 0x003ffffe,
987 },
988 normalized: [10]uint32{
989 0x03fff85e, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
990 0x03ffffff, 0x03ffffff, 0x03ffffff,
991 0x03ffffff, 0x03ffffff, 0x003ffffe,
992 },
993 }, {
994 name: "Value < 2^256 final reduction combination 3 via 2nd word",
995 raw: [10]uint32{
996 0x03fff85e, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
997 0x03ffffff, 0x03ffffff, 0x03ffffff,
998 0x03ffffff, 0x03ffffff, 0x003ffffe,
999 },
1000 normalized: [10]uint32{
1001 0x03fff85e, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
1002 0x03ffffff, 0x03ffffff, 0x03ffffff,
1003 0x03ffffff, 0x03ffffff, 0x003ffffe,
1004 },
1005 }, {
1006 name: "Value < 2^256 final reduction combination 3 via 1st word",
1007 raw: [10]uint32{
1008 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
1009 0x03ffffff, 0x03ffffff, 0x03ffffff,
1010 0x03ffffff, 0x03ffffff, 0x003ffffe,
1011 },
1012 normalized: [10]uint32{
1013 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
1014 0x03ffffff, 0x03ffffff, 0x03ffffff,
1015 0x03ffffff, 0x03ffffff, 0x003ffffe,
1016 },
1017 }, {
1018 name: "Value < 2^256 final reduction combination 4",
1019 raw: [10]uint32{
1020 0x03fff85e, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
1021 0x03ffffff, 0x03ffffff, 0x03ffffff,
1022 0x03ffffff, 0x03fffffe, 0x003fffff,
1023 },
1024 normalized: [10]uint32{
1025 0x03fff85e, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
1026 0x03ffffff, 0x03ffffff, 0x03ffffff,
1027 0x03ffffff, 0x03fffffe, 0x003fffff,
1028 },
1029 }, {
1030 name: "Value < 2^256 final reduction combination 5 via 2nd word",
1031 raw: [10]uint32{
1032 0x03fff85e, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
1033 0x03ffffff, 0x03ffffff, 0x03ffffff,
1034 0x03ffffff, 0x03fffffe, 0x003fffff,
1035 },
1036 normalized: [10]uint32{
1037 0x03fff85e, 0x03ffffc0, 0x03ffffff, 0x03ffffff,
1038 0x03ffffff, 0x03ffffff, 0x03ffffff,
1039 0x03ffffff, 0x03fffffe, 0x003fffff,
1040 },
1041 }, {
1042 name: "Value < 2^256 final reduction combination 5 via 1st word",
1043 raw: [10]uint32{
1044 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
1045 0x03ffffff, 0x03ffffff, 0x03ffffff,
1046 0x03ffffff, 0x03fffffe, 0x003fffff,
1047 },
1048 normalized: [10]uint32{
1049 0x03fffc2f, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
1050 0x03ffffff, 0x03ffffff, 0x03ffffff,
1051 0x03ffffff, 0x03fffffe, 0x003fffff,
1052 },
1053 }, {
1054 name: "Value < 2^256 final reduction combination 6",
1055 raw: [10]uint32{
1056 0x03fff85e, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
1057 0x03ffffff, 0x03ffffff, 0x03ffffff,
1058 0x03ffffff, 0x03ffffff, 0x003fffff,
1059 },
1060 normalized: [10]uint32{
1061 0x03fff85e, 0x03ffffbf, 0x03ffffff, 0x03ffffff,
1062 0x03ffffff, 0x03ffffff, 0x03ffffff,
1063 0x03ffffff, 0x03ffffff, 0x003fffff,
1064 },
1065 },
1066 }
1067 for _, test := range tests {
1068 f := new(FieldVal)
1069 f.n = test.raw
1070 f.Normalize()
1071 if !reflect.DeepEqual(f.n, test.normalized) {
1072 t.Errorf(
1073 "%s: wrong normalized result\ngot: %x\nwant: %x",
1074 test.name, f.n, test.normalized,
1075 )
1076 continue
1077 }
1078 }
1079 }
1080
1081 // TestFieldIsOdd ensures that checking if a field value is odd via IsOdd and
1082 // IsOddBit works as expected.
1083 func TestFieldIsOdd(t *testing.T) {
1084 tests := []struct {
1085 name string // test description
1086 in string // hex encoded value
1087 expected bool // expected oddness
1088 }{
1089 {
1090 name: "zero",
1091 in: "0",
1092 expected: false,
1093 }, {
1094 name: "one",
1095 in: "1",
1096 expected: true,
1097 }, {
1098 name: "two",
1099 in: "2",
1100 expected: false,
1101 }, {
1102 name: "2^32 - 1",
1103 in: "ffffffff",
1104 expected: true,
1105 }, {
1106 name: "2^64 - 2",
1107 in: "fffffffffffffffe",
1108 expected: false,
1109 }, {
1110 name: "secp256k1 prime (not normalized so should be incorrect result)",
1111 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1112 expected: true,
1113 }, {
1114 name: "secp256k1 prime + 1 (not normalized so should be incorrect result)",
1115 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
1116 expected: false,
1117 },
1118 }
1119 for _, test := range tests {
1120 f := new(FieldVal).SetHex(test.in)
1121 result := f.IsOdd()
1122 if result != test.expected {
1123 t.Errorf(
1124 "%s: wrong result -- got: %v, want: %v", test.name,
1125 result, test.expected,
1126 )
1127 continue
1128 }
1129 result2 := f.IsOddBit() == 1
1130 if result2 != test.expected {
1131 t.Errorf(
1132 "%s: wrong result -- got: %v, want: %v", test.name,
1133 result2, test.expected,
1134 )
1135 continue
1136 }
1137 }
1138 }
1139
1140 // TestFieldEquals ensures that checking two field values for equality via
1141 // Equals works as expected.
1142 func TestFieldEquals(t *testing.T) {
1143 tests := []struct {
1144 name string // test description
1145 in1 string // hex encoded value
1146 in2 string // hex encoded value
1147 expected bool // expected equality
1148 }{
1149 {
1150 name: "0 == 0?",
1151 in1: "0",
1152 in2: "0",
1153 expected: true,
1154 }, {
1155 name: "0 == 1?",
1156 in1: "0",
1157 in2: "1",
1158 expected: false,
1159 }, {
1160 name: "1 == 0?",
1161 in1: "1",
1162 in2: "0",
1163 expected: false,
1164 }, {
1165 name: "2^32 - 1 == 2^32 - 1?",
1166 in1: "ffffffff",
1167 in2: "ffffffff",
1168 expected: true,
1169 }, {
1170 name: "2^64 - 1 == 2^64 - 2?",
1171 in1: "ffffffffffffffff",
1172 in2: "fffffffffffffffe",
1173 expected: false,
1174 }, {
1175 name: "0 == prime (mod prime)?",
1176 in1: "0",
1177 in2: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1178 expected: true,
1179 }, {
1180 name: "1 == prime + 1 (mod prime)?",
1181 in1: "1",
1182 in2: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30",
1183 expected: true,
1184 },
1185 }
1186 for _, test := range tests {
1187 f := new(FieldVal).SetHex(test.in1).Normalize()
1188 f2 := new(FieldVal).SetHex(test.in2).Normalize()
1189 result := f.Equals(f2)
1190 if result != test.expected {
1191 t.Errorf(
1192 "%s: wrong result -- got: %v, want: %v", test.name, result,
1193 test.expected,
1194 )
1195 continue
1196 }
1197 }
1198 }
1199
1200 // TestFieldNegate ensures that negating field values via Negate works as
1201 // expected.
1202 func TestFieldNegate(t *testing.T) {
1203 tests := []struct {
1204 name string // test description
1205 in string // hex encoded test value
1206 expected string // hex encoded expected result
1207 }{
1208 {
1209 name: "zero",
1210 in: "0",
1211 expected: "0",
1212 }, {
1213 name: "secp256k1 prime (direct val in with 0 out)",
1214 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1215 expected: "0",
1216 }, {
1217 name: "secp256k1 prime (0 in with direct val out)",
1218 in: "0",
1219 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1220 }, {
1221 name: "1 -> secp256k1 prime - 1",
1222 in: "1",
1223 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1224 }, {
1225 name: "secp256k1 prime - 1 -> 1",
1226 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1227 expected: "1",
1228 }, {
1229 name: "2 -> secp256k1 prime - 2",
1230 in: "2",
1231 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
1232 }, {
1233 name: "secp256k1 prime - 2 -> 2",
1234 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
1235 expected: "2",
1236 }, {
1237 name: "random sampling #1",
1238 in: "b3d9aac9c5e43910b4385b53c7e78c21d4cd5f8e683c633aed04c233efc2e120",
1239 expected: "4c2655363a1bc6ef4bc7a4ac381873de2b32a07197c39cc512fb3dcb103d1b0f",
1240 }, {
1241 name: "random sampling #2",
1242 in: "f8a85984fee5a12a7c8dd08830d83423c937d77c379e4a958e447a25f407733f",
1243 expected: "757a67b011a5ed583722f77cf27cbdc36c82883c861b56a71bb85d90bf888f0",
1244 }, {
1245 name: "random sampling #3",
1246 in: "45ee6142a7fda884211e93352ed6cb2807800e419533be723a9548823ece8312",
1247 expected: "ba119ebd5802577bdee16ccad12934d7f87ff1be6acc418dc56ab77cc131791d",
1248 }, {
1249 name: "random sampling #4",
1250 in: "53c2a668f07e411a2e473e1c3b6dcb495dec1227af27673761d44afe5b43d22b",
1251 expected: "ac3d59970f81bee5d1b8c1e3c49234b6a213edd850d898c89e2bb500a4bc2a04",
1252 },
1253 }
1254 for _, test := range tests {
1255 f := new(FieldVal).SetHex(test.in).Normalize()
1256 expected := new(FieldVal).SetHex(test.expected).Normalize()
1257 // Ensure negating another value produces the expected result.
1258 result := new(FieldVal).NegateVal(f, 1).Normalize()
1259 if !result.Equals(expected) {
1260 t.Errorf(
1261 "%s: unexpected result -- got: %v, want: %v", test.name,
1262 result, expected,
1263 )
1264 continue
1265 }
1266 // Ensure self negating also produces the expected result.
1267 result2 := f.Negate(1).Normalize()
1268 if !result2.Equals(expected) {
1269 t.Errorf(
1270 "%s: unexpected result -- got: %v, want: %v", test.name,
1271 result2, expected,
1272 )
1273 continue
1274 }
1275 }
1276 }
1277
1278 // TestFieldAddInt ensures that adding an integer to field values via AddInt
1279 // works as expected.
1280 func TestFieldAddInt(t *testing.T) {
1281 tests := []struct {
1282 name string // test description
1283 in1 string // hex encoded value
1284 in2 uint16 // unsigned integer to add to the value above
1285 expected string // expected hex encoded value
1286 }{
1287 {
1288 name: "zero + one",
1289 in1: "0",
1290 in2: 1,
1291 expected: "1",
1292 }, {
1293 name: "one + zero",
1294 in1: "1",
1295 in2: 0,
1296 expected: "1",
1297 }, {
1298 name: "one + one",
1299 in1: "1",
1300 in2: 1,
1301 expected: "2",
1302 }, {
1303 name: "secp256k1 prime-1 + 1",
1304 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1305 in2: 1,
1306 expected: "0",
1307 }, {
1308 name: "secp256k1 prime + 1",
1309 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1310 in2: 1,
1311 expected: "1",
1312 }, {
1313 name: "random sampling #1",
1314 in1: "ff95ad9315aff04ab4af0ce673620c7145dc85d03bab5ba4b09ca2c4dec2d6c1",
1315 in2: 0x10f,
1316 expected: "ff95ad9315aff04ab4af0ce673620c7145dc85d03bab5ba4b09ca2c4dec2d7d0",
1317 }, {
1318 name: "random sampling #2",
1319 in1: "44bdae6b772e7987941f1ba314e6a5b7804a4c12c00961b57d20f41deea9cecf",
1320 in2: 0x3196,
1321 expected: "44bdae6b772e7987941f1ba314e6a5b7804a4c12c00961b57d20f41deeaa0065",
1322 }, {
1323 name: "random sampling #3",
1324 in1: "88c3ecae67b591935fb1f6a9499c35315ffad766adca665c50b55f7105122c9c",
1325 in2: 0x966f,
1326 expected: "88c3ecae67b591935fb1f6a9499c35315ffad766adca665c50b55f710512c30b",
1327 }, {
1328 name: "random sampling #4",
1329 in1: "8523e9edf360ca32a95aae4e57fcde5a542b471d08a974d94ea0ee09a015e2a6",
1330 in2: 0xc54,
1331 expected: "8523e9edf360ca32a95aae4e57fcde5a542b471d08a974d94ea0ee09a015eefa",
1332 },
1333 }
1334 for _, test := range tests {
1335 f := new(FieldVal).SetHex(test.in1).Normalize()
1336 expected := new(FieldVal).SetHex(test.expected).Normalize()
1337 result := f.AddInt(test.in2).Normalize()
1338 if !result.Equals(expected) {
1339 t.Errorf(
1340 "%s: wrong result -- got: %v -- want: %v", test.name,
1341 result, expected,
1342 )
1343 continue
1344 }
1345 }
1346 }
1347
1348 // TestFieldAdd ensures that adding two field values together via Add and Add2
1349 // works as expected.
1350 func TestFieldAdd(t *testing.T) {
1351 tests := []struct {
1352 name string // test description
1353 in1 string // first hex encoded value
1354 in2 string // second hex encoded value to add
1355 expected string // expected hex encoded value
1356 }{
1357 {
1358 name: "zero + one",
1359 in1: "0",
1360 in2: "1",
1361 expected: "1",
1362 }, {
1363 name: "one + zero",
1364 in1: "1",
1365 in2: "0",
1366 expected: "1",
1367 }, {
1368 name: "secp256k1 prime-1 + 1",
1369 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1370 in2: "1",
1371 expected: "0",
1372 }, {
1373 name: "secp256k1 prime + 1",
1374 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1375 in2: "1",
1376 expected: "1",
1377 }, {
1378 name: "random sampling #1",
1379 in1: "2b2012f975404e5065b4292fb8bed0a5d315eacf24c74d8b27e73bcc5430edcc",
1380 in2: "2c3cefa4e4753e8aeec6ac4c12d99da4d78accefda3b7885d4c6bab46c86db92",
1381 expected: "575d029e59b58cdb547ad57bcb986e4aaaa0b7beff02c610fcadf680c0b7c95e",
1382 }, {
1383 name: "random sampling #2",
1384 in1: "8131e8722fe59bb189692b96c9f38de92885730f1dd39ab025daffb94c97f79c",
1385 in2: "ff5454b765f0aab5f0977dcc629becc84cabeb9def48e79c6aadb2622c490fa9",
1386 expected: "80863d2995d646677a00a9632c8f7ab175315ead0d1c824c9088b21c78e10b16",
1387 }, {
1388 name: "random sampling #3",
1389 in1: "c7c95e93d0892b2b2cdd77e80eb646ea61be7a30ac7e097e9f843af73fad5c22",
1390 in2: "3afe6f91a74dfc1c7f15c34907ee981656c37236d946767dd53ccad9190e437c",
1391 expected: "2c7ce2577d72747abf33b3116a4df00b881ec6785c47ffc74c105d158bba36f",
1392 }, {
1393 name: "random sampling #4",
1394 in1: "fd1c26f6a23381e5d785ba889494ec059369b888ad8431cd67d8c934b580dbe1",
1395 in2: "a475aa5a31dcca90ef5b53c097d9133d6b7117474b41e7877bb199590fc0489c",
1396 expected: "a191d150d4104c76c6e10e492c6dff42fedacfcff8c61954e38a628ec541284e",
1397 }, {
1398 name: "random sampling #5",
1399 in1: "ad82b8d1cc136e23e9fd77fe2c7db1fe5a2ecbfcbde59ab3529758334f862d28",
1400 in2: "4d6a4e95d6d61f4f46b528bebe152d408fd741157a28f415639347a84f6f574b",
1401 expected: "faed0767a2e98d7330b2a0bcea92df3eea060d12380e8ec8b62a9fdb9ef58473",
1402 }, {
1403 name: "random sampling #6",
1404 in1: "f3f43a2540054a86e1df98547ec1c0e157b193e5350fb4a3c3ea214b228ac5e7",
1405 in2: "25706572592690ea3ddc951a1b48b504a4c83dc253756e1b96d56fdfb3199522",
1406 expected: "19649f97992bdb711fbc2d6e9a0a75e5fc79d1a7888522bf5abf912bd5a45eda",
1407 }, {
1408 name: "random sampling #7",
1409 in1: "6915bb94eef13ff1bb9b2633d997e13b9b1157c713363cc0e891416d6734f5b8",
1410 in2: "11f90d6ac6fe1c4e8900b1c85fb575c251ec31b9bc34b35ada0aea1c21eded22",
1411 expected: "7b0ec8ffb5ef5c40449bd7fc394d56fdecfd8980cf6af01bc29c2b898922e2da",
1412 }, {
1413 name: "random sampling #8",
1414 in1: "48b0c9eae622eed9335b747968544eb3e75cb2dc8128388f948aa30f88cabde4",
1415 in2: "0989882b52f85f9d524a3a3061a0e01f46d597839d2ba637320f4b9510c8d2d5",
1416 expected: "523a5216391b4e7685a5aea9c9f52ed32e324a601e53dec6c699eea4999390b9",
1417 },
1418 }
1419 for _, test := range tests {
1420 // Parse test hex.
1421 f1 := new(FieldVal).SetHex(test.in1).Normalize()
1422 f2 := new(FieldVal).SetHex(test.in2).Normalize()
1423 expected := new(FieldVal).SetHex(test.expected).Normalize()
1424 // Ensure adding the two values with the result going to another
1425 // variable produces the expected result.
1426 result := new(FieldVal).Add2(f1, f2).Normalize()
1427 if !result.Equals(expected) {
1428 t.Errorf(
1429 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
1430 result, expected,
1431 )
1432 continue
1433 }
1434 // Ensure adding the value to an existing field value produces the
1435 // expected result.
1436 f1.Add(f2).Normalize()
1437 if !f1.Equals(expected) {
1438 t.Errorf(
1439 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
1440 f1, expected,
1441 )
1442 continue
1443 }
1444 }
1445 }
1446
1447 // TestFieldMulInt ensures that multiplying an integer to field values via
1448 // MulInt works as expected.
1449 func TestFieldMulInt(t *testing.T) {
1450 tests := []struct {
1451 name string // test description
1452 in1 string // hex encoded value
1453 in2 uint8 // unsigned integer to multiply with value above
1454 expected string // expected hex encoded value
1455 }{
1456 {
1457 name: "zero * zero",
1458 in1: "0",
1459 in2: 0,
1460 expected: "0",
1461 }, {
1462 name: "one * zero",
1463 in1: "1",
1464 in2: 0,
1465 expected: "0",
1466 }, {
1467 name: "zero * one",
1468 in1: "0",
1469 in2: 1,
1470 expected: "0",
1471 }, {
1472 name: "one * one",
1473 in1: "1",
1474 in2: 1,
1475 expected: "1",
1476 }, {
1477 name: "secp256k1 prime-1 * 2",
1478 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1479 in2: 2,
1480 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
1481 }, {
1482 name: "secp256k1 prime * 3",
1483 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1484 in2: 3,
1485 expected: "0",
1486 }, {
1487 name: "secp256k1 prime-1 * 8",
1488 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1489 in2: 8,
1490 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc27",
1491 }, {
1492 // Random samples for first value. The second value is limited
1493 // to 8 since that is the maximum int used in the elliptic curve
1494 // calculations.
1495 name: "random sampling #1",
1496 in1: "b75674dc9180d306c692163ac5e089f7cef166af99645c0c23568ab6d967288a",
1497 in2: 6,
1498 expected: "4c06bd2b6904f228a76c8560a3433bced9a8681d985a2848d407404d186b0280",
1499 }, {
1500 name: "random sampling #2",
1501 in1: "54873298ac2b5ba8591c125ae54931f5ea72040aee07b208d6135476fb5b9c0e",
1502 in2: 3,
1503 expected: "fd9597ca048212f90b543710afdb95e1bf560c20ca17161a8239fd64f212d42a",
1504 }, {
1505 name: "random sampling #3",
1506 in1: "7c30fbd363a74c17e1198f56b090b59bbb6c8755a74927a6cba7a54843506401",
1507 in2: 5,
1508 expected: "6cf4eb20f2447c77657fccb172d38c0aa91ea4ac446dc641fa463a6b5091fba7",
1509 }, {
1510 name: "random sampling #3",
1511 in1: "fb4529be3e027a3d1587d8a500b72f2d312e3577340ef5175f96d113be4c2ceb",
1512 in2: 8,
1513 expected: "da294df1f013d1e8ac3ec52805b979698971abb9a077a8bafcb688a4f261820f",
1514 },
1515 }
1516 for _, test := range tests {
1517 f := new(FieldVal).SetHex(test.in1).Normalize()
1518 expected := new(FieldVal).SetHex(test.expected).Normalize()
1519 result := f.MulInt(test.in2).Normalize()
1520 if !result.Equals(expected) {
1521 t.Errorf(
1522 "%s: wrong result -- got: %v -- want: %v", test.name,
1523 result, expected,
1524 )
1525 continue
1526 }
1527 }
1528 }
1529
1530 // TestFieldMul ensures that multiplying two field values via Mul and Mul2 works
1531 // as expected.
1532 func TestFieldMul(t *testing.T) {
1533 tests := []struct {
1534 name string // test description
1535 in1 string // first hex encoded value
1536 in2 string // second hex encoded value to multiply with
1537 expected string // expected hex encoded value
1538 }{
1539 {
1540 name: "zero * zero",
1541 in1: "0",
1542 in2: "0",
1543 expected: "0",
1544 }, {
1545 name: "one * zero",
1546 in1: "1",
1547 in2: "0",
1548 expected: "0",
1549 }, {
1550 name: "zero * one",
1551 in1: "0",
1552 in2: "1",
1553 expected: "0",
1554 }, {
1555 name: "one * one",
1556 in1: "1",
1557 in2: "1",
1558 expected: "1",
1559 }, {
1560 name: "slightly over prime",
1561 in1: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1ffff",
1562 in2: "1000",
1563 expected: "1ffff3d1",
1564 }, {
1565 name: "secp256k1 prime-1 * 2",
1566 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1567 in2: "2",
1568 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
1569 }, {
1570 name: "secp256k1 prime * 3",
1571 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1572 in2: "3",
1573 expected: "0",
1574 }, {
1575 name: "secp256k1 prime * 3",
1576 in1: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1577 in2: "8",
1578 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc27",
1579 }, {
1580 name: "random sampling #1",
1581 in1: "cfb81753d5ef499a98ecc04c62cb7768c2e4f1740032946db1c12e405248137e",
1582 in2: "58f355ad27b4d75fb7db0442452e732c436c1f7c5a7c4e214fa9cc031426a7d3",
1583 expected: "1018cd2d7c2535235b71e18db9cd98027386328d2fa6a14b36ec663c4c87282b",
1584 }, {
1585 name: "random sampling #2",
1586 in1: "26e9d61d1cdf3920e9928e85fa3df3e7556ef9ab1d14ec56d8b4fc8ed37235bf",
1587 in2: "2dfc4bbe537afee979c644f8c97b31e58be5296d6dbc460091eae630c98511cf",
1588 expected: "da85f48da2dc371e223a1ae63bd30b7e7ee45ae9b189ac43ff357e9ef8cf107a",
1589 }, {
1590 name: "random sampling #3",
1591 in1: "5db64ed5afb71646c8b231585d5b2bf7e628590154e0854c4c29920b999ff351",
1592 in2: "279cfae5eea5d09ade8e6a7409182f9de40981bc31c84c3d3dfe1d933f152e9a",
1593 expected: "2c78fbae91792dd0b157abe3054920049b1879a7cc9d98cfda927d83be411b37",
1594 }, {
1595 name: "random sampling #4",
1596 in1: "b66dfc1f96820b07d2bdbd559c19319a3a73c97ceb7b3d662f4fe75ecb6819e6",
1597 in2: "bf774aba43e3e49eb63a6e18037d1118152568f1a3ac4ec8b89aeb6ff8008ae1",
1598 expected: "c4f016558ca8e950c21c3f7fc15f640293a979c7b01754ee7f8b3340d4902ebb",
1599 },
1600 }
1601 for _, test := range tests {
1602 f1 := new(FieldVal).SetHex(test.in1).Normalize()
1603 f2 := new(FieldVal).SetHex(test.in2).Normalize()
1604 expected := new(FieldVal).SetHex(test.expected).Normalize()
1605 // Ensure multiplying the two values with the result going to another
1606 // variable produces the expected result.
1607 result := new(FieldVal).Mul2(f1, f2).Normalize()
1608 if !result.Equals(expected) {
1609 t.Errorf(
1610 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
1611 result, expected,
1612 )
1613 continue
1614 }
1615 // Ensure multiplying the value to an existing field value produces the
1616 // expected result.
1617 f1.Mul(f2).Normalize()
1618 if !f1.Equals(expected) {
1619 t.Errorf(
1620 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
1621 f1, expected,
1622 )
1623 continue
1624 }
1625 }
1626 }
1627
1628 // TestFieldSquare ensures that squaring field values via Square and SqualVal
1629 // works as expected.
1630 func TestFieldSquare(t *testing.T) {
1631 tests := []struct {
1632 name string // test description
1633 in string // hex encoded value
1634 expected string // expected hex encoded value
1635 }{
1636 {
1637 name: "zero",
1638 in: "0",
1639 expected: "0",
1640 }, {
1641 name: "secp256k1 prime (direct val in with 0 out)",
1642 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1643 expected: "0",
1644 }, {
1645 name: "secp256k1 prime (0 in with direct val out)",
1646 in: "0",
1647 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1648 }, {
1649 name: "secp256k1 prime - 1",
1650 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1651 expected: "1",
1652 }, {
1653 name: "secp256k1 prime - 2",
1654 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
1655 expected: "4",
1656 }, {
1657 name: "random sampling #1",
1658 in: "b0ba920360ea8436a216128047aab9766d8faf468895eb5090fc8241ec758896",
1659 expected: "133896b0b69fda8ce9f648b9a3af38f345290c9eea3cbd35bafcadf7c34653d3",
1660 }, {
1661 name: "random sampling #2",
1662 in: "c55d0d730b1d0285a1599995938b042a756e6e8857d390165ffab480af61cbd5",
1663 expected: "cd81758b3f5877cbe7e5b0a10cebfa73bcbf0957ca6453e63ee8954ab7780bee",
1664 }, {
1665 name: "random sampling #3",
1666 in: "e89c1f9a70d93651a1ba4bca5b78658f00de65a66014a25544d3365b0ab82324",
1667 expected: "39ffc7a43e5dbef78fd5d0354fb82c6d34f5a08735e34df29da14665b43aa1f",
1668 }, {
1669 name: "random sampling #4",
1670 in: "7dc26186079d22bcbe1614aa20ae627e62d72f9be7ad1e99cac0feb438956f05",
1671 expected: "bf86bcfc4edb3d81f916853adfda80c07c57745b008b60f560b1912f95bce8ae",
1672 },
1673 }
1674 for _, test := range tests {
1675 f := new(FieldVal).SetHex(test.in).Normalize()
1676 expected := new(FieldVal).SetHex(test.expected).Normalize()
1677 // Ensure squaring the value with the result going to another variable
1678 // produces the expected result.
1679 result := new(FieldVal).SquareVal(f).Normalize()
1680 if !result.Equals(expected) {
1681 t.Errorf(
1682 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
1683 result, expected,
1684 )
1685 continue
1686 }
1687 // Ensure self squaring an existing field value produces the expected
1688 // result.
1689 f.Square().Normalize()
1690 if !f.Equals(expected) {
1691 t.Errorf(
1692 "%s: unexpected result\ngot: %v\nwant: %v", test.name,
1693 f, expected,
1694 )
1695 continue
1696 }
1697 }
1698 }
1699
1700 // TestFieldSquareRoot ensures that calculating the square root of field values
1701 // via SquareRootVal works as expected for edge cases.
1702 func TestFieldSquareRoot(t *testing.T) {
1703 tests := []struct {
1704 name string // test description
1705 in string // hex encoded value
1706 valid bool // whether the value has a square root
1707 want string // expected hex encoded value
1708 }{
1709 {
1710 name: "secp256k1 prime (as 0 in and out)",
1711 in: "0",
1712 valid: true,
1713 want: "0",
1714 }, {
1715 name: "secp256k1 prime (direct val with 0 out)",
1716 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1717 valid: true,
1718 want: "0",
1719 }, {
1720 name: "secp256k1 prime (as 0 in direct val out)",
1721 in: "0",
1722 valid: true,
1723 want: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1724 }, {
1725 name: "secp256k1 prime-1",
1726 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1727 valid: false,
1728 want: "0000000000000000000000000000000000000000000000000000000000000001",
1729 }, {
1730 name: "secp256k1 prime-2",
1731 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
1732 valid: false,
1733 want: "210c790573632359b1edb4302c117d8a132654692c3feeb7de3a86ac3f3b53f7",
1734 }, {
1735 name: "(secp256k1 prime-2)^2",
1736 in: "0000000000000000000000000000000000000000000000000000000000000004",
1737 valid: true,
1738 want: "0000000000000000000000000000000000000000000000000000000000000002",
1739 }, {
1740 name: "value 1",
1741 in: "0000000000000000000000000000000000000000000000000000000000000001",
1742 valid: true,
1743 want: "0000000000000000000000000000000000000000000000000000000000000001",
1744 }, {
1745 name: "value 2",
1746 in: "0000000000000000000000000000000000000000000000000000000000000002",
1747 valid: true,
1748 want: "210c790573632359b1edb4302c117d8a132654692c3feeb7de3a86ac3f3b53f7",
1749 }, {
1750 name: "random sampling 1",
1751 in: "16fb970147a9acc73654d4be233cc48b875ce20a2122d24f073d29bd28805aca",
1752 valid: false,
1753 want: "6a27dcfca440cf7930a967be533b9620e397f122787c53958aaa7da7ad3d89a4",
1754 }, {
1755 name: "square of random sampling 1",
1756 in: "f4a8c3738ace0a1c3abf77737ae737f07687b5e24c07a643398298bd96893a18",
1757 valid: true,
1758 want: "e90468feb8565338c9ab2b41dcc33b7478a31df5dedd2db0f8c2d641d77fa165",
1759 }, {
1760 name: "random sampling 2",
1761 in: "69d1323ce9f1f7b3bd3c7320b0d6311408e30281e273e39a0d8c7ee1c8257919",
1762 valid: true,
1763 want: "61f4a7348274a52d75dfe176b8e3aaff61c1c833b6678260ba73def0fb2ad148",
1764 }, {
1765 name: "random sampling 3",
1766 in: "e0debf988ae098ecda07d0b57713e97c6d213db19753e8c95aa12a2fc1cc5272",
1767 valid: false,
1768 want: "6e1cc9c311d33d901670135244f994b1ea39501f38002269b34ce231750cfbac",
1769 }, {
1770 name: "random sampling 4",
1771 in: "dcd394f91f74c2ba16aad74a22bb0ed47fe857774b8f2d6c09e28bfb14642878",
1772 valid: true,
1773 want: "72b22fe6f173f8bcb21898806142ed4c05428601256eafce5d36c1b08fb82bab",
1774 },
1775 }
1776 for _, test := range tests {
1777 input := new(FieldVal).SetHex(test.in).Normalize()
1778 want := new(FieldVal).SetHex(test.want).Normalize()
1779 // Calculate the square root and enusre the validity flag matches the
1780 // expected value.
1781 var result FieldVal
1782 isValid := result.SquareRootVal(input)
1783 if isValid != test.valid {
1784 t.Errorf(
1785 "%s: mismatched validity -- got %v, want %v", test.name,
1786 isValid, test.valid,
1787 )
1788 continue
1789 }
1790 // Ensure the calculated result matches the expected value.
1791 result.Normalize()
1792 if !result.Equals(want) {
1793 t.Errorf(
1794 "%s: d wrong result\ngot: %v\nwant: %v", test.name, result,
1795 want,
1796 )
1797 continue
1798 }
1799 }
1800 }
1801
1802 // TestFieldSquareRootRandom ensures that calculating the square root for random
1803 // field values works as expected by also performing the same operation with big
1804 // ints and comparing the results.
1805 func TestFieldSquareRootRandom(t *testing.T) {
1806 // Use a unique random seed each test instance and log it if the tests fail.
1807 seed := time.Now().Unix()
1808 rng := rand.New(rand.NewSource(seed))
1809 defer func(t *testing.T, seed int64) {
1810 if t.Failed() {
1811 t.Logf("random seed: %d", seed)
1812 }
1813 }(t, seed)
1814 for i := 0; i < 100; i++ {
1815 // Generate big integer and field value with the same random value.
1816 bigIntVal, fVal := randIntAndFieldVal(t, rng)
1817 // Calculate the square root of the value using big ints.
1818 bigIntResult := new(big.Int).ModSqrt(bigIntVal, curveParams.P)
1819 bigIntHasSqrt := bigIntResult != nil
1820 // Calculate the square root of the value using a field value.
1821 var fValResult FieldVal
1822 fValHasSqrt := fValResult.SquareRootVal(fVal)
1823 // Ensure they match.
1824 if bigIntHasSqrt != fValHasSqrt {
1825 t.Fatalf(
1826 "mismatched square root existence\nbig int in: %x\nfield "+
1827 "in: %v\nbig int result: %v\nfield result %v", bigIntVal,
1828 fVal,
1829 bigIntHasSqrt, fValHasSqrt,
1830 )
1831 }
1832 if !fValHasSqrt {
1833 continue
1834 }
1835 bigIntResultHex := fmt.Sprintf("%064x", bigIntResult)
1836 fieldValResultHex := fmt.Sprintf("%v", fValResult)
1837 if bigIntResultHex != fieldValResultHex {
1838 t.Fatalf(
1839 "mismatched square root\nbig int in: %x\nfield in: %v\n"+
1840 "big int result: %x\nfield result %v", bigIntVal, fVal,
1841 bigIntResult, fValResult,
1842 )
1843 }
1844 }
1845 }
1846
1847 // TestFieldInverse ensures that finding the multiplicative inverse via Inverse
1848 // works as expected.
1849 func TestFieldInverse(t *testing.T) {
1850 tests := []struct {
1851 name string // test description
1852 in string // hex encoded value
1853 expected string // expected hex encoded value
1854 }{
1855 {
1856 name: "zero",
1857 in: "0",
1858 expected: "0",
1859 }, {
1860 name: "secp256k1 prime (direct val in with 0 out)",
1861 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1862 expected: "0",
1863 }, {
1864 name: "secp256k1 prime (0 in with direct val out)",
1865 in: "0",
1866 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
1867 }, {
1868 name: "secp256k1 prime - 1",
1869 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1870 expected: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
1871 }, {
1872 name: "secp256k1 prime - 2",
1873 in: "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d",
1874 expected: "7fffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffe17",
1875 }, {
1876 name: "random sampling #1",
1877 in: "16fb970147a9acc73654d4be233cc48b875ce20a2122d24f073d29bd28805aca",
1878 expected: "987aeb257b063df0c6d1334051c47092b6d8766c4bf10c463786d93f5bc54354",
1879 }, {
1880 name: "random sampling #2",
1881 in: "69d1323ce9f1f7b3bd3c7320b0d6311408e30281e273e39a0d8c7ee1c8257919",
1882 expected: "49340981fa9b8d3dad72de470b34f547ed9179c3953797d0943af67806f4bb6",
1883 }, {
1884 name: "random sampling #3",
1885 in: "e0debf988ae098ecda07d0b57713e97c6d213db19753e8c95aa12a2fc1cc5272",
1886 expected: "64f58077b68af5b656b413ea366863f7b2819f8d27375d9c4d9804135ca220c2",
1887 }, {
1888 name: "random sampling #4",
1889 in: "dcd394f91f74c2ba16aad74a22bb0ed47fe857774b8f2d6c09e28bfb14642878",
1890 expected: "fb848ec64d0be572a63c38fe83df5e7f3d032f60bf8c969ef67d36bf4ada22a9",
1891 },
1892 }
1893 for _, test := range tests {
1894 f := new(FieldVal).SetHex(test.in).Normalize()
1895 expected := new(FieldVal).SetHex(test.expected).Normalize()
1896 result := f.Inverse().Normalize()
1897 if !result.Equals(expected) {
1898 t.Errorf(
1899 "%s: d wrong result\ngot: %v\nwant: %v", test.name, result,
1900 expected,
1901 )
1902 continue
1903 }
1904 }
1905 }
1906
1907 // TestFieldIsGtOrEqPrimeMinusOrder ensures that field values report whether or
1908 // not they are greater than or equal to the field prime minus the group order
1909 // as expected for edge cases.
1910 func TestFieldIsGtOrEqPrimeMinusOrder(t *testing.T) {
1911 tests := []struct {
1912 name string // test description
1913 in string // hex encoded test value
1914 expected bool // expected result
1915 }{
1916 {
1917 name: "zero",
1918 in: "0",
1919 expected: false,
1920 }, {
1921 name: "one",
1922 in: "1",
1923 expected: false,
1924 }, {
1925 name: "p - n - 1",
1926 in: "14551231950b75fc4402da1722fc9baed",
1927 expected: false,
1928 }, {
1929 name: "p - n",
1930 in: "14551231950b75fc4402da1722fc9baee",
1931 expected: true,
1932 }, {
1933 name: "p - n + 1",
1934 in: "14551231950b75fc4402da1722fc9baef",
1935 expected: true,
1936 }, {
1937 name: "over p - n word one",
1938 in: "14551231950b75fc4402da17233c9baee",
1939 expected: true,
1940 }, {
1941 name: "over p - n word two",
1942 in: "14551231950b75fc4403da1722fc9baee",
1943 expected: true,
1944 }, {
1945 name: "over p - n word three",
1946 in: "14551231950b79fc4402da1722fc9baee",
1947 expected: true,
1948 }, {
1949 name: "over p - n word four",
1950 in: "14551241950b75fc4402da1722fc9baee",
1951 expected: true,
1952 }, {
1953 name: "over p - n word five",
1954 in: "54551231950b75fc4402da1722fc9baee",
1955 expected: true,
1956 }, {
1957 name: "over p - n word six",
1958 in: "100000014551231950b75fc4402da1722fc9baee",
1959 expected: true,
1960 }, {
1961 name: "over p - n word seven",
1962 in: "000000000000000000400000000000014551231950b75fc4402da1722fc9baee",
1963 expected: true,
1964 }, {
1965 name: "over p - n word eight",
1966 in: "000000000001000000000000000000014551231950b75fc4402da1722fc9baee",
1967 expected: true,
1968 }, {
1969 name: "over p - n word nine",
1970 in: "000004000000000000000000000000014551231950b75fc4402da1722fc9baee",
1971 expected: true,
1972 },
1973 }
1974 for _, test := range tests {
1975 result := new(FieldVal).SetHex(test.in).IsGtOrEqPrimeMinusOrder()
1976 if result != test.expected {
1977 t.Errorf(
1978 "%s: unexpected result -- got: %v, want: %v", test.name,
1979 result, test.expected,
1980 )
1981 continue
1982 }
1983 }
1984 }
1985
1986 // TestFieldIsGtOrEqPrimeMinusOrderRandom ensures that field values report
1987 // whether or not they are greater than or equal to the field prime minus the
1988 // group order as expected by also performing the same operation with big ints
1989 // and comparing the results.
1990 func TestFieldIsGtOrEqPrimeMinusOrderRandom(t *testing.T) {
1991 // Use a unique random seed each test instance and log it if the tests fail.
1992 seed := time.Now().Unix()
1993 rng := rand.New(rand.NewSource(seed))
1994 defer func(t *testing.T, seed int64) {
1995 if t.Failed() {
1996 t.Logf("random seed: %d", seed)
1997 }
1998 }(t, seed)
1999 bigPMinusN := new(big.Int).Sub(curveParams.P, curveParams.N)
2000 for i := 0; i < 100; i++ {
2001 // Generate big integer and field value with the same random value.
2002 bigIntVal, fVal := randIntAndFieldVal(t, rng)
2003 // Determine the value is greater than or equal to the prime minus the
2004 // order using big ints.
2005 bigIntResult := bigIntVal.Cmp(bigPMinusN) >= 0
2006 // Determine the value is greater than or equal to the prime minus the
2007 // order using a field value.
2008 fValResult := fVal.IsGtOrEqPrimeMinusOrder()
2009 // Ensure they match.
2010 if bigIntResult != fValResult {
2011 t.Fatalf(
2012 "mismatched is gt or eq prime minus order\nbig int in: "+
2013 "%x\nscalar in: %v\nbig int result: %v\nscalar result %v",
2014 bigIntVal, fVal, bigIntResult, fValResult,
2015 )
2016 }
2017 }
2018 }
2019