@@ -22,8 +22,9 @@ func addmod_internal(a, b, m: StUint): StUint {.inline.}=
22
22
let b_from_m = m - b
23
23
24
24
if a >= b_from_m:
25
- return a - b_from_m
26
- return m - b_from_m + a
25
+ a - b_from_m
26
+ else :
27
+ m - b_from_m + a
27
28
28
29
func submod_internal(a, b, m: StUint): StUint {.inline.}=
29
30
# # Modular substraction
@@ -34,53 +35,9 @@ func submod_internal(a, b, m: StUint): StUint {.inline.}=
34
35
35
36
# We don't do a_m - b_m directly to avoid underflows
36
37
if a >= b:
37
- return a - b
38
- return m - b + a
39
-
40
-
41
- func doublemod_internal(a, m: StUint): StUint {.inline.}=
42
- # # Double a modulo m. Assume a < m
43
- # # Internal proc - used in mulmod
44
-
45
- doAssert a < m
46
-
47
- result = a
48
- if a >= m - a:
49
- result -= m
50
- result += a
51
-
52
- func mulmod_internal(a, b, m: StUint): StUint {.inline.}=
53
- # # Does (a * b) mod m. Assume a < m and b < m
54
- # # Internal proc - used in powmod
55
-
56
- doAssert a < m
57
- doAssert b < m
58
-
59
- var (a, b) = (a, b)
60
-
61
- if b > a:
62
- swap(a, b)
63
-
64
- while not b.isZero:
65
- if b.isOdd:
66
- result = result .addmod_internal(a, m)
67
- a = doublemod_internal(a, m)
68
- b = b shr 1
69
-
70
- func powmod_internal(a, b, m: StUint): StUint {.inline.}=
71
- # # Compute ``(a ^ b) mod m``, assume a < m
72
- # # Internal proc
73
-
74
- doAssert a < m
75
-
76
- var (a, b) = (a, b)
77
- result = one(type a)
78
-
79
- while not b.isZero:
80
- if b.isOdd:
81
- result = result .mulmod_internal(a, m)
82
- b = b shr 1
83
- a = mulmod_internal(a, a, m)
38
+ a - b
39
+ else :
40
+ m - b + a
84
41
85
42
func addmod* (a, b, m: StUint): StUint =
86
43
# # Modular addition
@@ -90,7 +47,7 @@ func addmod*(a, b, m: StUint): StUint =
90
47
let b_m = if b < m: b
91
48
else : b mod m
92
49
93
- result = addmod_internal(a_m, b_m, m)
50
+ addmod_internal(a_m, b_m, m)
94
51
95
52
func submod* (a, b, m: StUint): StUint =
96
53
# # Modular substraction
@@ -100,24 +57,29 @@ func submod*(a, b, m: StUint): StUint =
100
57
let b_m = if b < m: b
101
58
else : b mod m
102
59
103
- result = submod_internal(a_m, b_m, m)
60
+ submod_internal(a_m, b_m, m)
104
61
105
62
func mulmod* (a, b, m: StUint): StUint =
106
63
# # Modular multiplication
107
64
108
- let a_m = if a < m: a
109
- else : a mod m
110
- let b_m = if b < m: b
111
- else : b mod m
65
+ let
66
+ ax = a.stuint(a.bits * 2 )
67
+ bx = b.stuint(b.bits * 2 )
68
+ mx = m.stuint(m.bits * 2 )
69
+ px = ax * bx
112
70
113
- result = mulmod_internal(a_m, b_m, m )
71
+ divmod(px, mx).rem.stuint(a.bits )
114
72
115
73
func powmod* (a, b, m: StUint): StUint =
116
74
# # Modular exponentiation
117
75
118
- let a_m = if a < m: a
119
- else : a mod m
76
+ var (a, b) = (a, b)
77
+ result = one( type a)
120
78
121
- result = powmod_internal(a_m, b, m)
79
+ while not b.isZero:
80
+ if b.isOdd:
81
+ result = result .mulmod(a, m)
82
+ b = b shr 1
83
+ a = mulmod(a, a, m)
122
84
123
85
{.pop.}
0 commit comments