Skip to content

Commit de1e3d4

Browse files
committed
Restrict modular inverse to signed integers
1 parent ff40799 commit de1e3d4

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

src/util/math.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ pub trait IntegerMathOps<T: Integer<T>> {
2020
fn gcd(self, b: T) -> T;
2121
fn lcm(self, b: T) -> T;
2222
fn mod_pow(self, e: T, m: T) -> T;
23-
fn mod_inv(self, m: T) -> T;
2423
}
2524

2625
pub trait UnsignedMathOps<T: Unsigned<T>> {
2726
fn sqrt(self) -> T;
2827
}
2928

29+
pub trait SignedMathOps<T: Signed<T>> {
30+
fn mod_inv(self, m: T) -> T;
31+
}
32+
3033
impl<T: Integer<T>> IntegerMathOps<T> for T {
3134
/// Greatest common divisor
3235
fn gcd(self, mut b: T) -> T {
@@ -59,7 +62,27 @@ impl<T: Integer<T>> IntegerMathOps<T> for T {
5962

6063
c
6164
}
65+
}
66+
67+
impl<T: Unsigned<T>> UnsignedMathOps<T> for T {
68+
// Integer square root. Once [`isqrt`] is stablized then this function can be removed.
69+
fn sqrt(self) -> T {
70+
let mut bit = T::ONE << (self.ilog2() >> T::ONE);
71+
let mut root = bit;
6272

73+
while bit > T::ONE {
74+
bit = bit >> T::ONE;
75+
let next = root | bit;
76+
if next * next <= self {
77+
root = next;
78+
}
79+
}
80+
81+
root
82+
}
83+
}
84+
85+
impl<T: Signed<T>> SignedMathOps<T> for T {
6386
// Modular multiplicative inverse
6487
fn mod_inv(self, m: T) -> T {
6588
let mut t = T::ZERO;
@@ -79,21 +102,3 @@ impl<T: Integer<T>> IntegerMathOps<T> for T {
79102
t
80103
}
81104
}
82-
83-
impl<T: Unsigned<T>> UnsignedMathOps<T> for T {
84-
// Once [`isqrt`] is stablized then this function can be removed.
85-
fn sqrt(self) -> T {
86-
let mut bit = T::ONE << (self.ilog2() >> T::ONE);
87-
let mut root = bit;
88-
89-
while bit > T::ONE {
90-
bit = bit >> T::ONE;
91-
let next = root | bit;
92-
if next * next <= self {
93-
root = next;
94-
}
95-
}
96-
97-
root
98-
}
99-
}

0 commit comments

Comments
 (0)