1
2
3
4
5 package secp256k1
6
7 import (
8 "bytes"
9 "encoding/hex"
10 "fmt"
11 "math/big"
12 "math/rand"
13 "reflect"
14 "testing"
15 "time"
16 )
17
18
19
20
21
22
23
24
25
26 func (s *ModNScalar) SetHex(hexString string) *ModNScalar {
27 if len(hexString)%2 != 0 {
28 hexString = "0" + hexString
29 }
30 bytes, _ := hex.DecodeString(hexString)
31 s.SetByteSlice(bytes)
32 return s
33 }
34
35
36
37 func randModNScalar(t *testing.T, rng *rand.Rand) *ModNScalar {
38 t.Helper()
39
40 var buf [32]byte
41 if _, err := rng.Read(buf[:]); err != nil {
42 t.Fatalf("failed to read random: %v", err)
43 }
44
45
46 var modNVal ModNScalar
47 modNVal.SetBytes(&buf)
48 return &modNVal
49 }
50
51
52
53 func randIntAndModNScalar(t *testing.T, rng *rand.Rand) (*big.Int, *ModNScalar) {
54 t.Helper()
55
56 var buf [32]byte
57 if _, err := rng.Read(buf[:]); err != nil {
58 t.Fatalf("failed to read random: %v", err)
59 }
60
61
62 bigIntVal := new(big.Int).SetBytes(buf[:])
63 bigIntVal.Mod(bigIntVal, curveParams.N)
64 var modNVal ModNScalar
65 modNVal.SetBytes(&buf)
66 return bigIntVal, &modNVal
67 }
68
69
70
71 func TestModNScalarZero(t *testing.T) {
72 var s ModNScalar
73 s.SetHex("a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5")
74 s.Zero()
75 for idx, rawInt := range s.n {
76 if rawInt != 0 {
77 t.Errorf("internal integer at index #%d is not zero - got %d", idx,
78 rawInt)
79 }
80 }
81 }
82
83
84
85 func TestModNScalarIsZero(t *testing.T) {
86 var s ModNScalar
87 if !s.IsZero() {
88 t.Errorf("new scalar is not zero - got %v (rawints %x)", s, s.n)
89 }
90 if s.IsZeroBit() != 1 {
91 t.Errorf("new scalar is not zero - got %v (rawints %x)", s, s.n)
92 }
93
94 s.SetInt(1)
95 if s.IsZero() {
96 t.Errorf("claims zero for nonzero scalar - got %v (rawints %x)", s, s.n)
97 }
98 if s.IsZeroBit() == 1 {
99 t.Errorf("claims zero for nonzero scalar - got %v (rawints %x)", s, s.n)
100 }
101
102 s.SetInt(0)
103 if !s.IsZero() {
104 t.Errorf("claims nonzero for zero scalar - got %v (rawints %x)", s, s.n)
105 }
106 if s.IsZeroBit() != 1 {
107 t.Errorf("claims nonzero for zero scalar - got %v (rawints %x)", s, s.n)
108 }
109
110 s.SetInt(1)
111 s.Zero()
112 if !s.IsZero() {
113 t.Errorf("claims nonzero for zero scalar - got %v (rawints %x)", s, s.n)
114 }
115 if s.IsZeroBit() != 1 {
116 t.Errorf("claims nonzero for zero scalar - got %v (rawints %x)", s, s.n)
117 }
118 }
119
120
121
122 func TestModNScalarSetInt(t *testing.T) {
123 tests := []struct {
124 name string
125 in uint32
126 expected [8]uint32
127 }{{
128 name: "five",
129 in: 5,
130 expected: [8]uint32{5, 0, 0, 0, 0, 0, 0, 0},
131 }, {
132 name: "group order word zero",
133 in: orderWordZero,
134 expected: [8]uint32{orderWordZero, 0, 0, 0, 0, 0, 0, 0},
135 }, {
136 name: "group order word zero + 1",
137 in: orderWordZero + 1,
138 expected: [8]uint32{orderWordZero + 1, 0, 0, 0, 0, 0, 0, 0},
139 }, {
140 name: "2^32 - 1",
141 in: 4294967295,
142 expected: [8]uint32{4294967295, 0, 0, 0, 0, 0, 0, 0},
143 }}
144
145 for _, test := range tests {
146 s := new(ModNScalar).SetInt(test.in)
147 if !reflect.DeepEqual(s.n, test.expected) {
148 t.Errorf("%s: wrong result\ngot: %v\nwant: %v", test.name, s.n,
149 test.expected)
150 continue
151 }
152 }
153 }
154
155
156
157
158 func TestModNScalarSetBytes(t *testing.T) {
159 tests := []struct {
160 name string
161 in string
162 expected [8]uint32
163 overflow bool
164 }{{
165 name: "zero",
166 in: "00",
167 expected: [8]uint32{0, 0, 0, 0, 0, 0, 0, 0},
168 overflow: false,
169 }, {
170 name: "group order (aka 0)",
171 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
172 expected: [8]uint32{0, 0, 0, 0, 0, 0, 0, 0},
173 overflow: true,
174 }, {
175 name: "group order - 1",
176 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
177 expected: [8]uint32{
178 0xd0364140, 0xbfd25e8c, 0xaf48a03b, 0xbaaedce6,
179 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff,
180 },
181 overflow: false,
182 }, {
183 name: "group order + 1 (aka 1, overflow in word zero)",
184 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
185 expected: [8]uint32{1, 0, 0, 0, 0, 0, 0, 0},
186 overflow: true,
187 }, {
188 name: "group order word zero",
189 in: "d0364141",
190 expected: [8]uint32{0xd0364141, 0, 0, 0, 0, 0, 0, 0},
191 overflow: false,
192 }, {
193 name: "group order word zero and one",
194 in: "bfd25e8cd0364141",
195 expected: [8]uint32{0xd0364141, 0xbfd25e8c, 0, 0, 0, 0, 0, 0},
196 overflow: false,
197 }, {
198 name: "group order words zero, one, and two",
199 in: "af48a03bbfd25e8cd0364141",
200 expected: [8]uint32{0xd0364141, 0xbfd25e8c, 0xaf48a03b, 0, 0, 0, 0, 0},
201 overflow: false,
202 }, {
203 name: "overflow in word one",
204 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8dd0364141",
205 expected: [8]uint32{0, 1, 0, 0, 0, 0, 0, 0},
206 overflow: true,
207 }, {
208 name: "overflow in word two",
209 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03cbfd25e8cd0364141",
210 expected: [8]uint32{0, 0, 1, 0, 0, 0, 0, 0},
211 overflow: true,
212 }, {
213 name: "overflow in word three",
214 in: "fffffffffffffffffffffffffffffffebaaedce7af48a03bbfd25e8cd0364141",
215 expected: [8]uint32{0, 0, 0, 1, 0, 0, 0, 0},
216 overflow: true,
217 }, {
218 name: "overflow in word four",
219 in: "ffffffffffffffffffffffffffffffffbaaedce6af48a03bbfd25e8cd0364141",
220 expected: [8]uint32{0, 0, 0, 0, 1, 0, 0, 0},
221 overflow: true,
222 }, {
223 name: "(group order - 1) * 2 NOT mod N, truncated >32 bytes",
224 in: "01fffffffffffffffffffffffffffffffd755db9cd5e9140777fa4bd19a06c8284",
225 expected: [8]uint32{
226 0x19a06c82, 0x777fa4bd, 0xcd5e9140, 0xfd755db9,
227 0xffffffff, 0xffffffff, 0xffffffff, 0x01ffffff,
228 },
229 overflow: false,
230 }, {
231 name: "alternating bits",
232 in: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
233 expected: [8]uint32{
234 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
235 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5, 0xa5a5a5a5,
236 },
237 overflow: false,
238 }, {
239 name: "alternating bits 2",
240 in: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
241 expected: [8]uint32{
242 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a,
243 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a,
244 },
245 overflow: false,
246 }}
247
248 for _, test := range tests {
249 inBytes := hexToBytes(test.in)
250
251
252 var s ModNScalar
253 overflow := s.SetByteSlice(inBytes)
254 if !reflect.DeepEqual(s.n, test.expected) {
255 t.Errorf("%s: unexpected result\ngot: %x\nwant: %x", test.name, s.n,
256 test.expected)
257 continue
258 }
259
260
261
262 if overflow != test.overflow {
263 t.Errorf("%s: unexpected overflow -- got: %v, want: %v", test.name,
264 overflow, test.overflow)
265 continue
266 }
267
268
269 var s2 ModNScalar
270 var b32 [32]byte
271 truncatedInBytes := inBytes
272 if len(truncatedInBytes) > 32 {
273 truncatedInBytes = truncatedInBytes[:32]
274 }
275 copy(b32[32-len(truncatedInBytes):], truncatedInBytes)
276 overflow = s2.SetBytes(&b32) != 0
277 if !reflect.DeepEqual(s2.n, test.expected) {
278 t.Errorf("%s: unexpected result\ngot: %x\nwant: %x", test.name,
279 s2.n, test.expected)
280 continue
281 }
282
283
284
285 if overflow != test.overflow {
286 t.Errorf("%s: unexpected overflow -- got: %v, want: %v", test.name,
287 overflow, test.overflow)
288 continue
289 }
290 }
291 }
292
293
294
295
296 func TestModNScalarBytes(t *testing.T) {
297 tests := []struct {
298 name string
299 in string
300 expected string
301 overflow bool
302 }{{
303 name: "zero",
304 in: "0",
305 expected: "0000000000000000000000000000000000000000000000000000000000000000",
306 }, {
307 name: "group order (aka 0)",
308 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
309 expected: "0000000000000000000000000000000000000000000000000000000000000000",
310 }, {
311 name: "group order - 1",
312 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
313 expected: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
314 }, {
315 name: "group order + 1 (aka 1, overflow in word zero)",
316 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
317 expected: "0000000000000000000000000000000000000000000000000000000000000001",
318 }, {
319 name: "group order word zero",
320 in: "d0364141",
321 expected: "00000000000000000000000000000000000000000000000000000000d0364141",
322 }, {
323 name: "group order word zero and one",
324 in: "bfd25e8cd0364141",
325 expected: "000000000000000000000000000000000000000000000000bfd25e8cd0364141",
326 }, {
327 name: "group order words zero, one, and two",
328 in: "af48a03bbfd25e8cd0364141",
329 expected: "0000000000000000000000000000000000000000af48a03bbfd25e8cd0364141",
330 }, {
331 name: "overflow in word one",
332 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8dd0364141",
333 expected: "0000000000000000000000000000000000000000000000000000000100000000",
334 }, {
335 name: "overflow in word two",
336 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03cbfd25e8cd0364141",
337 expected: "0000000000000000000000000000000000000000000000010000000000000000",
338 }, {
339 name: "overflow in word three",
340 in: "fffffffffffffffffffffffffffffffebaaedce7af48a03bbfd25e8cd0364141",
341 expected: "0000000000000000000000000000000000000001000000000000000000000000",
342 }, {
343 name: "overflow in word four",
344 in: "ffffffffffffffffffffffffffffffffbaaedce6af48a03bbfd25e8cd0364141",
345 expected: "0000000000000000000000000000000100000000000000000000000000000000",
346 }, {
347 name: "alternating bits",
348 in: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
349 expected: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
350 }, {
351 name: "alternating bits 2",
352 in: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
353 expected: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
354 }}
355
356 for _, test := range tests {
357 s := new(ModNScalar).SetHex(test.in)
358 expected := hexToBytes(test.expected)
359
360
361 gotBytes := s.Bytes()
362 if !bytes.Equal(gotBytes[:], expected) {
363 t.Errorf("%s: unexpected result\ngot: %x\nwant: %x", test.name,
364 gotBytes, expected)
365 continue
366 }
367
368
369 var b32 [32]byte
370 s.PutBytes(&b32)
371 if !bytes.Equal(b32[:], expected) {
372 t.Errorf("%s: unexpected result\ngot: %x\nwant: %x", test.name,
373 b32, expected)
374 continue
375 }
376
377
378 var buffer [64]byte
379 s.PutBytesUnchecked(buffer[:])
380 if !bytes.Equal(buffer[:32], expected) {
381 t.Errorf("%s: unexpected result\ngot: %x\nwant: %x", test.name,
382 buffer[:32], expected)
383 continue
384 }
385 }
386 }
387
388
389
390 func TestModNScalarIsOdd(t *testing.T) {
391 tests := []struct {
392 name string
393 in string
394 expected bool
395 }{{
396 name: "zero",
397 in: "0",
398 expected: false,
399 }, {
400 name: "one",
401 in: "1",
402 expected: true,
403 }, {
404 name: "two",
405 in: "2",
406 expected: false,
407 }, {
408 name: "2^32 - 1",
409 in: "ffffffff",
410 expected: true,
411 }, {
412 name: "2^64 - 2",
413 in: "fffffffffffffffe",
414 expected: false,
415 }, {
416 name: "group order (aka 0)",
417 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
418 expected: false,
419 }, {
420 name: "group order + 1 (aka 1)",
421 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
422 expected: true,
423 }}
424
425 for _, test := range tests {
426 result := new(ModNScalar).SetHex(test.in).IsOdd()
427 if result != test.expected {
428 t.Errorf("%s: wrong result -- got: %v, want: %v", test.name,
429 result, test.expected)
430 continue
431 }
432 }
433 }
434
435
436
437 func TestModNScalarEquals(t *testing.T) {
438 tests := []struct {
439 name string
440 in1 string
441 in2 string
442 expected bool
443 }{{
444 name: "0 == 0?",
445 in1: "0",
446 in2: "0",
447 expected: true,
448 }, {
449 name: "0 == 1?",
450 in1: "0",
451 in2: "1",
452 expected: false,
453 }, {
454 name: "1 == 0?",
455 in1: "1",
456 in2: "0",
457 expected: false,
458 }, {
459 name: "2^32 - 1 == 2^32 - 1?",
460 in1: "ffffffff",
461 in2: "ffffffff",
462 expected: true,
463 }, {
464 name: "2^64 - 1 == 2^64 - 2?",
465 in1: "ffffffffffffffff",
466 in2: "fffffffffffffffe",
467 expected: false,
468 }, {
469 name: "0 == group order?",
470 in1: "0",
471 in2: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
472 expected: true,
473 }, {
474 name: "1 == group order + 1?",
475 in1: "1",
476 in2: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142",
477 expected: true,
478 }}
479
480 for _, test := range tests {
481 s1 := new(ModNScalar).SetHex(test.in1)
482 s2 := new(ModNScalar).SetHex(test.in2)
483 result := s1.Equals(s2)
484 if result != test.expected {
485 t.Errorf("%s: wrong result -- got: %v, want: %v", test.name, result,
486 test.expected)
487 continue
488 }
489 }
490 }
491
492
493
494 func TestModNScalarEqualsRandom(t *testing.T) {
495
496 seed := time.Now().Unix()
497 rng := rand.New(rand.NewSource(seed))
498 defer func(t *testing.T, seed int64) {
499 if t.Failed() {
500 t.Logf("random seed: %d", seed)
501 }
502 }(t, seed)
503
504 for i := 0; i < 100; i++ {
505
506 s := randModNScalar(t, rng)
507 if !s.Equals(s) {
508 t.Fatalf("failed equality check\nscalar in: %v", s)
509 }
510
511
512 randomWord := rng.Int31n(int32(len(s.n)))
513 randomBit := uint32(1 << uint32(rng.Int31n(32)))
514 s2 := new(ModNScalar).Set(s)
515 s2.n[randomWord] ^= randomBit
516 if s2.Equals(s) {
517 t.Fatalf("failed inequality check\nscalar in: %v", s2)
518 }
519 }
520 }
521
522
523
524 func TestModNScalarAdd(t *testing.T) {
525 tests := []struct {
526 name string
527 in1 string
528 in2 string
529 expected string
530 }{{
531 name: "zero + one",
532 in1: "0",
533 in2: "1",
534 expected: "1",
535 }, {
536 name: "one + zero",
537 in1: "1",
538 in2: "0",
539 expected: "1",
540 }, {
541 name: "group order (aka 0) + 1 (gets reduced, no overflow)",
542 in1: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
543 in2: "1",
544 expected: "1",
545 }, {
546 name: "group order - 1 + 1 (aka 0, overflow to prime)",
547 in1: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
548 in2: "1",
549 expected: "0",
550 }, {
551 name: "group order - 1 + 2 (aka 1, overflow in word zero)",
552 in1: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
553 in2: "2",
554 expected: "1",
555 }, {
556 name: "overflow in word one",
557 in1: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8bd0364141",
558 in2: "100000001",
559 expected: "1",
560 }, {
561 name: "overflow in word two",
562 in1: "fffffffffffffffffffffffffffffffebaaedce6af48a03abfd25e8cd0364141",
563 in2: "10000000000000001",
564 expected: "1",
565 }, {
566 name: "overflow in word three",
567 in1: "fffffffffffffffffffffffffffffffebaaedce5af48a03bbfd25e8cd0364141",
568 in2: "1000000000000000000000001",
569 expected: "1",
570 }, {
571 name: "overflow in word four",
572 in1: "fffffffffffffffffffffffffffffffdbaaedce6af48a03bbfd25e8cd0364141",
573 in2: "100000000000000000000000000000001",
574 expected: "1",
575 }, {
576 name: "overflow in word five",
577 in1: "fffffffffffffffffffffffefffffffebaaedce6af48a03bbfd25e8cd0364141",
578 in2: "10000000000000000000000000000000000000001",
579 expected: "1",
580 }, {
581 name: "overflow in word six",
582 in1: "fffffffffffffffefffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
583 in2: "1000000000000000000000000000000000000000000000001",
584 expected: "1",
585 }, {
586 name: "overflow in word seven",
587 in1: "fffffffefffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
588 in2: "100000000000000000000000000000000000000000000000000000001",
589 expected: "1",
590 }, {
591 name: "alternating bits",
592 in1: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
593 in2: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
594 expected: "14551231950b75fc4402da1732fc9bebe",
595 }, {
596 name: "alternating bits 2",
597 in1: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
598 in2: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
599 expected: "14551231950b75fc4402da1732fc9bebe",
600 }}
601
602 for _, test := range tests {
603
604 s1 := new(ModNScalar).SetHex(test.in1)
605 s2 := new(ModNScalar).SetHex(test.in2)
606 expected := new(ModNScalar).SetHex(test.expected)
607
608
609 s1.Add(s2)
610 if !s1.Equals(expected) {
611 t.Errorf("%s: unexpected result\ngot: %x\nwant: %x", test.name,
612 s1, expected)
613 continue
614 }
615 }
616 }
617
618
619
620
621 func TestModNScalarAddRandom(t *testing.T) {
622
623 seed := time.Now().Unix()
624 rng := rand.New(rand.NewSource(seed))
625 defer func(t *testing.T, seed int64) {
626 if t.Failed() {
627 t.Logf("random seed: %d", seed)
628 }
629 }(t, seed)
630
631 for i := 0; i < 100; i++ {
632
633 bigIntVal1, modNVal1 := randIntAndModNScalar(t, rng)
634 bigIntVal2, modNVal2 := randIntAndModNScalar(t, rng)
635
636
637 bigIntResult := new(big.Int).Add(bigIntVal1, bigIntVal2)
638 bigIntResult.Mod(bigIntResult, curveParams.N)
639
640
641 modNValResult := new(ModNScalar).Add2(modNVal1, modNVal2)
642
643
644 bigIntResultHex := fmt.Sprintf("%064x", bigIntResult)
645 modNResultHex := fmt.Sprintf("%v", modNValResult)
646 if bigIntResultHex != modNResultHex {
647 t.Fatalf("mismatched add\nbig int in 1: %x\nbig int in 2: %x\n"+
648 "scalar in 1: %v\nscalar in 2: %v\nbig int result: %x\nscalar "+
649 "result %v", bigIntVal1, bigIntVal2, modNVal1, modNVal2,
650 bigIntResult, modNValResult)
651 }
652 }
653 }
654
655
656
657 func TestAccumulator96Add(t *testing.T) {
658 tests := []struct {
659 name string
660 start accumulator96
661 in uint64
662 expected accumulator96
663 }{{
664 name: "0 + 0 = 0",
665 start: accumulator96{[3]uint32{0, 0, 0}},
666 in: 0,
667 expected: accumulator96{[3]uint32{0, 0, 0}},
668 }, {
669 name: "overflow in word zero",
670 start: accumulator96{[3]uint32{0xffffffff, 0, 0}},
671 in: 1,
672 expected: accumulator96{[3]uint32{0, 1, 0}},
673 }, {
674 name: "overflow in word one",
675 start: accumulator96{[3]uint32{0, 0xffffffff, 0}},
676 in: 0x100000000,
677 expected: accumulator96{[3]uint32{0, 0, 1}},
678 }, {
679 name: "overflow in words one and two",
680 start: accumulator96{[3]uint32{0xffffffff, 0xffffffff, 0}},
681 in: 1,
682 expected: accumulator96{[3]uint32{0, 0, 1}},
683 }, {
684
685
686 name: "max result from eight adds of max uint32 multiplications",
687 start: accumulator96{[3]uint32{7, 4294967282, 6}},
688 in: 18446744065119617025,
689 expected: accumulator96{[3]uint32{8, 4294967280, 7}},
690 }}
691
692 for _, test := range tests {
693 acc := test.start
694 acc.Add(test.in)
695 if acc.n != test.expected.n {
696 t.Errorf("%s: wrong result\ngot: %v\nwant: %v", test.name, acc.n,
697 test.expected.n)
698 }
699 }
700 }
701
702
703
704 func TestModNScalarMul(t *testing.T) {
705 tests := []struct {
706 name string
707 in1 string
708 in2 string
709 expected string
710 }{{
711 name: "zero * zero",
712 in1: "0",
713 in2: "0",
714 expected: "0",
715 }, {
716 name: "one * zero",
717 in1: "1",
718 in2: "0",
719 expected: "0",
720 }, {
721 name: "one * one",
722 in1: "1",
723 in2: "1",
724 expected: "1",
725 }, {
726 name: "(group order-1) * 2",
727 in1: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
728 in2: "2",
729 expected: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f",
730 }, {
731 name: "(group order-1) * (group order-1)",
732 in1: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
733 in2: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
734 expected: "1",
735 }, {
736 name: "slightly over group order",
737 in1: "7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1",
738 in2: "2",
739 expected: "1",
740 }, {
741 name: "group order (aka 0) * 3",
742 in1: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
743 in2: "3",
744 expected: "0",
745 }, {
746 name: "overflow in word eight",
747 in1: "100000000000000000000000000000000",
748 in2: "100000000000000000000000000000000",
749 expected: "14551231950b75fc4402da1732fc9bebf",
750 }, {
751 name: "overflow in word nine",
752 in1: "1000000000000000000000000000000000000",
753 in2: "1000000000000000000000000000000000000",
754 expected: "14551231950b75fc4402da1732fc9bebf00000000",
755 }, {
756 name: "overflow in word ten",
757 in1: "10000000000000000000000000000000000000000",
758 in2: "10000000000000000000000000000000000000000",
759 expected: "14551231950b75fc4402da1732fc9bebf0000000000000000",
760 }, {
761 name: "overflow in word eleven",
762 in1: "100000000000000000000000000000000000000000000",
763 in2: "100000000000000000000000000000000000000000000",
764 expected: "14551231950b75fc4402da1732fc9bebf000000000000000000000000",
765 }, {
766 name: "overflow in word twelve",
767 in1: "1000000000000000000000000000000000000000000000000",
768 in2: "1000000000000000000000000000000000000000000000000",
769 expected: "4551231950b75fc4402da1732fc9bec04551231950b75fc4402da1732fc9bebf",
770 }, {
771 name: "overflow in word thirteen",
772 in1: "10000000000000000000000000000000000000000000000000000",
773 in2: "10000000000000000000000000000000000000000000000000000",
774 expected: "50b75fc4402da1732fc9bec09d671cd51b343a1b66926b57d2a4c1c61536bda7",
775 }, {
776 name: "overflow in word fourteen",
777 in1: "100000000000000000000000000000000000000000000000000000000",
778 in2: "100000000000000000000000000000000000000000000000000000000",
779 expected: "402da1732fc9bec09d671cd581c69bc59509b0b074ec0aea8f564d667ec7eb3c",
780 }, {
781 name: "overflow in word fifteen",
782 in1: "1000000000000000000000000000000000000000000000000000000000000",
783 in2: "1000000000000000000000000000000000000000000000000000000000000",
784 expected: "2fc9bec09d671cd581c69bc5e697f5e41f12c33a0a7b6f4e3302b92ea029cecd",
785 }, {
786 name: "double overflow in internal accumulator",
787 in1: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
788 in2: "55555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c2",
789 expected: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b7f",
790 }, {
791 name: "alternating bits",
792 in1: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
793 in2: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
794 expected: "88edea3d29272800e7988455cfdf19b039dbfbb1c93b5b44a48c2ba462316838",
795 }, {
796 name: "alternating bits 2",
797 in1: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
798 in2: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
799 expected: "88edea3d29272800e7988455cfdf19b039dbfbb1c93b5b44a48c2ba462316838",
800 }}
801
802 for _, test := range tests {
803 v1 := new(ModNScalar).SetHex(test.in1)
804 v2 := new(ModNScalar).SetHex(test.in2)
805 expected := new(ModNScalar).SetHex(test.expected)
806
807
808 result := new(ModNScalar).Mul2(v1, v2)
809 if !result.Equals(expected) {
810 t.Errorf("%s: wrong result\ngot: %v\nwant: %v", test.name, result,
811 expected)
812 continue
813 }
814
815
816
817 result2 := new(ModNScalar).Set(v1).Mul(v2)
818 if !result2.Equals(expected) {
819 t.Errorf("%s: wrong result\ngot: %v\nwant: %v", test.name, result2,
820 expected)
821 continue
822 }
823 }
824 }
825
826
827
828
829 func TestModNScalarMulRandom(t *testing.T) {
830
831 seed := time.Now().Unix()
832 rng := rand.New(rand.NewSource(seed))
833 defer func(t *testing.T, seed int64) {
834 if t.Failed() {
835 t.Logf("random seed: %d", seed)
836 }
837 }(t, seed)
838
839 for i := 0; i < 100; i++ {
840
841 bigIntVal1, modNVal1 := randIntAndModNScalar(t, rng)
842 bigIntVal2, modNVal2 := randIntAndModNScalar(t, rng)
843
844
845 bigIntResult := new(big.Int).Mul(bigIntVal1, bigIntVal2)
846 bigIntResult.Mod(bigIntResult, curveParams.N)
847
848
849 modNValResult := new(ModNScalar).Mul2(modNVal1, modNVal2)
850
851
852 bigIntResultHex := fmt.Sprintf("%064x", bigIntResult)
853 modNResultHex := fmt.Sprintf("%v", modNValResult)
854 if bigIntResultHex != modNResultHex {
855 t.Fatalf("mismatched mul\nbig int in 1: %x\nbig int in 2: %x\n"+
856 "scalar in 1: %v\nscalar in 2: %v\nbig int result: %x\nscalar "+
857 "result %v", bigIntVal1, bigIntVal2, modNVal1, modNVal2,
858 bigIntResult, modNValResult)
859 }
860 }
861 }
862
863
864
865 func TestModNScalarSquare(t *testing.T) {
866 tests := []struct {
867 name string
868 in string
869 expected string
870 }{{
871 name: "zero",
872 in: "0",
873 expected: "0",
874 }, {
875 name: "one",
876 in: "1",
877 expected: "1",
878 }, {
879 name: "over group order",
880 in: "0000000000000000000000000000000100000000000000000000000000000000",
881 expected: "000000000000000000000000000000014551231950b75fc4402da1732fc9bebf",
882 }, {
883 name: "group order - 1",
884 in: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
885 expected: "0000000000000000000000000000000000000000000000000000000000000001",
886 }, {
887 name: "overflow in word eight",
888 in: "100000000000000000000000000000000",
889 expected: "14551231950b75fc4402da1732fc9bebf",
890 }, {
891 name: "overflow in word nine",
892 in: "1000000000000000000000000000000000000",
893 expected: "14551231950b75fc4402da1732fc9bebf00000000",
894 }, {
895 name: "overflow in word ten",
896 in: "10000000000000000000000000000000000000000",
897 expected: "14551231950b75fc4402da1732fc9bebf0000000000000000",
898 }, {
899 name: "overflow in word eleven",
900 in: "100000000000000000000000000000000000000000000",
901 expected: "14551231950b75fc4402da1732fc9bebf000000000000000000000000",
902 }, {
903 name: "overflow in word twelve",
904 in: "1000000000000000000000000000000000000000000000000",
905 expected: "4551231950b75fc4402da1732fc9bec04551231950b75fc4402da1732fc9bebf",
906 }, {
907 name: "overflow in word thirteen",
908 in: "10000000000000000000000000000000000000000000000000000",
909 expected: "50b75fc4402da1732fc9bec09d671cd51b343a1b66926b57d2a4c1c61536bda7",
910 }, {
911 name: "overflow in word fourteen",
912 in: "100000000000000000000000000000000000000000000000000000000",
913 expected: "402da1732fc9bec09d671cd581c69bc59509b0b074ec0aea8f564d667ec7eb3c",
914 }, {
915 name: "overflow in word fifteen",
916 in: "1000000000000000000000000000000000000000000000000000000000000",
917 expected: "2fc9bec09d671cd581c69bc5e697f5e41f12c33a0a7b6f4e3302b92ea029cecd",
918 }, {
919 name: "alternating bits",
920 in: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
921 expected: "fb0982c5761d1eac534247f2a7c3af186a134d709b977ca88300faad5eafe9bc",
922 }, {
923 name: "alternating bits 2",
924 in: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
925 expected: "9081c595b95b2d17c424a546144b25488104c5889d914635bc9d1a51859e1c19",
926 }}
927
928 for _, test := range tests {
929 v := new(ModNScalar).SetHex(test.in)
930 expected := new(ModNScalar).SetHex(test.expected)
931
932
933 result := new(ModNScalar).SquareVal(v)
934 if !result.Equals(expected) {
935 t.Errorf("%s: wrong result\ngot: %v\nwant: %v", test.name, result,
936 expected)
937 continue
938 }
939
940
941 result2 := new(ModNScalar).Set(v).Square()
942 if !result2.Equals(expected) {
943 t.Errorf("%s: wrong result\ngot: %v\nwant: %v", test.name, result2,
944 expected)
945 continue
946 }
947 }
948 }
949
950
951
952
953 func TestModNScalarSquareRandom(t *testing.T) {
954
955 seed := time.Now().Unix()
956 rng := rand.New(rand.NewSource(seed))
957 defer func(t *testing.T, seed int64) {
958 if t.Failed() {
959 t.Logf("random seed: %d", seed)
960 }
961 }(t, seed)
962
963 for i := 0; i < 100; i++ {
964
965 bigIntVal, modNVal := randIntAndModNScalar(t, rng)
966
967
968 bigIntResult := new(big.Int).Mul(bigIntVal, bigIntVal)
969 bigIntResult.Mod(bigIntResult, curveParams.N)
970
971
972 modNValResult := new(ModNScalar).SquareVal(modNVal)
973
974
975 bigIntResultHex := fmt.Sprintf("%064x", bigIntResult)
976 modNResultHex := fmt.Sprintf("%v", modNValResult)
977 if bigIntResultHex != modNResultHex {
978 t.Fatalf("mismatched square\nbig int in: %x\nscalar in: %v\n"+
979 "big int result: %x\nscalar result %v", bigIntVal, modNVal,
980 bigIntResult, modNValResult)
981 }
982 }
983 }
984
985
986
987 func TestModNScalarNegate(t *testing.T) {
988 tests := []struct {
989 name string
990 in string
991 expected string
992 }{{
993 name: "zero",
994 in: "0",
995 expected: "0",
996 }, {
997 name: "one",
998 in: "1",
999 expected: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
1000 }, {
1001 name: "negation in word one",
1002 in: "0000000000000000000000000000000000000000000000000000000100000000",
1003 expected: "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8bd0364141",
1004 }, {
1005 name: "negation in word two",
1006 in: "0000000000000000000000000000000000000000000000010000000000000000",
1007 expected: "fffffffffffffffffffffffffffffffebaaedce6af48a03abfd25e8cd0364141",
1008 }, {
1009 name: "negation in word three",
1010 in: "0000000000000000000000000000000000000001000000000000000000000000",
1011 expected: "fffffffffffffffffffffffffffffffebaaedce5af48a03bbfd25e8cd0364141",
1012 }, {
1013 name: "negation in word four",
1014 in: "0000000000000000000000000000000100000000000000000000000000000000",
1015 expected: "fffffffffffffffffffffffffffffffdbaaedce6af48a03bbfd25e8cd0364141",
1016 }, {
1017 name: "negation in word five",
1018 in: "0000000000000000000000010000000000000000000000000000000000000000",
1019 expected: "fffffffffffffffffffffffefffffffebaaedce6af48a03bbfd25e8cd0364141",
1020 }, {
1021 name: "negation in word six",
1022 in: "0000000000000001000000000000000000000000000000000000000000000000",
1023 expected: "fffffffffffffffefffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
1024 }, {
1025 name: "negation in word seven",
1026 in: "0000000100000000000000000000000000000000000000000000000000000000",
1027 expected: "fffffffefffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
1028 }, {
1029 name: "alternating bits",
1030 in: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
1031 expected: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a591509374109a2fa961a2cb8e72a909b9c",
1032 }, {
1033 name: "alternating bits 2",
1034 in: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
1035 expected: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a46054828c54ee45e16578043275dbe6e7",
1036 }}
1037
1038 for _, test := range tests {
1039 s := new(ModNScalar).SetHex(test.in)
1040 expected := new(ModNScalar).SetHex(test.expected)
1041
1042
1043 result := new(ModNScalar).NegateVal(s)
1044 if !result.Equals(expected) {
1045 t.Errorf("%s: unexpected result -- got: %v, want: %v", test.name,
1046 result, expected)
1047 continue
1048 }
1049
1050
1051 result2 := new(ModNScalar).Set(s).Negate()
1052 if !result2.Equals(expected) {
1053 t.Errorf("%s: unexpected result -- got: %v, want: %v", test.name,
1054 result2, expected)
1055 continue
1056 }
1057 }
1058 }
1059
1060
1061
1062
1063 func TestModNScalarNegateRandom(t *testing.T) {
1064
1065 seed := time.Now().Unix()
1066 rng := rand.New(rand.NewSource(seed))
1067 defer func(t *testing.T, seed int64) {
1068 if t.Failed() {
1069 t.Logf("random seed: %d", seed)
1070 }
1071 }(t, seed)
1072
1073 for i := 0; i < 100; i++ {
1074
1075 bigIntVal, modNVal := randIntAndModNScalar(t, rng)
1076
1077
1078 bigIntResult := new(big.Int).Neg(bigIntVal)
1079 bigIntResult.Mod(bigIntResult, curveParams.N)
1080
1081
1082 modNValResult := new(ModNScalar).NegateVal(modNVal)
1083
1084
1085 bigIntResultHex := fmt.Sprintf("%064x", bigIntResult)
1086 modNResultHex := fmt.Sprintf("%v", modNValResult)
1087 if bigIntResultHex != modNResultHex {
1088 t.Fatalf("mismatched negate\nbig int in: %x\nscalar in: %v\n"+
1089 "big int result: %x\nscalar result %v", bigIntVal, modNVal,
1090 bigIntResult, modNValResult)
1091 }
1092 }
1093 }
1094
1095
1096
1097 func TestModNScalarInverseNonConst(t *testing.T) {
1098 tests := []struct {
1099 name string
1100 in string
1101 expected string
1102 }{{
1103 name: "zero",
1104 in: "0",
1105 expected: "0",
1106 }, {
1107 name: "one",
1108 in: "1",
1109 expected: "1",
1110 }, {
1111 name: "inverse carry in word one",
1112 in: "0000000000000000000000000000000000000000000000000000000100000000",
1113 expected: "5588b13effffffffffffffffffffffff934e5b00ca8417bf50177f7ba415411a",
1114 }, {
1115 name: "inverse carry in word two",
1116 in: "0000000000000000000000000000000000000000000000010000000000000000",
1117 expected: "4b0dff665588b13effffffffffffffffa09f710af01555259d4ad302583de6dc",
1118 }, {
1119 name: "inverse carry in word three",
1120 in: "0000000000000000000000000000000000000001000000000000000000000000",
1121 expected: "34b9ec244b0dff665588b13effffffffbcff4127932a971a78274c9d74176b38",
1122 }, {
1123 name: "inverse carry in word four",
1124 in: "0000000000000000000000000000000100000000000000000000000000000000",
1125 expected: "50a51ac834b9ec244b0dff665588b13e9984d5b3cf80ef0fd6a23766a3ee9f22",
1126 }, {
1127 name: "inverse carry in word five",
1128 in: "0000000000000000000000010000000000000000000000000000000000000000",
1129 expected: "27cfab5e50a51ac834b9ec244b0dff6622f16e85b683d5a059bcd5a3b29d9dff",
1130 }, {
1131 name: "inverse carry in word six",
1132 in: "0000000000000001000000000000000000000000000000000000000000000000",
1133 expected: "897f30c127cfab5e50a51ac834b9ec239c53f268b4700c14f19b9499ac58d8ad",
1134 }, {
1135 name: "inverse carry in word seven",
1136 in: "0000000100000000000000000000000000000000000000000000000000000000",
1137 expected: "6494ef93897f30c127cfab5e50a51ac7b4e8f713e0cddd182234e907286ae6b3",
1138 }, {
1139 name: "alternating bits",
1140 in: "a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5",
1141 expected: "cb6086e560b8597a85c934e46f5b6e8a445bf3f0a88e4160d7fa8d83fd10338d",
1142 }, {
1143 name: "alternating bits 2",
1144 in: "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
1145 expected: "9f864ca486a74eb5f546364d76d24aa93716dc78f84847aa6c1c09fca2707d77",
1146 }}
1147
1148 for _, test := range tests {
1149 s := new(ModNScalar).SetHex(test.in)
1150 expected := new(ModNScalar).SetHex(test.expected)
1151
1152
1153
1154 result := new(ModNScalar).InverseValNonConst(s)
1155 if !result.Equals(expected) {
1156 t.Errorf("%s: unexpected result -- got: %v, want: %v", test.name,
1157 result, expected)
1158 continue
1159 }
1160
1161
1162
1163 result2 := new(ModNScalar).Set(s).InverseNonConst()
1164 if !result2.Equals(expected) {
1165 t.Errorf("%s: unexpected result -- got: %v, want: %v", test.name,
1166 result2, expected)
1167 continue
1168 }
1169 }
1170 }
1171
1172
1173
1174
1175
1176 func TestModNScalarInverseNonConstRandom(t *testing.T) {
1177
1178 seed := time.Now().Unix()
1179 rng := rand.New(rand.NewSource(seed))
1180 defer func(t *testing.T, seed int64) {
1181 if t.Failed() {
1182 t.Logf("random seed: %d", seed)
1183 }
1184 }(t, seed)
1185
1186 for i := 0; i < 100; i++ {
1187
1188 bigIntVal, modNVal := randIntAndModNScalar(t, rng)
1189
1190
1191 bigIntResult := new(big.Int).ModInverse(bigIntVal, curveParams.N)
1192
1193
1194 modNValResult := new(ModNScalar).InverseValNonConst(modNVal)
1195
1196
1197 bigIntResultHex := fmt.Sprintf("%064x", bigIntResult)
1198 modNResultHex := fmt.Sprintf("%v", modNValResult)
1199 if bigIntResultHex != modNResultHex {
1200 t.Fatalf("mismatched inverse\nbig int in: %x\nscalar in: %v\n"+
1201 "big int result: %x\nscalar result %v", bigIntVal, modNVal,
1202 bigIntResult, modNValResult)
1203 }
1204 }
1205 }
1206
1207
1208
1209 func TestModNScalarIsOverHalfOrder(t *testing.T) {
1210 tests := []struct {
1211 name string
1212 in string
1213 expected bool
1214 }{{
1215 name: "zero",
1216 in: "0",
1217 expected: false,
1218 }, {
1219 name: "one",
1220 in: "1",
1221 expected: false,
1222 }, {
1223 name: "group half order - 1",
1224 in: "7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b209f",
1225 expected: false,
1226 }, {
1227 name: "group half order",
1228 in: "7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0",
1229 expected: false,
1230 }, {
1231 name: "group half order + 1",
1232 in: "7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1",
1233 expected: true,
1234 }, {
1235 name: "over half order word one",
1236 in: "7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f47681b20a0",
1237 expected: true,
1238 }, {
1239 name: "over half order word two",
1240 in: "7fffffffffffffffffffffffffffffff5d576e7357a4501edfe92f46681b20a0",
1241 expected: true,
1242 }, {
1243 name: "over half order word three",
1244 in: "7fffffffffffffffffffffffffffffff5d576e7457a4501ddfe92f46681b20a0",
1245 expected: true,
1246 }, {
1247 name: "over half order word seven",
1248 in: "8fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0",
1249 expected: true,
1250 }}
1251
1252 for _, test := range tests {
1253 result := new(ModNScalar).SetHex(test.in).IsOverHalfOrder()
1254 if result != test.expected {
1255 t.Errorf("%s: unexpected result -- got: %v, want: %v", test.name,
1256 result, test.expected)
1257 continue
1258 }
1259 }
1260 }
1261
1262
1263
1264
1265 func TestModNScalarIsOverHalfOrderRandom(t *testing.T) {
1266
1267 seed := time.Now().Unix()
1268 rng := rand.New(rand.NewSource(seed))
1269 defer func(t *testing.T, seed int64) {
1270 if t.Failed() {
1271 t.Logf("random seed: %d", seed)
1272 }
1273 }(t, seed)
1274
1275 bigHalfOrder := new(big.Int).Rsh(curveParams.N, 1)
1276 for i := 0; i < 100; i++ {
1277
1278 bigIntVal, modNVal := randIntAndModNScalar(t, rng)
1279
1280
1281 bigIntResult := bigIntVal.Cmp(bigHalfOrder) > 0
1282
1283
1284 modNValResult := modNVal.IsOverHalfOrder()
1285
1286
1287 if bigIntResult != modNValResult {
1288 t.Fatalf("mismatched is over half order\nbig int in: %x\nscalar "+
1289 "in: %v\nbig int result: %v\nscalar result %v", bigIntVal,
1290 modNVal, bigIntResult, modNValResult)
1291 }
1292 }
1293 }
1294
View as plain text