factorizer

This commit is contained in:
Christoph J. Scherr 2023-05-27 18:05:53 +02:00
parent 4943a7d47c
commit 44e2a6876e
Signed by: PlexSheep
GPG Key ID: 25B4ACF7D88186CC
8 changed files with 114 additions and 4 deletions

View File

@ -1,7 +1,7 @@
[package] [package]
name = "plexcryptool" name = "plexcryptool"
authors = ["Christoph J. Scherr <software@cscherr.de>"] authors = ["Christoph J. Scherr <software@cscherr.de>"]
version = "0.2.5" version = "0.2.7"
edition = "2021" edition = "2021"
readme = "README.md" readme = "README.md"
description = "Various tools for use with math and cryptology, includes executable and a library." description = "Various tools for use with math and cryptology, includes executable and a library."

View File

@ -70,8 +70,12 @@ pub enum MathActions {
Modred(ModredArgs), Modred(ModredArgs),
/// p minus 1 prime test /// p minus 1 prime test
Pm1(PM1Args), Pm1(PM1Args),
//// calculate in a gallois field /// calculate in a gallois field
Gallois(GalloisAction), Gallois(GalloisAction),
/// Euklidian Algorithm
Gcd(GcdArgs),
/// factorize a natural number
Factorize(FactorizeArgs)
} }
#[derive(Args, Clone, Debug, PartialEq, Eq)] #[derive(Args, Clone, Debug, PartialEq, Eq)]
@ -105,6 +109,25 @@ pub struct GalloisAction {
pub action: GalloisActions pub action: GalloisActions
} }
#[derive(Args, Clone, Debug, PartialEq, Eq)]
pub struct GcdArgs {
#[clap(value_parser=maybe_hex::<u128>)]
/// first number
pub a: u128,
#[clap(value_parser=maybe_hex::<u128>)]
/// second number
pub b: u128,
#[arg(short, long, default_value_t = false)]
/// use extended gcd
pub ext: bool
}
#[derive(Args, Clone, Debug, PartialEq, Eq)]
pub struct FactorizeArgs {
#[clap(value_parser=maybe_hex::<u128>)]
pub n: u128,
}
#[derive(Subcommand, Clone, Debug, PartialEq, Eq)] #[derive(Subcommand, Clone, Debug, PartialEq, Eq)]
pub enum GalloisActions { pub enum GalloisActions {
/// draw the root of n /// draw the root of n

View File

@ -138,10 +138,10 @@ pub fn proc_vec<T>(vec: Vec<T>, args: Cli)
seperator(); seperator();
} }
if args.machine { if args.machine {
println!("{:#?}", vec); println!("{:?}", vec);
} }
else { else {
println!("result is\n{:#?}", vec); println!("result is\n{:?}", vec);
} }
} }

View File

@ -52,6 +52,9 @@ fn register_math_module(py: Python, parent_module: &PyModule) -> PyResult<()> {
let math_module = PyModule::new(py, "math")?; let math_module = PyModule::new(py, "math")?;
math_module.add_function(wrap_pyfunction!(math::modexp::py_modular_exponentiation, math_module)?)?; math_module.add_function(wrap_pyfunction!(math::modexp::py_modular_exponentiation, math_module)?)?;
math_module.add_function(wrap_pyfunction!(math::pm1::py_p_minus_one, math_module)?)?; math_module.add_function(wrap_pyfunction!(math::pm1::py_p_minus_one, math_module)?)?;
math_module.add_function(wrap_pyfunction!(math::gcd::gcd, math_module)?)?;
math_module.add_function(wrap_pyfunction!(math::gcd::egcd, math_module)?)?;
math_module.add_function(wrap_pyfunction!(math::factorise::prime_factors , math_module)?)?;
parent_module.add_submodule(math_module)?; parent_module.add_submodule(math_module)?;
Ok(()) Ok(())
} }

View File

@ -77,6 +77,20 @@ pub fn main() {
} }
} }
} }
MathActions::Factorize(fac_args) => {
let vec = math::factorise::prime_factors(fac_args.n, args.verbose);
cplex::printing::proc_vec(vec, args);
}
MathActions::Gcd(gcd_args) => {
if gcd_args.ext {
let vec = math::gcd::egcd(gcd_args.a, gcd_args.b);
cplex::printing::proc_vec(vec, args)
}
else {
let num = math::gcd::gcd(gcd_args.a, gcd_args.b);
cplex::printing::proc_num(num, args)
}
}
} }
} }
Commands::Binary(action) => { Commands::Binary(action) => {

38
src/math/factorise.rs Normal file
View File

@ -0,0 +1,38 @@
#![allow(dead_code)]
/// factorize a large integer
///
/// Author: Christoph J. Scherr <software@cscherr.de>
/// License: MIT
/// Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
use pyo3::prelude::*;
#[pyfunction]
/// find the prime factors of n
pub fn prime_factors(mut n: u128, verbose: bool) -> Vec<u128> {
let mut i: u128 = 2;
let mut factors: Vec<u128> = Vec::new();
while i.pow(2) <= n {
if n % i > 0 {
i += 1;
}
else {
n = n.checked_div(i).expect("n / i is not an integer");
factors.push(i);
}
if verbose {
println!("i={i}\t{:?}", factors);
}
}
if n > 1 {
factors.push(n);
}
return factors;
}
#[test]
fn test_prime_factors() {
assert_eq!(prime_factors(360, true), vec![2, 2, 2, 3, 3, 5]);
// see https://math.tools/numbers/prime-factors/3603234
assert_eq!(prime_factors(3603234, true), vec![2, 3, 223, 2693]);
}

30
src/math/gcd.rs Normal file
View File

@ -0,0 +1,30 @@
#![allow(dead_code)]
/// euclidian algorithm, find greatest common divider
///
/// This does not implement the euclidian algorithm by itself.
///
/// Author: Christoph J. Scherr <software@cscherr.de>
/// License: MIT
/// Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
use num::Integer;
use pyo3::prelude::*;
#[pyfunction]
/// extended euclidian algorithm
pub fn egcd(mut a: u128, mut b: u128) -> Vec<i128> {
if a > b {
let tmp = a;
a = b;
b = tmp;
}
let egcd = (a as i128).extended_gcd(&(b as i128));
return vec![egcd.gcd, egcd.x, egcd.y]
}
#[pyfunction]
/// euclidian algorithm
pub fn gcd(a: u128, b: u128) -> u128 {
a.gcd(&b)
}

View File

@ -10,3 +10,5 @@ pub mod modexp;
pub mod pm1; pub mod pm1;
pub mod modred; pub mod modred;
pub mod gallois; pub mod gallois;
pub mod gcd;
pub mod factorise;