Source file
src/math/big/nat.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package big
15
16 import (
17 "internal/byteorder"
18 "math/bits"
19 "math/rand"
20 "slices"
21 "sync"
22 )
23
24
25
26
27
28
29
30
31
32
33
34
35 type nat []Word
36
37 var (
38 natOne = nat{1}
39 natTwo = nat{2}
40 natFive = nat{5}
41 natTen = nat{10}
42 )
43
44 func (z nat) String() string {
45 return "0x" + string(z.itoa(false, 16))
46 }
47
48 func (z nat) norm() nat {
49 i := len(z)
50 for i > 0 && z[i-1] == 0 {
51 i--
52 }
53 return z[0:i]
54 }
55
56 func (z nat) make(n int) nat {
57 if n <= cap(z) {
58 return z[:n]
59 }
60 if n == 1 {
61
62 return make(nat, 1)
63 }
64
65
66 const e = 4
67 return make(nat, n, n+e)
68 }
69
70 func (z nat) setWord(x Word) nat {
71 if x == 0 {
72 return z[:0]
73 }
74 z = z.make(1)
75 z[0] = x
76 return z
77 }
78
79 func (z nat) setUint64(x uint64) nat {
80
81 if w := Word(x); uint64(w) == x {
82 return z.setWord(w)
83 }
84
85 z = z.make(2)
86 z[1] = Word(x >> 32)
87 z[0] = Word(x)
88 return z
89 }
90
91 func (z nat) set(x nat) nat {
92 z = z.make(len(x))
93 copy(z, x)
94 return z
95 }
96
97 func (z nat) add(x, y nat) nat {
98 m := len(x)
99 n := len(y)
100
101 switch {
102 case m < n:
103 return z.add(y, x)
104 case m == 0:
105
106 return z[:0]
107 case n == 0:
108
109 return z.set(x)
110 }
111
112
113 z = z.make(m + 1)
114 c := addVV(z[:n], x[:n], y[:n])
115 if m > n {
116 c = addVW(z[n:m], x[n:], c)
117 }
118 z[m] = c
119
120 return z.norm()
121 }
122
123 func (z nat) sub(x, y nat) nat {
124 m := len(x)
125 n := len(y)
126
127 switch {
128 case m < n:
129 panic("underflow")
130 case m == 0:
131
132 return z[:0]
133 case n == 0:
134
135 return z.set(x)
136 }
137
138
139 z = z.make(m)
140 c := subVV(z[:n], x[:n], y[:n])
141 if m > n {
142 c = subVW(z[n:], x[n:], c)
143 }
144 if c != 0 {
145 panic("underflow")
146 }
147
148 return z.norm()
149 }
150
151 func (x nat) cmp(y nat) (r int) {
152 m := len(x)
153 n := len(y)
154 if m != n || m == 0 {
155 switch {
156 case m < n:
157 r = -1
158 case m > n:
159 r = 1
160 }
161 return
162 }
163
164 i := m - 1
165 for i > 0 && x[i] == y[i] {
166 i--
167 }
168
169 switch {
170 case x[i] < y[i]:
171 r = -1
172 case x[i] > y[i]:
173 r = 1
174 }
175 return
176 }
177
178
179
180
181
182
183
184
185
186
187 func (z nat) montgomery(x, y, m nat, k Word, n int) nat {
188
189
190
191
192 if len(x) != n || len(y) != n || len(m) != n {
193 panic("math/big: mismatched montgomery number lengths")
194 }
195 z = z.make(n * 2)
196 clear(z)
197 var c Word
198 for i := 0; i < n; i++ {
199 d := y[i]
200 c2 := addMulVVWW(z[i:n+i], z[i:n+i], x, d, 0)
201 t := z[i] * k
202 c3 := addMulVVWW(z[i:n+i], z[i:n+i], m, t, 0)
203 cx := c + c2
204 cy := cx + c3
205 z[n+i] = cy
206 if cx < c2 || cy < c3 {
207 c = 1
208 } else {
209 c = 0
210 }
211 }
212 if c != 0 {
213 subVV(z[:n], z[n:], m)
214 } else {
215 copy(z[:n], z[n:])
216 }
217 return z[:n]
218 }
219
220
221
222
223
224
225
226 func alias(x, y nat) bool {
227 return cap(x) > 0 && cap(y) > 0 && &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1]
228 }
229
230
231
232
233 func addTo(z, x nat) {
234 if n := len(x); n > 0 {
235 if c := addVV(z[:n], z[:n], x[:n]); c != 0 {
236 if n < len(z) {
237 addVW(z[n:], z[n:], c)
238 }
239 }
240 }
241 }
242
243
244
245
246 func (z nat) mulRange(stk *stack, a, b uint64) nat {
247 switch {
248 case a == 0:
249
250 return z.setUint64(0)
251 case a > b:
252 return z.setUint64(1)
253 case a == b:
254 return z.setUint64(a)
255 case a+1 == b:
256 return z.mul(stk, nat(nil).setUint64(a), nat(nil).setUint64(b))
257 }
258
259 if stk == nil {
260 stk = getStack()
261 defer stk.free()
262 }
263
264 m := a + (b-a)/2
265 return z.mul(stk, nat(nil).mulRange(stk, a, m), nat(nil).mulRange(stk, m+1, b))
266 }
267
268
269
270
271 type stackInner struct {
272 w []Word
273 }
274
275 var stackPool sync.Pool
276
277
278
279 func getStackInner() *stackInner {
280 s, _ := stackPool.Get().(*stackInner)
281 if s == nil {
282 s = new(stackInner)
283 }
284 return s
285 }
286
287
288 func (s *stackInner) free() {
289 s.w = s.w[:0]
290 stackPool.Put(s)
291 }
292
293
294
295
296 func (s *stackInner) save() int {
297 return len(s.w)
298 }
299
300
301
302
303
304
305
306
307 func (s *stackInner) restore(n int) {
308 s.w = s.w[:n]
309 }
310
311
312 func (s *stackInner) nat(n int) nat {
313 nr := (n + 3) &^ 3
314 off := len(s.w)
315 s.w = slices.Grow(s.w, nr)
316 s.w = s.w[:off+nr]
317 x := s.w[off : off+n : off+n]
318 if n > 0 {
319 x[0] = 0xfedcb
320 }
321 return x
322 }
323
324
325
326
327
328
329
330
331 type stack struct {
332 si *stackInner
333 }
334
335 func getStack() *stack {
336 return &stack{}
337 }
338 func (s *stack) free() {
339 si := s.si
340 if si != nil {
341 si.free()
342 }
343 }
344 func (s *stack) save() int {
345 si := s.si
346 if si == nil {
347 return 0
348 }
349 return si.save()
350 }
351 func (s *stack) restore(n int) {
352 si := s.si
353 if si == nil {
354 return
355 }
356 si.restore(n)
357 }
358 func (s *stack) nat(n int) nat {
359 si := s.si
360 if si == nil {
361 if n <= 4 {
362
363
364
365 r := slices.Grow(nat(nil), n)
366 r = r[:n]
367 if n > 0 {
368 r[0] = 0xabcdef
369 }
370 return r
371 }
372 si, _ = stackPool.Get().(*stackInner)
373 if si == nil {
374 si = new(stackInner)
375 }
376 s.si = si
377 }
378 return si.nat(n)
379 }
380
381
382
383 func (x nat) bitLen() int {
384
385
386
387 if i := len(x) - 1; i >= 0 {
388
389
390
391 top := uint(x[i])
392 top |= top >> 1
393 top |= top >> 2
394 top |= top >> 4
395 top |= top >> 8
396 top |= top >> 16
397 top |= top >> 16 >> 16
398 return i*_W + bits.Len(top)
399 }
400 return 0
401 }
402
403
404
405 func (x nat) trailingZeroBits() uint {
406 if len(x) == 0 {
407 return 0
408 }
409 var i uint
410 for x[i] == 0 {
411 i++
412 }
413
414 return i*_W + uint(bits.TrailingZeros(uint(x[i])))
415 }
416
417
418 func (x nat) isPow2() (uint, bool) {
419 var i uint
420 for x[i] == 0 {
421 i++
422 }
423 if i == uint(len(x))-1 && x[i]&(x[i]-1) == 0 {
424 return i*_W + uint(bits.TrailingZeros(uint(x[i]))), true
425 }
426 return 0, false
427 }
428
429 func same(x, y nat) bool {
430 return len(x) == len(y) && len(x) > 0 && &x[0] == &y[0]
431 }
432
433
434 func (z nat) lsh(x nat, s uint) nat {
435 if s == 0 {
436 if same(z, x) {
437 return z
438 }
439 if !alias(z, x) {
440 return z.set(x)
441 }
442 }
443
444 m := len(x)
445 if m == 0 {
446 return z[:0]
447 }
448
449
450 n := m + int(s/_W)
451 z = z.make(n + 1)
452 if s %= _W; s == 0 {
453 copy(z[n-m:n], x)
454 z[n] = 0
455 } else {
456 z[n] = lshVU(z[n-m:n], x, s)
457 }
458 clear(z[0 : n-m])
459
460 return z.norm()
461 }
462
463
464 func (z nat) rsh(x nat, s uint) nat {
465 if s == 0 {
466 if same(z, x) {
467 return z
468 }
469 if !alias(z, x) {
470 return z.set(x)
471 }
472 }
473
474 m := len(x)
475 n := m - int(s/_W)
476 if n <= 0 {
477 return z[:0]
478 }
479
480
481 z = z.make(n)
482 if s %= _W; s == 0 {
483 copy(z, x[m-n:])
484 } else {
485 rshVU(z, x[m-n:], s)
486 }
487
488 return z.norm()
489 }
490
491 func (z nat) setBit(x nat, i uint, b uint) nat {
492 j := int(i / _W)
493 m := Word(1) << (i % _W)
494 n := len(x)
495 switch b {
496 case 0:
497 z = z.make(n)
498 copy(z, x)
499 if j >= n {
500
501 return z
502 }
503 z[j] &^= m
504 return z.norm()
505 case 1:
506 if j >= n {
507 z = z.make(j + 1)
508 clear(z[n:])
509 } else {
510 z = z.make(n)
511 }
512 copy(z, x)
513 z[j] |= m
514
515 return z
516 }
517 panic("set bit is not 0 or 1")
518 }
519
520
521 func (x nat) bit(i uint) uint {
522 j := i / _W
523 if j >= uint(len(x)) {
524 return 0
525 }
526
527 return uint(x[j] >> (i % _W) & 1)
528 }
529
530
531
532 func (x nat) sticky(i uint) uint {
533 j := i / _W
534 if j >= uint(len(x)) {
535 if len(x) == 0 {
536 return 0
537 }
538 return 1
539 }
540
541 for _, x := range x[:j] {
542 if x != 0 {
543 return 1
544 }
545 }
546 if x[j]<<(_W-i%_W) != 0 {
547 return 1
548 }
549 return 0
550 }
551
552 func (z nat) and(x, y nat) nat {
553 m := len(x)
554 n := len(y)
555 if m > n {
556 m = n
557 }
558
559
560 z = z.make(m)
561 for i := 0; i < m; i++ {
562 z[i] = x[i] & y[i]
563 }
564
565 return z.norm()
566 }
567
568
569 func (z nat) trunc(x nat, n uint) nat {
570 w := (n + _W - 1) / _W
571 if uint(len(x)) < w {
572 return z.set(x)
573 }
574 z = z.make(int(w))
575 copy(z, x)
576 if n%_W != 0 {
577 z[len(z)-1] &= 1<<(n%_W) - 1
578 }
579 return z.norm()
580 }
581
582 func (z nat) andNot(x, y nat) nat {
583 m := len(x)
584 n := len(y)
585 if n > m {
586 n = m
587 }
588
589
590 z = z.make(m)
591 for i := 0; i < n; i++ {
592 z[i] = x[i] &^ y[i]
593 }
594 copy(z[n:m], x[n:m])
595
596 return z.norm()
597 }
598
599 func (z nat) or(x, y nat) nat {
600 m := len(x)
601 n := len(y)
602 s := x
603 if m < n {
604 n, m = m, n
605 s = y
606 }
607
608
609 z = z.make(m)
610 for i := 0; i < n; i++ {
611 z[i] = x[i] | y[i]
612 }
613 copy(z[n:m], s[n:m])
614
615 return z.norm()
616 }
617
618 func (z nat) xor(x, y nat) nat {
619 m := len(x)
620 n := len(y)
621 s := x
622 if m < n {
623 n, m = m, n
624 s = y
625 }
626
627
628 z = z.make(m)
629 for i := 0; i < n; i++ {
630 z[i] = x[i] ^ y[i]
631 }
632 copy(z[n:m], s[n:m])
633
634 return z.norm()
635 }
636
637
638
639 func (z nat) random(rand *rand.Rand, limit nat, n int) nat {
640 if alias(z, limit) {
641 z = nil
642 }
643 z = z.make(len(limit))
644
645 bitLengthOfMSW := uint(n % _W)
646 if bitLengthOfMSW == 0 {
647 bitLengthOfMSW = _W
648 }
649 mask := Word((1 << bitLengthOfMSW) - 1)
650
651 for {
652 switch _W {
653 case 32:
654 for i := range z {
655 z[i] = Word(rand.Uint32())
656 }
657 case 64:
658 for i := range z {
659 z[i] = Word(rand.Uint32()) | Word(rand.Uint32())<<32
660 }
661 default:
662 panic("unknown word size")
663 }
664 z[len(limit)-1] &= mask
665 if z.cmp(limit) < 0 {
666 break
667 }
668 }
669
670 return z.norm()
671 }
672
673
674
675
676 func (z nat) expNN(stk *stack, x, y, m nat, slow bool) nat {
677 if alias(z, x) || alias(z, y) {
678
679 z = nil
680 }
681
682
683 if len(m) == 1 && m[0] == 1 {
684 return z.setWord(0)
685 }
686
687
688
689 if len(y) == 0 {
690 return z.setWord(1)
691 }
692
693
694
695 if len(x) == 0 {
696 return z.setWord(0)
697 }
698
699
700
701 if len(x) == 1 && x[0] == 1 {
702 return z.setWord(1)
703 }
704
705
706
707 if len(y) == 1 && y[0] == 1 && len(m) == 0 {
708 return z.set(x)
709 }
710 if stk == nil {
711 stk = getStack()
712 defer stk.free()
713 }
714 if len(y) == 1 && y[0] == 1 {
715 return z.rem(stk, x, m)
716 }
717
718
719
720 if len(m) != 0 {
721
722 z = z.make(len(m))
723
724
725
726
727
728
729 if len(y) > 1 && !slow {
730 if m[0]&1 == 1 {
731 return z.expNNMontgomery(stk, x, y, m)
732 }
733 if logM, ok := m.isPow2(); ok {
734 return z.expNNWindowed(stk, x, y, logM)
735 }
736 return z.expNNMontgomeryEven(stk, x, y, m)
737 }
738 }
739
740 z = z.set(x)
741 v := y[len(y)-1]
742 shift := nlz(v) + 1
743 v <<= shift
744 var q nat
745
746 const mask = 1 << (_W - 1)
747
748
749
750
751
752 w := _W - int(shift)
753
754
755 var zz, r nat
756 for j := 0; j < w; j++ {
757 zz = zz.sqr(stk, z)
758 zz, z = z, zz
759
760 if v&mask != 0 {
761 zz = zz.mul(stk, z, x)
762 zz, z = z, zz
763 }
764
765 if len(m) != 0 {
766 zz, r = zz.div(stk, r, z, m)
767 zz, r, q, z = q, z, zz, r
768 }
769
770 v <<= 1
771 }
772
773 for i := len(y) - 2; i >= 0; i-- {
774 v = y[i]
775
776 for j := 0; j < _W; j++ {
777 zz = zz.sqr(stk, z)
778 zz, z = z, zz
779
780 if v&mask != 0 {
781 zz = zz.mul(stk, z, x)
782 zz, z = z, zz
783 }
784
785 if len(m) != 0 {
786 zz, r = zz.div(stk, r, z, m)
787 zz, r, q, z = q, z, zz, r
788 }
789
790 v <<= 1
791 }
792 }
793
794 return z.norm()
795 }
796
797
798
799
800
801
802
803
804
805 func (z nat) expNNMontgomeryEven(stk *stack, x, y, m nat) nat {
806
807 n := m.trailingZeroBits()
808 m1 := nat(nil).lsh(natOne, n)
809 m2 := nat(nil).rsh(m, n)
810
811
812
813
814
815
816
817 z1 := nat(nil).expNN(stk, x, y, m1, false)
818 z2 := nat(nil).expNN(stk, x, y, m2, false)
819
820
821
822
823
824
825
826
827
828
829
830 z = z.set(z2)
831
832
833 z1 = z1.subMod2N(z1, z2, n)
834
835
836 m2inv := nat(nil).modInverse(m2, m1)
837 z2 = z2.mul(stk, z1, m2inv)
838 z2 = z2.trunc(z2, n)
839
840
841 z = z.add(z, z1.mul(stk, z2, m2))
842
843 return z
844 }
845
846
847
848 func (z nat) expNNWindowed(stk *stack, x, y nat, logM uint) nat {
849 if len(y) <= 1 {
850 panic("big: misuse of expNNWindowed")
851 }
852 if x[0]&1 == 0 {
853
854
855 return z.setWord(0)
856 }
857 if logM == 1 {
858 return z.setWord(1)
859 }
860
861
862
863 defer stk.restore(stk.save())
864 w := int((logM + _W - 1) / _W)
865 zz := stk.nat(w)
866
867 const n = 4
868
869 var powers [1 << n]nat
870 for i := range powers {
871 powers[i] = stk.nat(w)
872 }
873 powers[0] = powers[0].set(natOne)
874 powers[1] = powers[1].trunc(x, logM)
875 for i := 2; i < 1<<n; i += 2 {
876 p2, p, p1 := &powers[i/2], &powers[i], &powers[i+1]
877 *p = p.sqr(stk, *p2)
878 *p = p.trunc(*p, logM)
879 *p1 = p1.mul(stk, *p, x)
880 *p1 = p1.trunc(*p1, logM)
881 }
882
883
884
885
886
887
888 i := len(y) - 1
889 mtop := int((logM - 2) / _W)
890 mmask := ^Word(0)
891 if mbits := (logM - 1) & (_W - 1); mbits != 0 {
892 mmask = (1 << mbits) - 1
893 }
894 if i > mtop {
895 i = mtop
896 }
897 advance := false
898 z = z.setWord(1)
899 for ; i >= 0; i-- {
900 yi := y[i]
901 if i == mtop {
902 yi &= mmask
903 }
904 for j := 0; j < _W; j += n {
905 if advance {
906
907
908
909
910 zz = zz.sqr(stk, z)
911 zz, z = z, zz
912 z = z.trunc(z, logM)
913
914 zz = zz.sqr(stk, z)
915 zz, z = z, zz
916 z = z.trunc(z, logM)
917
918 zz = zz.sqr(stk, z)
919 zz, z = z, zz
920 z = z.trunc(z, logM)
921
922 zz = zz.sqr(stk, z)
923 zz, z = z, zz
924 z = z.trunc(z, logM)
925 }
926
927 zz = zz.mul(stk, z, powers[yi>>(_W-n)])
928 zz, z = z, zz
929 z = z.trunc(z, logM)
930
931 yi <<= n
932 advance = true
933 }
934 }
935
936 return z.norm()
937 }
938
939
940
941 func (z nat) expNNMontgomery(stk *stack, x, y, m nat) nat {
942 numWords := len(m)
943
944
945
946 if len(x) > numWords {
947 _, x = nat(nil).div(stk, nil, x, m)
948
949 }
950 if len(x) < numWords {
951 rr := make(nat, numWords)
952 copy(rr, x)
953 x = rr
954 }
955
956
957
958
959 k0 := 2 - m[0]
960 t := m[0] - 1
961 for i := 1; i < _W; i <<= 1 {
962 t *= t
963 k0 *= (t + 1)
964 }
965 k0 = -k0
966
967
968 RR := nat(nil).setWord(1)
969 zz := nat(nil).lsh(RR, uint(2*numWords*_W))
970 _, RR = nat(nil).div(stk, RR, zz, m)
971 if len(RR) < numWords {
972 zz = zz.make(numWords)
973 copy(zz, RR)
974 RR = zz
975 }
976
977 one := make(nat, numWords)
978 one[0] = 1
979
980 const n = 4
981
982 var powers [1 << n]nat
983 powers[0] = powers[0].montgomery(one, RR, m, k0, numWords)
984 powers[1] = powers[1].montgomery(x, RR, m, k0, numWords)
985 for i := 2; i < 1<<n; i++ {
986 powers[i] = powers[i].montgomery(powers[i-1], powers[1], m, k0, numWords)
987 }
988
989
990 z = z.make(numWords)
991 copy(z, powers[0])
992
993 zz = zz.make(numWords)
994
995
996 for i := len(y) - 1; i >= 0; i-- {
997 yi := y[i]
998 for j := 0; j < _W; j += n {
999 if i != len(y)-1 || j != 0 {
1000 zz = zz.montgomery(z, z, m, k0, numWords)
1001 z = z.montgomery(zz, zz, m, k0, numWords)
1002 zz = zz.montgomery(z, z, m, k0, numWords)
1003 z = z.montgomery(zz, zz, m, k0, numWords)
1004 }
1005 zz = zz.montgomery(z, powers[yi>>(_W-n)], m, k0, numWords)
1006 z, zz = zz, z
1007 yi <<= n
1008 }
1009 }
1010
1011 zz = zz.montgomery(z, one, m, k0, numWords)
1012
1013
1014
1015 if zz.cmp(m) >= 0 {
1016
1017
1018
1019
1020
1021
1022
1023 zz = zz.sub(zz, m)
1024 if zz.cmp(m) >= 0 {
1025 _, zz = nat(nil).div(stk, nil, zz, m)
1026 }
1027 }
1028
1029 return zz.norm()
1030 }
1031
1032
1033
1034
1035
1036 func (z nat) bytes(buf []byte) (i int) {
1037
1038
1039
1040 i = len(buf)
1041 for _, d := range z {
1042 for j := 0; j < _S; j++ {
1043 i--
1044 if i >= 0 {
1045 buf[i] = byte(d)
1046 } else if byte(d) != 0 {
1047 panic("math/big: buffer too small to fit value")
1048 }
1049 d >>= 8
1050 }
1051 }
1052
1053 if i < 0 {
1054 i = 0
1055 }
1056 for i < len(buf) && buf[i] == 0 {
1057 i++
1058 }
1059
1060 return
1061 }
1062
1063
1064 func bigEndianWord(buf []byte) Word {
1065 if _W == 64 {
1066 return Word(byteorder.BEUint64(buf))
1067 }
1068 return Word(byteorder.BEUint32(buf))
1069 }
1070
1071
1072
1073 func (z nat) setBytes(buf []byte) nat {
1074 z = z.make((len(buf) + _S - 1) / _S)
1075
1076 i := len(buf)
1077 for k := 0; i >= _S; k++ {
1078 z[k] = bigEndianWord(buf[i-_S : i])
1079 i -= _S
1080 }
1081 if i > 0 {
1082 var d Word
1083 for s := uint(0); i > 0; s += 8 {
1084 d |= Word(buf[i-1]) << s
1085 i--
1086 }
1087 z[len(z)-1] = d
1088 }
1089
1090 return z.norm()
1091 }
1092
1093
1094
1095 func (z nat) sqrt(stk *stack, x nat) nat {
1096 if x.cmp(natOne) <= 0 {
1097 return z.set(x)
1098 }
1099 if alias(z, x) {
1100 z = nil
1101 }
1102
1103 if stk == nil {
1104 stk = getStack()
1105 defer stk.free()
1106 }
1107
1108
1109
1110
1111
1112
1113 var z1, z2 nat
1114 z1 = z
1115 z1 = z1.setUint64(1)
1116 z1 = z1.lsh(z1, uint(x.bitLen()+1)/2)
1117 for n := 0; ; n++ {
1118 z2, _ = z2.div(stk, nil, x, z1)
1119 z2 = z2.add(z2, z1)
1120 z2 = z2.rsh(z2, 1)
1121 if z2.cmp(z1) >= 0 {
1122
1123
1124 if n&1 == 0 {
1125 return z1
1126 }
1127 return z.set(z1)
1128 }
1129 z1, z2 = z2, z1
1130 }
1131 }
1132
1133
1134 func (z nat) subMod2N(x, y nat, n uint) nat {
1135 if uint(x.bitLen()) > n {
1136 if alias(z, x) {
1137
1138 x = x.trunc(x, n)
1139 } else {
1140 x = nat(nil).trunc(x, n)
1141 }
1142 }
1143 if uint(y.bitLen()) > n {
1144 if alias(z, y) {
1145
1146 y = y.trunc(y, n)
1147 } else {
1148 y = nat(nil).trunc(y, n)
1149 }
1150 }
1151 if x.cmp(y) >= 0 {
1152 return z.sub(x, y)
1153 }
1154
1155 z = z.sub(y, x)
1156 for uint(len(z))*_W < n {
1157 z = append(z, 0)
1158 }
1159 for i := range z {
1160 z[i] = ^z[i]
1161 }
1162 z = z.trunc(z, n)
1163 return z.add(z, natOne)
1164 }
1165
View as plain text