p minus one working
This commit is contained in:
parent
462ee87ac4
commit
cc1116c2ca
|
@ -16,6 +16,8 @@ path = "src/main.rs"
|
|||
[dependencies]
|
||||
clap = { version = "4.2.7", features = ["derive"]}
|
||||
clap-num = "1.0.2"
|
||||
num = "0.4.0"
|
||||
num-bigint = "0.4.3"
|
||||
num-traits = "0.2.15"
|
||||
primes = "0.3.0"
|
||||
pyo3 = "0.18.1"
|
||||
|
|
32
src/main.rs
32
src/main.rs
|
@ -78,6 +78,7 @@ struct AlgoCommand {
|
|||
enum MathActions {
|
||||
#[command(name="modexp")]
|
||||
Modexp(ModexpArgs),
|
||||
Pm1(PM1Args),
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -87,6 +88,12 @@ struct ModexpArgs {
|
|||
field: String
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug, PartialEq, Eq)]
|
||||
struct PM1Args {
|
||||
n: u128,
|
||||
max_prime: u128,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Clone, Debug, PartialEq, Eq)]
|
||||
enum BinaryActions {
|
||||
/// bit rotation/circular shifting (only 32bit)
|
||||
|
@ -165,6 +172,31 @@ pub fn main() {
|
|||
println!("result is {}", result)
|
||||
}
|
||||
}
|
||||
MathActions::Pm1(pm1_args) => {
|
||||
let result: Result<Vec<u128>, String> = math::pm1::p_minus_one(
|
||||
pm1_args.n,
|
||||
pm1_args.max_prime,
|
||||
args.verbose
|
||||
);
|
||||
match result {
|
||||
Ok(vec) => {
|
||||
if args.machine {
|
||||
println!("{:?}", vec)
|
||||
}
|
||||
else {
|
||||
println!("result is {:?}", vec)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if args.machine {
|
||||
println!("{:?}", e)
|
||||
}
|
||||
else {
|
||||
println!("could not compute: {:?}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Commands::Binary(action) => {
|
||||
|
|
|
@ -7,3 +7,4 @@
|
|||
/// License: MIT
|
||||
/// Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
|
||||
pub mod modexp;
|
||||
pub mod pm1;
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
#![allow(dead_code)]
|
||||
/// P minus 1 method
|
||||
///
|
||||
/// Determine the prime factors of a number with the p minus 1 method.
|
||||
/// Effecient for numbers with low ranged prime factors.
|
||||
///
|
||||
/// Author: Christoph J. Scherr <software@cscherr.de>
|
||||
/// License: MIT
|
||||
/// Source: <https://git.cscherr.de/PlexSheep/plexcryptool/>
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
use num::integer::gcd;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use primes::{Sieve, PrimeSet};
|
||||
|
||||
use crate::math::modexp;
|
||||
|
||||
/// excecute the p minus one calculation
|
||||
pub fn p_minus_one(n: u128, max_prime: u128, verbose: bool) -> Result<Vec<u128>, String> {
|
||||
assert!(n > 2);
|
||||
let m1: u128 = n -1;
|
||||
let mut k_parts: Vec<(u128, u32)> = Vec::new();
|
||||
let mut prime_parts: Vec<u128> = Vec::new();
|
||||
//
|
||||
// get a list of the early primes
|
||||
let mut pset = Sieve::new();
|
||||
if verbose {
|
||||
println!("getting list of first {max_prime} primes");
|
||||
}
|
||||
for (_i_prime, prime) in pset.iter().enumerate().take(max_prime as usize) {
|
||||
let num: u128 = prime as u128;
|
||||
if num > max_prime {
|
||||
break;
|
||||
}
|
||||
let mut exp: u32 = 1;
|
||||
if verbose {
|
||||
println!("current prime: {num}");
|
||||
}
|
||||
loop {
|
||||
if num.pow(exp + 1) < max_prime {
|
||||
exp += 1;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if verbose {
|
||||
println!("exponented prime: {}", num.pow(exp));
|
||||
}
|
||||
k_parts.push((num, exp));
|
||||
}
|
||||
let mut k = 1u128;
|
||||
for (num, exp) in k_parts.clone() {
|
||||
k = num.pow(exp) * k;
|
||||
if verbose {
|
||||
println!("k at step: {k}");
|
||||
}
|
||||
}
|
||||
if verbose {
|
||||
println!("k: {k}\nk parts: {:?}", k_parts);
|
||||
}
|
||||
|
||||
let a = 2u128;
|
||||
let akn1: u128 = ((modexp::modular_exponentiation(
|
||||
BigInt::from(a),
|
||||
BigInt::from(k),
|
||||
BigInt::from(n),
|
||||
false)
|
||||
) - BigInt::from(1)).try_into().expect("Number too big");
|
||||
if verbose {
|
||||
println!("a: {a}\na**k-1 {akn1}");
|
||||
}
|
||||
let mut next_gcd = gcd(akn1, n);
|
||||
|
||||
if next_gcd == 1 {
|
||||
return Err(format!("P minus one does not offer divisor for {n} with max_prime: {max_prime}"));
|
||||
}
|
||||
let mut q: u128;
|
||||
while next_gcd > 1 {
|
||||
prime_parts.push(next_gcd);
|
||||
q = n / next_gcd;
|
||||
next_gcd = gcd(q, n);
|
||||
if verbose {
|
||||
println!("nextgcd: {next_gcd}|q: {q}");
|
||||
}
|
||||
if prime_parts.contains(&next_gcd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Ok(prime_parts);
|
||||
}
|
||||
|
||||
/// alternative simple implementation for gcd
|
||||
pub fn alt_gcd(mut a: u128, mut b: u128) -> u128 {
|
||||
let mut tmp: u128;
|
||||
while b > 0 {
|
||||
tmp = b;
|
||||
b = a % b;
|
||||
a = tmp;
|
||||
}
|
||||
return a;
|
||||
}
|
Loading…
Reference in New Issue