use 16-bit n and add comments
This commit is contained in:
parent
b8775f3675
commit
7960658ef9
2 changed files with 50 additions and 26 deletions
10
src/main.rs
10
src/main.rs
|
@ -1,7 +1,13 @@
|
|||
mod pollard_rho;
|
||||
|
||||
fn main() {
|
||||
let n = rand::random::<u8>();
|
||||
let mut n = 0;
|
||||
while n % 2 == 0 {
|
||||
n = rand::random::<u16>();
|
||||
}
|
||||
let n_primediv = pollard_rho::pollard_rho(n.into());
|
||||
eprintln!("Generated random number {}, got prime divisor {}", n, n_primediv);
|
||||
eprintln!(
|
||||
"Generated random number {}, got prime divisor {}",
|
||||
n, n_primediv
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,29 +1,44 @@
|
|||
use gcd::Gcd;
|
||||
|
||||
/**
|
||||
* Calculate the primedivisor for some number `n`
|
||||
* Calculate the prime divisor for some number `n`
|
||||
*
|
||||
* Uses cycle finding
|
||||
*/
|
||||
pub fn pollard_rho(n: u16) -> u16 {
|
||||
if n == 1 { return 1; } // 1 only has 1 as prime divisor
|
||||
if n % 2 == 0 { return 2; } // even numbers have at least 2 as prime divisor
|
||||
if is_prime(n) { return n; }
|
||||
pub fn pollard_rho(n: u32) -> u32 {
|
||||
if n == 1 {
|
||||
return 1;
|
||||
} // 1 only has 1 as prime divisor
|
||||
if n % 2 == 0 {
|
||||
return 2;
|
||||
} // even numbers have at least 2 as prime divisor
|
||||
if is_prime(n) {
|
||||
return n;
|
||||
} // need to detect to be able to decide if we have bad random numbers or the
|
||||
|
||||
let mut x = rand::random::<u16>() % 2;
|
||||
let mut y = x;
|
||||
let mut x = rand::random::<u32>() % n; // cycle finding: tortoise
|
||||
let mut y = x; // cycle finding: hare
|
||||
|
||||
let c = rand::random::<u16>() % 2;
|
||||
let mut div = 1;
|
||||
let c = rand::random::<u32>() % n; // random number to add to the cycle finding moves
|
||||
let mut div = 1; // divisor - 1 applies to all numbers and is our failed and start value
|
||||
|
||||
while div == 1 {
|
||||
// tortoise move
|
||||
x = (mod_pow(x, 2, n) + c + n) % n;
|
||||
// hare move
|
||||
y = (mod_pow(y, 2, n) + c + n) % n;
|
||||
y = (mod_pow(y, 2, n) + c + n) % n;
|
||||
div = u16::try_from((i16::try_from(x).unwrap()-i16::try_from(y).unwrap()).abs()).unwrap().gcd(n);
|
||||
eprintln!("Got div {}", div);
|
||||
if div == n { return pollard_rho(n); }
|
||||
// divisor is the greatest common divisor between |x-y| and n
|
||||
div = u32::try_from((i32::try_from(x).unwrap() - i32::try_from(y).unwrap()).abs())
|
||||
.unwrap()
|
||||
.gcd(n);
|
||||
// bad random numbers, try again
|
||||
if div == n {
|
||||
return pollard_rho(n);
|
||||
}
|
||||
}
|
||||
|
||||
return div;
|
||||
div
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,19 +50,22 @@ pub fn pollard_rho(n: u16) -> u16 {
|
|||
*
|
||||
* Counterpart function to the discrete logarithm.
|
||||
*/
|
||||
fn mod_pow(base: u16, exp: u16, r#mod: u16) -> u16 {
|
||||
fn mod_pow(base: u32, exp: u32, r#mod: u32) -> u32 {
|
||||
let mut result = 1;
|
||||
|
||||
for _ in 0..exp-1 {
|
||||
for _ in 0..exp - 1 {
|
||||
result = (result * base) % r#mod;
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn is_prime(n: u16) -> bool {
|
||||
for i in (3..=(n as f32).sqrt() as u16).step_by(2) {
|
||||
if n % i == 0 { return false; }
|
||||
/**
|
||||
* very primitive prime checker
|
||||
*/
|
||||
fn is_prime(n: u32) -> bool {
|
||||
for i in (3..=(n as f32).sqrt() as u32).step_by(2) {
|
||||
if n % i == 0 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue