Skip to content

Commit 57b2c5f

Browse files
authored
Fixed gcd_extended and mod_inverse for modular exponential (#750)
1 parent 864ef42 commit 57b2c5f

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

src/math/modular_exponential.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@
88
///
99
/// # Returns
1010
///
11-
/// A tuple (gcd, x) such that:
11+
/// A tuple (gcd, x1, x2) such that:
1212
/// gcd - the greatest common divisor of a and m.
13-
/// x - the coefficient such that `a * x` is equivalent to `gcd` modulo `m`.
14-
pub fn gcd_extended(a: i64, m: i64) -> (i64, i64) {
13+
/// x1, x2 - the coefficients such that `a * x1 + m * x2` is equivalent to `gcd` modulo `m`.
14+
pub fn gcd_extended(a: i64, m: i64) -> (i64, i64, i64) {
1515
if a == 0 {
16-
(m, 0)
16+
(m, 0, 1)
1717
} else {
18-
let (gcd, x1) = gcd_extended(m % a, a);
19-
let x = x1 - (m / a) * x1;
20-
(gcd, x)
18+
let (gcd, x1, x2) = gcd_extended(m % a, a);
19+
let x = x2 - (m / a) * x1;
20+
(gcd, x, x1)
2121
}
2222
}
2323

@@ -36,7 +36,7 @@ pub fn gcd_extended(a: i64, m: i64) -> (i64, i64) {
3636
///
3737
/// Panics if the inverse does not exist (i.e., `b` and `m` are not coprime).
3838
pub fn mod_inverse(b: i64, m: i64) -> i64 {
39-
let (gcd, x) = gcd_extended(b, m);
39+
let (gcd, x, _) = gcd_extended(b, m);
4040
if gcd != 1 {
4141
panic!("Inverse does not exist");
4242
} else {
@@ -96,6 +96,15 @@ mod tests {
9696
assert_eq!(modular_exponential(123, 45, 67), 62); // 123^45 % 67
9797
}
9898

99+
#[test]
100+
fn test_modular_inverse() {
101+
assert_eq!(mod_inverse(7, 13), 2); // Inverse of 7 mod 13 is 2
102+
assert_eq!(mod_inverse(5, 31), 25); // Inverse of 5 mod 31 is 25
103+
assert_eq!(mod_inverse(10, 11), 10); // Inverse of 10 mod 1 is 10
104+
assert_eq!(mod_inverse(123, 67), 6); // Inverse of 123 mod 67 is 6
105+
assert_eq!(mod_inverse(9, 17), 2); // Inverse of 9 mod 17 is 2
106+
}
107+
99108
#[test]
100109
fn test_modular_exponential_negative() {
101110
assert_eq!(
@@ -111,8 +120,8 @@ mod tests {
111120
mod_inverse(10, 11).pow(8) % 11
112121
); // Inverse of 10 mod 11 is 10, 10^8 % 11 = 10
113122
assert_eq!(
114-
modular_exponential(123, -45, 67),
115-
mod_inverse(123, 67).pow(45) % 67
123+
modular_exponential(123, -5, 67),
124+
mod_inverse(123, 67).pow(5) % 67
116125
); // Inverse of 123 mod 67 is calculated via the function
117126
}
118127

0 commit comments

Comments
 (0)