Skip to content

Commit

Permalink
Switch from u128 -> BigInt in pollards rho (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
hesampakdaman authored Apr 7, 2024
1 parent 6c86b39 commit e052c77
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 25 deletions.
12 changes: 8 additions & 4 deletions src/algorithms/pollards_rho.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@ use crate::orchestration;
use crate::primality_test::MillerRabin;
use crate::traits::Factorize;
use crate::PrimeFactorization;
use num_bigint::BigInt;
use num_integer::Integer;
use num_traits::{One, Signed};

pub struct PollardsRho;

impl Factorize for PollardsRho {
fn factorize(n: u128) -> u128 {
let init = 2;
let psudorandom_fn = utils::generate_psudeorandom_fn(n);
let finished = |x: u128, y: u128| utils::gcd(x.abs_diff(y), n) != 1;
let n = BigInt::from(n);
let init = BigInt::from(2);
let psudorandom_fn = utils::generate_pseudorandom_fn(&n);
let finished = |x: &BigInt, y: &BigInt| (x - y).abs().gcd(&n) != BigInt::one();
let (tortoise, hare) = utils::floyds_cycle_detection(init, &psudorandom_fn, &finished);
utils::gcd(tortoise.abs_diff(hare), n)
(hare - tortoise).abs().gcd(&n).try_into().unwrap()
}
}

Expand Down
34 changes: 13 additions & 21 deletions src/algorithms/pollards_rho/utils.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
use rand::Rng;
use std::ops::Range;
use num_bigint::{BigInt, RandBigInt};
use num_traits::One;

pub fn floyds_cycle_detection<F, P>(init: u128, next: &F, finished: &P) -> (u128, u128)
pub fn floyds_cycle_detection<F, P>(init: BigInt, next: &F, finished: &P) -> (BigInt, BigInt)
where
F: Fn(u128) -> u128 + ?Sized,
P: Fn(u128, u128) -> bool + ?Sized,
F: Fn(&BigInt) -> BigInt + ?Sized,
P: Fn(&BigInt, &BigInt) -> bool + ?Sized,
{
let mut tortoise = init;
let mut hare = next(tortoise);
while !finished(tortoise, hare) {
tortoise = next(tortoise);
hare = next(next(hare));
let mut hare = next(&tortoise);
while !finished(&tortoise, &hare) {
tortoise = next(&tortoise);
hare = next(&next(&hare));
}
(tortoise, hare)
}

pub fn gcd(a: u128, b: u128) -> u128 {
if b == 0 {
return a;
}
gcd(b, a % b)
}

pub fn generate_psudeorandom_fn(n: u128) -> impl Fn(u128) -> u128 {
let c = random_integer(1..n);
move |x| (x * x + c) % n
pub fn generate_pseudorandom_fn(n: &'_ BigInt) -> impl Fn(&BigInt) -> BigInt + '_ {
move |x| (x.pow(2) + random_integer(n)) % n
}

fn random_integer(r: Range<u128>) -> u128 {
rand::thread_rng().gen_range(r)
fn random_integer(bound: &BigInt) -> BigInt {
rand::thread_rng().gen_bigint_range(&BigInt::one(), bound)
}

0 comments on commit e052c77

Please sign in to comment.