Source file src/pkg/math/big/nat.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14 package big
15
16 import (
17 "encoding/binary"
18 "math/bits"
19 "math/rand"
20 "sync"
21 )
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) clear() {
45 for i := range z {
46 z[i] = 0
47 }
48 }
49
50 func (z nat) norm() nat {
51 i := len(z)
52 for i > 0 && z[i-1] == 0 {
53 i--
54 }
55 return z[0:i]
56 }
57
58 func (z nat) make(n int) nat {
59 if n <= cap(z) {
60 return z[:n]
61 }
62 if n == 1 {
63
64 return make(nat, 1)
65 }
66
67
68 const e = 4
69 return make(nat, n, n+e)
70 }
71
72 func (z nat) setWord(x Word) nat {
73 if x == 0 {
74 return z[:0]
75 }
76 z = z.make(1)
77 z[0] = x
78 return z
79 }
80
81 func (z nat) setUint64(x uint64) nat {
82
83 if w := Word(x); uint64(w) == x {
84 return z.setWord(w)
85 }
86
87 z = z.make(2)
88 z[1] = Word(x >> 32)
89 z[0] = Word(x)
90 return z
91 }
92
93 func (z nat) set(x nat) nat {
94 z = z.make(len(x))
95 copy(z, x)
96 return z
97 }
98
99 func (z nat) add(x, y nat) nat {
100 m := len(x)
101 n := len(y)
102
103 switch {
104 case m < n:
105 return z.add(y, x)
106 case m == 0:
107
108 return z[:0]
109 case n == 0:
110
111 return z.set(x)
112 }
113
114
115 z = z.make(m + 1)
116 c := addVV(z[0:n], x, y)
117 if m > n {
118 c = addVW(z[n:m], x[n:], c)
119 }
120 z[m] = c
121
122 return z.norm()
123 }
124
125 func (z nat) sub(x, y nat) nat {
126 m := len(x)
127 n := len(y)
128
129 switch {
130 case m < n:
131 panic("underflow")
132 case m == 0:
133
134 return z[:0]
135 case n == 0:
136
137 return z.set(x)
138 }
139
140
141 z = z.make(m)
142 c := subVV(z[0:n], x, y)
143 if m > n {
144 c = subVW(z[n:], x[n:], c)
145 }
146 if c != 0 {
147 panic("underflow")
148 }
149
150 return z.norm()
151 }
152
153 func (x nat) cmp(y nat) (r int) {
154 m := len(x)
155 n := len(y)
156 if m != n || m == 0 {
157 switch {
158 case m < n:
159 r = -1
160 case m > n:
161 r = 1
162 }
163 return
164 }
165
166 i := m - 1
167 for i > 0 && x[i] == y[i] {
168 i--
169 }
170
171 switch {
172 case x[i] < y[i]:
173 r = -1
174 case x[i] > y[i]:
175 r = 1
176 }
177 return
178 }
179
180 func (z nat) mulAddWW(x nat, y, r Word) nat {
181 m := len(x)
182 if m == 0 || y == 0 {
183 return z.setWord(r)
184 }
185
186
187 z = z.make(m + 1)
188 z[m] = mulAddVWW(z[0:m], x, y, r)
189
190 return z.norm()
191 }
192
193
194
195 func basicMul(z, x, y nat) {
196 z[0 : len(x)+len(y)].clear()
197 for i, d := range y {
198 if d != 0 {
199 z[len(x)+i] = addMulVVW(z[i:i+len(x)], x, d)
200 }
201 }
202 }
203
204
205
206
207
208
209
210
211
212
213 func (z nat) montgomery(x, y, m nat, k Word, n int) nat {
214
215
216
217
218 if len(x) != n || len(y) != n || len(m) != n {
219 panic("math/big: mismatched montgomery number lengths")
220 }
221 z = z.make(n * 2)
222 z.clear()
223 var c Word
224 for i := 0; i < n; i++ {
225 d := y[i]
226 c2 := addMulVVW(z[i:n+i], x, d)
227 t := z[i] * k
228 c3 := addMulVVW(z[i:n+i], m, t)
229 cx := c + c2
230 cy := cx + c3
231 z[n+i] = cy
232 if cx < c2 || cy < c3 {
233 c = 1
234 } else {
235 c = 0
236 }
237 }
238 if c != 0 {
239 subVV(z[:n], z[n:], m)
240 } else {
241 copy(z[:n], z[n:])
242 }
243 return z[:n]
244 }
245
246
247
248 func karatsubaAdd(z, x nat, n int) {
249 if c := addVV(z[0:n], z, x); c != 0 {
250 addVW(z[n:n+n>>1], z[n:], c)
251 }
252 }
253
254
255 func karatsubaSub(z, x nat, n int) {
256 if c := subVV(z[0:n], z, x); c != 0 {
257 subVW(z[n:n+n>>1], z[n:], c)
258 }
259 }
260
261
262
263
264 var karatsubaThreshold = 40
265
266
267
268
269
270 func karatsuba(z, x, y nat) {
271 n := len(y)
272
273
274
275
276 if n&1 != 0 || n < karatsubaThreshold || n < 2 {
277 basicMul(z, x, y)
278 return
279 }
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306 n2 := n >> 1
307 x1, x0 := x[n2:], x[0:n2]
308 y1, y0 := y[n2:], y[0:n2]
309
310
311
312
313
314
315
316
317
318
319
320 karatsuba(z, x0, y0)
321 karatsuba(z[n:], x1, y1)
322
323
324 s := 1
325 xd := z[2*n : 2*n+n2]
326 if subVV(xd, x1, x0) != 0 {
327 s = -s
328 subVV(xd, x0, x1)
329 }
330
331
332 yd := z[2*n+n2 : 3*n]
333 if subVV(yd, y0, y1) != 0 {
334 s = -s
335 subVV(yd, y1, y0)
336 }
337
338
339
340 p := z[n*3:]
341 karatsuba(p, xd, yd)
342
343
344
345 r := z[n*4:]
346 copy(r, z[:n*2])
347
348
349
350
351
352
353
354
355
356 karatsubaAdd(z[n2:], r, n)
357 karatsubaAdd(z[n2:], r[n:], n)
358 if s > 0 {
359 karatsubaAdd(z[n2:], p, n)
360 } else {
361 karatsubaSub(z[n2:], p, n)
362 }
363 }
364
365
366
367
368
369
370 func alias(x, y nat) bool {
371 return cap(x) > 0 && cap(y) > 0 && &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1]
372 }
373
374
375
376
377 func addAt(z, x nat, i int) {
378 if n := len(x); n > 0 {
379 if c := addVV(z[i:i+n], z[i:], x); c != 0 {
380 j := i + n
381 if j < len(z) {
382 addVW(z[j:], z[j:], c)
383 }
384 }
385 }
386 }
387
388 func max(x, y int) int {
389 if x > y {
390 return x
391 }
392 return y
393 }
394
395
396
397
398
399 func karatsubaLen(n, threshold int) int {
400 i := uint(0)
401 for n > threshold {
402 n >>= 1
403 i++
404 }
405 return n << i
406 }
407
408 func (z nat) mul(x, y nat) nat {
409 m := len(x)
410 n := len(y)
411
412 switch {
413 case m < n:
414 return z.mul(y, x)
415 case m == 0 || n == 0:
416 return z[:0]
417 case n == 1:
418 return z.mulAddWW(x, y[0], 0)
419 }
420
421
422
423 if alias(z, x) || alias(z, y) {
424 z = nil
425 }
426
427
428 if n < karatsubaThreshold {
429 z = z.make(m + n)
430 basicMul(z, x, y)
431 return z.norm()
432 }
433
434
435
436
437
438
439
440
441 k := karatsubaLen(n, karatsubaThreshold)
442
443
444
445 x0 := x[0:k]
446 y0 := y[0:k]
447 z = z.make(max(6*k, m+n))
448 karatsuba(z, x0, y0)
449 z = z[0 : m+n]
450 z[2*k:].clear()
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465 if k < n || m != n {
466 var t nat
467
468
469 x0 := x0.norm()
470 y1 := y[k:]
471 t = t.mul(x0, y1)
472 addAt(z, t, k)
473
474
475 y0 := y0.norm()
476 for i := k; i < len(x); i += k {
477 xi := x[i:]
478 if len(xi) > k {
479 xi = xi[:k]
480 }
481 xi = xi.norm()
482 t = t.mul(xi, y0)
483 addAt(z, t, i)
484 t = t.mul(xi, y1)
485 addAt(z, t, i+k)
486 }
487 }
488
489 return z.norm()
490 }
491
492
493
494
495
496 func basicSqr(z, x nat) {
497 n := len(x)
498 t := make(nat, 2*n)
499 z[1], z[0] = mulWW(x[0], x[0])
500 for i := 1; i < n; i++ {
501 d := x[i]
502
503 z[2*i+1], z[2*i] = mulWW(d, d)
504
505 t[2*i] = addMulVVW(t[i:2*i], x[0:i], d)
506 }
507 t[2*n-1] = shlVU(t[1:2*n-1], t[1:2*n-1], 1)
508 addVV(z, z, t)
509 }
510
511
512
513
514
515
516 func karatsubaSqr(z, x nat) {
517 n := len(x)
518
519 if n&1 != 0 || n < karatsubaSqrThreshold || n < 2 {
520 basicSqr(z[:2*n], x)
521 return
522 }
523
524 n2 := n >> 1
525 x1, x0 := x[n2:], x[0:n2]
526
527 karatsubaSqr(z, x0)
528 karatsubaSqr(z[n:], x1)
529
530
531 xd := z[2*n : 2*n+n2]
532 if subVV(xd, x1, x0) != 0 {
533 subVV(xd, x0, x1)
534 }
535
536 p := z[n*3:]
537 karatsubaSqr(p, xd)
538
539 r := z[n*4:]
540 copy(r, z[:n*2])
541
542 karatsubaAdd(z[n2:], r, n)
543 karatsubaAdd(z[n2:], r[n:], n)
544 karatsubaSub(z[n2:], p, n)
545 }
546
547
548
549
550 var basicSqrThreshold = 20
551 var karatsubaSqrThreshold = 260
552
553
554 func (z nat) sqr(x nat) nat {
555 n := len(x)
556 switch {
557 case n == 0:
558 return z[:0]
559 case n == 1:
560 d := x[0]
561 z = z.make(2)
562 z[1], z[0] = mulWW(d, d)
563 return z.norm()
564 }
565
566 if alias(z, x) {
567 z = nil
568 }
569
570 if n < basicSqrThreshold {
571 z = z.make(2 * n)
572 basicMul(z, x, x)
573 return z.norm()
574 }
575 if n < karatsubaSqrThreshold {
576 z = z.make(2 * n)
577 basicSqr(z, x)
578 return z.norm()
579 }
580
581
582
583
584
585
586 k := karatsubaLen(n, karatsubaSqrThreshold)
587
588 x0 := x[0:k]
589 z = z.make(max(6*k, 2*n))
590 karatsubaSqr(z, x0)
591 z = z[0 : 2*n]
592 z[2*k:].clear()
593
594 if k < n {
595 var t nat
596 x0 := x0.norm()
597 x1 := x[k:]
598 t = t.mul(x0, x1)
599 addAt(z, t, k)
600 addAt(z, t, k)
601 t = t.sqr(x1)
602 addAt(z, t, 2*k)
603 }
604
605 return z.norm()
606 }
607
608
609
610 func (z nat) mulRange(a, b uint64) nat {
611 switch {
612 case a == 0:
613
614 return z.setUint64(0)
615 case a > b:
616 return z.setUint64(1)
617 case a == b:
618 return z.setUint64(a)
619 case a+1 == b:
620 return z.mul(nat(nil).setUint64(a), nat(nil).setUint64(b))
621 }
622 m := (a + b) / 2
623 return z.mul(nat(nil).mulRange(a, m), nat(nil).mulRange(m+1, b))
624 }
625
626
627 func (z nat) divW(x nat, y Word) (q nat, r Word) {
628 m := len(x)
629 switch {
630 case y == 0:
631 panic("division by zero")
632 case y == 1:
633 q = z.set(x)
634 return
635 case m == 0:
636 q = z[:0]
637 return
638 }
639
640 z = z.make(m)
641 r = divWVW(z, 0, x, y)
642 q = z.norm()
643 return
644 }
645
646 func (z nat) div(z2, u, v nat) (q, r nat) {
647 if len(v) == 0 {
648 panic("division by zero")
649 }
650
651 if u.cmp(v) < 0 {
652 q = z[:0]
653 r = z2.set(u)
654 return
655 }
656
657 if len(v) == 1 {
658 var r2 Word
659 q, r2 = z.divW(u, v[0])
660 r = z2.setWord(r2)
661 return
662 }
663
664 q, r = z.divLarge(z2, u, v)
665 return
666 }
667
668
669
670 func getNat(n int) *nat {
671 var z *nat
672 if v := natPool.Get(); v != nil {
673 z = v.(*nat)
674 }
675 if z == nil {
676 z = new(nat)
677 }
678 *z = z.make(n)
679 return z
680 }
681
682 func putNat(x *nat) {
683 natPool.Put(x)
684 }
685
686 var natPool sync.Pool
687
688
689
690
691
692
693
694
695 func (z nat) divLarge(u, uIn, vIn nat) (q, r nat) {
696 n := len(vIn)
697 m := len(uIn) - n
698
699
700 shift := nlz(vIn[n-1])
701
702 vp := getNat(n)
703 v := *vp
704 shlVU(v, vIn, shift)
705
706
707 u = u.make(len(uIn) + 1)
708 u[len(uIn)] = shlVU(u[0:len(uIn)], uIn, shift)
709
710
711 if alias(z, u) {
712 z = nil
713 }
714 q = z.make(m + 1)
715
716 qhatvp := getNat(n + 1)
717 qhatv := *qhatvp
718
719
720 vn1 := v[n-1]
721 for j := m; j >= 0; j-- {
722
723 qhat := Word(_M)
724 if ujn := u[j+n]; ujn != vn1 {
725 var rhat Word
726 qhat, rhat = divWW(ujn, u[j+n-1], vn1)
727
728
729 vn2 := v[n-2]
730 x1, x2 := mulWW(qhat, vn2)
731
732 ujn2 := u[j+n-2]
733 for greaterThan(x1, x2, rhat, ujn2) {
734 qhat--
735 prevRhat := rhat
736 rhat += vn1
737
738 if rhat < prevRhat {
739 break
740 }
741 x1, x2 = mulWW(qhat, vn2)
742 }
743 }
744
745
746 qhatv[n] = mulAddVWW(qhatv[0:n], v, qhat, 0)
747
748 c := subVV(u[j:j+len(qhatv)], u[j:], qhatv)
749 if c != 0 {
750 c := addVV(u[j:j+n], u[j:], v)
751 u[j+n] += c
752 qhat--
753 }
754
755 q[j] = qhat
756 }
757
758 putNat(vp)
759 putNat(qhatvp)
760
761 q = q.norm()
762 shrVU(u, u, shift)
763 r = u.norm()
764
765 return q, r
766 }
767
768
769 func (x nat) bitLen() int {
770 if i := len(x) - 1; i >= 0 {
771 return i*_W + bits.Len(uint(x[i]))
772 }
773 return 0
774 }
775
776
777
778 func (x nat) trailingZeroBits() uint {
779 if len(x) == 0 {
780 return 0
781 }
782 var i uint
783 for x[i] == 0 {
784 i++
785 }
786
787 return i*_W + uint(bits.TrailingZeros(uint(x[i])))
788 }
789
790 func same(x, y nat) bool {
791 return len(x) == len(y) && len(x) > 0 && &x[0] == &y[0]
792 }
793
794
795 func (z nat) shl(x nat, s uint) nat {
796 if s == 0 {
797 if same(z, x) {
798 return z
799 }
800 if !alias(z, x) {
801 return z.set(x)
802 }
803 }
804
805 m := len(x)
806 if m == 0 {
807 return z[:0]
808 }
809
810
811 n := m + int(s/_W)
812 z = z.make(n + 1)
813 z[n] = shlVU(z[n-m:n], x, s%_W)
814 z[0 : n-m].clear()
815
816 return z.norm()
817 }
818
819
820 func (z nat) shr(x nat, s uint) nat {
821 if s == 0 {
822 if same(z, x) {
823 return z
824 }
825 if !alias(z, x) {
826 return z.set(x)
827 }
828 }
829
830 m := len(x)
831 n := m - int(s/_W)
832 if n <= 0 {
833 return z[:0]
834 }
835
836
837 z = z.make(n)
838 shrVU(z, x[m-n:], s%_W)
839
840 return z.norm()
841 }
842
843 func (z nat) setBit(x nat, i uint, b uint) nat {
844 j := int(i / _W)
845 m := Word(1) << (i % _W)
846 n := len(x)
847 switch b {
848 case 0:
849 z = z.make(n)
850 copy(z, x)
851 if j >= n {
852
853 return z
854 }
855 z[j] &^= m
856 return z.norm()
857 case 1:
858 if j >= n {
859 z = z.make(j + 1)
860 z[n:].clear()
861 } else {
862 z = z.make(n)
863 }
864 copy(z, x)
865 z[j] |= m
866
867 return z
868 }
869 panic("set bit is not 0 or 1")
870 }
871
872
873 func (x nat) bit(i uint) uint {
874 j := i / _W
875 if j >= uint(len(x)) {
876 return 0
877 }
878
879 return uint(x[j] >> (i % _W) & 1)
880 }
881
882
883
884 func (x nat) sticky(i uint) uint {
885 j := i / _W
886 if j >= uint(len(x)) {
887 if len(x) == 0 {
888 return 0
889 }
890 return 1
891 }
892
893 for _, x := range x[:j] {
894 if x != 0 {
895 return 1
896 }
897 }
898 if x[j]<<(_W-i%_W) != 0 {
899 return 1
900 }
901 return 0
902 }
903
904 func (z nat) and(x, y nat) nat {
905 m := len(x)
906 n := len(y)
907 if m > n {
908 m = n
909 }
910
911
912 z = z.make(m)
913 for i := 0; i < m; i++ {
914 z[i] = x[i] & y[i]
915 }
916
917 return z.norm()
918 }
919
920 func (z nat) andNot(x, y nat) nat {
921 m := len(x)
922 n := len(y)
923 if n > m {
924 n = m
925 }
926
927
928 z = z.make(m)
929 for i := 0; i < n; i++ {
930 z[i] = x[i] &^ y[i]
931 }
932 copy(z[n:m], x[n:m])
933
934 return z.norm()
935 }
936
937 func (z nat) or(x, y nat) nat {
938 m := len(x)
939 n := len(y)
940 s := x
941 if m < n {
942 n, m = m, n
943 s = y
944 }
945
946
947 z = z.make(m)
948 for i := 0; i < n; i++ {
949 z[i] = x[i] | y[i]
950 }
951 copy(z[n:m], s[n:m])
952
953 return z.norm()
954 }
955
956 func (z nat) xor(x, y nat) nat {
957 m := len(x)
958 n := len(y)
959 s := x
960 if m < n {
961 n, m = m, n
962 s = y
963 }
964
965
966 z = z.make(m)
967 for i := 0; i < n; i++ {
968 z[i] = x[i] ^ y[i]
969 }
970 copy(z[n:m], s[n:m])
971
972 return z.norm()
973 }
974
975
976 func greaterThan(x1, x2, y1, y2 Word) bool {
977 return x1 > y1 || x1 == y1 && x2 > y2
978 }
979
980
981 func (x nat) modW(d Word) (r Word) {
982
983 var q nat
984 q = q.make(len(x))
985 return divWVW(q, 0, x, d)
986 }
987
988
989
990 func (z nat) random(rand *rand.Rand, limit nat, n int) nat {
991 if alias(z, limit) {
992 z = nil
993 }
994 z = z.make(len(limit))
995
996 bitLengthOfMSW := uint(n % _W)
997 if bitLengthOfMSW == 0 {
998 bitLengthOfMSW = _W
999 }
1000 mask := Word((1 << bitLengthOfMSW) - 1)
1001
1002 for {
1003 switch _W {
1004 case 32:
1005 for i := range z {
1006 z[i] = Word(rand.Uint32())
1007 }
1008 case 64:
1009 for i := range z {
1010 z[i] = Word(rand.Uint32()) | Word(rand.Uint32())<<32
1011 }
1012 default:
1013 panic("unknown word size")
1014 }
1015 z[len(limit)-1] &= mask
1016 if z.cmp(limit) < 0 {
1017 break
1018 }
1019 }
1020
1021 return z.norm()
1022 }
1023
1024
1025
1026 func (z nat) expNN(x, y, m nat) nat {
1027 if alias(z, x) || alias(z, y) {
1028
1029 z = nil
1030 }
1031
1032
1033 if len(m) == 1 && m[0] == 1 {
1034 return z.setWord(0)
1035 }
1036
1037
1038
1039 if len(y) == 0 {
1040 return z.setWord(1)
1041 }
1042
1043
1044
1045 if len(y) == 1 && y[0] == 1 && len(m) != 0 {
1046 _, z = nat(nil).div(z, x, m)
1047 return z
1048 }
1049
1050
1051 if len(m) != 0 {
1052
1053 z = z.make(len(m))
1054 }
1055 z = z.set(x)
1056
1057
1058
1059
1060
1061
1062 if x.cmp(natOne) > 0 && len(y) > 1 && len(m) > 0 {
1063 if m[0]&1 == 1 {
1064 return z.expNNMontgomery(x, y, m)
1065 }
1066 return z.expNNWindowed(x, y, m)
1067 }
1068
1069 v := y[len(y)-1]
1070 shift := nlz(v) + 1
1071 v <<= shift
1072 var q nat
1073
1074 const mask = 1 << (_W - 1)
1075
1076
1077
1078
1079
1080 w := _W - int(shift)
1081
1082
1083 var zz, r nat
1084 for j := 0; j < w; j++ {
1085 zz = zz.sqr(z)
1086 zz, z = z, zz
1087
1088 if v&mask != 0 {
1089 zz = zz.mul(z, x)
1090 zz, z = z, zz
1091 }
1092
1093 if len(m) != 0 {
1094 zz, r = zz.div(r, z, m)
1095 zz, r, q, z = q, z, zz, r
1096 }
1097
1098 v <<= 1
1099 }
1100
1101 for i := len(y) - 2; i >= 0; i-- {
1102 v = y[i]
1103
1104 for j := 0; j < _W; j++ {
1105 zz = zz.sqr(z)
1106 zz, z = z, zz
1107
1108 if v&mask != 0 {
1109 zz = zz.mul(z, x)
1110 zz, z = z, zz
1111 }
1112
1113 if len(m) != 0 {
1114 zz, r = zz.div(r, z, m)
1115 zz, r, q, z = q, z, zz, r
1116 }
1117
1118 v <<= 1
1119 }
1120 }
1121
1122 return z.norm()
1123 }
1124
1125
1126 func (z nat) expNNWindowed(x, y, m nat) nat {
1127
1128
1129 var zz, r nat
1130
1131 const n = 4
1132
1133 var powers [1 << n]nat
1134 powers[0] = natOne
1135 powers[1] = x
1136 for i := 2; i < 1<<n; i += 2 {
1137 p2, p, p1 := &powers[i/2], &powers[i], &powers[i+1]
1138 *p = p.sqr(*p2)
1139 zz, r = zz.div(r, *p, m)
1140 *p, r = r, *p
1141 *p1 = p1.mul(*p, x)
1142 zz, r = zz.div(r, *p1, m)
1143 *p1, r = r, *p1
1144 }
1145
1146 z = z.setWord(1)
1147
1148 for i := len(y) - 1; i >= 0; i-- {
1149 yi := y[i]
1150 for j := 0; j < _W; j += n {
1151 if i != len(y)-1 || j != 0 {
1152
1153
1154
1155 zz = zz.sqr(z)
1156 zz, z = z, zz
1157 zz, r = zz.div(r, z, m)
1158 z, r = r, z
1159
1160 zz = zz.sqr(z)
1161 zz, z = z, zz
1162 zz, r = zz.div(r, z, m)
1163 z, r = r, z
1164
1165 zz = zz.sqr(z)
1166 zz, z = z, zz
1167 zz, r = zz.div(r, z, m)
1168 z, r = r, z
1169
1170 zz = zz.sqr(z)
1171 zz, z = z, zz
1172 zz, r = zz.div(r, z, m)
1173 z, r = r, z
1174 }
1175
1176 zz = zz.mul(z, powers[yi>>(_W-n)])
1177 zz, z = z, zz
1178 zz, r = zz.div(r, z, m)
1179 z, r = r, z
1180
1181 yi <<= n
1182 }
1183 }
1184
1185 return z.norm()
1186 }
1187
1188
1189
1190 func (z nat) expNNMontgomery(x, y, m nat) nat {
1191 numWords := len(m)
1192
1193
1194
1195 if len(x) > numWords {
1196 _, x = nat(nil).div(nil, x, m)
1197
1198 }
1199 if len(x) < numWords {
1200 rr := make(nat, numWords)
1201 copy(rr, x)
1202 x = rr
1203 }
1204
1205
1206
1207
1208 k0 := 2 - m[0]
1209 t := m[0] - 1
1210 for i := 1; i < _W; i <<= 1 {
1211 t *= t
1212 k0 *= (t + 1)
1213 }
1214 k0 = -k0
1215
1216
1217 RR := nat(nil).setWord(1)
1218 zz := nat(nil).shl(RR, uint(2*numWords*_W))
1219 _, RR = nat(nil).div(RR, zz, m)
1220 if len(RR) < numWords {
1221 zz = zz.make(numWords)
1222 copy(zz, RR)
1223 RR = zz
1224 }
1225
1226 one := make(nat, numWords)
1227 one[0] = 1
1228
1229 const n = 4
1230
1231 var powers [1 << n]nat
1232 powers[0] = powers[0].montgomery(one, RR, m, k0, numWords)
1233 powers[1] = powers[1].montgomery(x, RR, m, k0, numWords)
1234 for i := 2; i < 1<<n; i++ {
1235 powers[i] = powers[i].montgomery(powers[i-1], powers[1], m, k0, numWords)
1236 }
1237
1238
1239 z = z.make(numWords)
1240 copy(z, powers[0])
1241
1242 zz = zz.make(numWords)
1243
1244
1245 for i := len(y) - 1; i >= 0; i-- {
1246 yi := y[i]
1247 for j := 0; j < _W; j += n {
1248 if i != len(y)-1 || j != 0 {
1249 zz = zz.montgomery(z, z, m, k0, numWords)
1250 z = z.montgomery(zz, zz, m, k0, numWords)
1251 zz = zz.montgomery(z, z, m, k0, numWords)
1252 z = z.montgomery(zz, zz, m, k0, numWords)
1253 }
1254 zz = zz.montgomery(z, powers[yi>>(_W-n)], m, k0, numWords)
1255 z, zz = zz, z
1256 yi <<= n
1257 }
1258 }
1259
1260 zz = zz.montgomery(z, one, m, k0, numWords)
1261
1262
1263
1264 if zz.cmp(m) >= 0 {
1265
1266
1267
1268
1269
1270
1271
1272 zz = zz.sub(zz, m)
1273 if zz.cmp(m) >= 0 {
1274 _, zz = nat(nil).div(nil, zz, m)
1275 }
1276 }
1277
1278 return zz.norm()
1279 }
1280
1281
1282
1283
1284
1285 func (z nat) bytes(buf []byte) (i int) {
1286 i = len(buf)
1287 for _, d := range z {
1288 for j := 0; j < _S; j++ {
1289 i--
1290 buf[i] = byte(d)
1291 d >>= 8
1292 }
1293 }
1294
1295 for i < len(buf) && buf[i] == 0 {
1296 i++
1297 }
1298
1299 return
1300 }
1301
1302
1303 func bigEndianWord(buf []byte) Word {
1304 if _W == 64 {
1305 return Word(binary.BigEndian.Uint64(buf))
1306 }
1307 return Word(binary.BigEndian.Uint32(buf))
1308 }
1309
1310
1311
1312 func (z nat) setBytes(buf []byte) nat {
1313 z = z.make((len(buf) + _S - 1) / _S)
1314
1315 i := len(buf)
1316 for k := 0; i >= _S; k++ {
1317 z[k] = bigEndianWord(buf[i-_S : i])
1318 i -= _S
1319 }
1320 if i > 0 {
1321 var d Word
1322 for s := uint(0); i > 0; s += 8 {
1323 d |= Word(buf[i-1]) << s
1324 i--
1325 }
1326 z[len(z)-1] = d
1327 }
1328
1329 return z.norm()
1330 }
1331
1332
1333 func (z nat) sqrt(x nat) nat {
1334 if x.cmp(natOne) <= 0 {
1335 return z.set(x)
1336 }
1337 if alias(z, x) {
1338 z = nil
1339 }
1340
1341
1342
1343
1344
1345
1346 var z1, z2 nat
1347 z1 = z
1348 z1 = z1.setUint64(1)
1349 z1 = z1.shl(z1, uint(x.bitLen()+1)/2)
1350 for n := 0; ; n++ {
1351 z2, _ = z2.div(nil, x, z1)
1352 z2 = z2.add(z2, z1)
1353 z2 = z2.shr(z2, 1)
1354 if z2.cmp(z1) >= 0 {
1355
1356
1357 if n&1 == 0 {
1358 return z1
1359 }
1360 return z.set(z1)
1361 }
1362 z1, z2 = z2, z1
1363 }
1364 }
1365
View as plain text