///|
/// Pollard's Rho algorithm for integer factorization with Brent's cycle detection.
///
/// ### Parameters
/// * `n`: Composite number to be factored.
/// * `k`: Frequency of GCD computations.
/// * `c`: Constant used in the polynomial function.
/// * `f`: Polynomial function (default is f(t) = (t^2 + c) mod n).
/// * `rand`: Random number generator (default is a time-based seed).
/// * `retry`: Number of attempts to find a non-trivial factor.
pub fn pollard_rho_brent(
n : BigInt,
k? : Int = 128,
c? : (@random.Rand) -> BigInt = rand => random_range(rand, 1, n - 1),
f? : (BigInt, BigInt, BigInt) -> BigInt = (t, c, n) => (t * t + c).mod(n),
rand? : @random.Rand = random_time_based(),
retry? : Int = 10,
) -> BigInt {
for _ in 0.. 1 && d < n {
return d
}
}
n
}
///|
/// ### Parameters
/// * `n`: Composite number to be factored.
/// * `k`: Frequency of GCD computations.
/// * `c`: Constant used in the polynomial function.
/// * `f`: Polynomial function (default is f(t) = (t^2 + c) mod n).
/// * `rand`: Random number generator (default is a time-based seed).
pub fn pollard_rho_brent_loop(
n : BigInt,
k? : Int = 128,
c? : (@random.Rand) -> BigInt = rand => random_range(rand, 1, n - 1),
f? : (BigInt, BigInt, BigInt) -> BigInt = (t, c, n) => (t * t + c).mod(n),
rand? : @random.Rand = random_time_based(),
) -> BigInt {
guard n > 2 else { n }
guard @prime.is_odd(n) else { n >> 1 }
let c = c(rand) // fixed constant
let mut t : BigInt = 2
for goal = 1; ; goal = goal << 1 {
let s = t
let mut v : BigInt = 1
for step in 1..<=goal {
t = f(t, c, n)
v = v * abs(t - s) % n
guard !v.is_zero() else { return n }
if step % k == 0 {
let d = gcd(v, n)
guard !(d > 1) else { return d }
}
}
let d = gcd(v, n)
guard !(d > 1) else { return d }
}
}