Skip to content

Commit

Permalink
prepare to push the factoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
gogo2464 committed Dec 9, 2023
1 parent 924c686 commit 887e124
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 35 deletions.
10 changes: 4 additions & 6 deletions cryptatools-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@ itertools = "*"
uniffi_bindgen = "*"
time = "*"
rand = "*"
num-bigint = "*"
num-traits = "*"
num = "*"
num-bigfloat = "*"
num-bigint-dig = { version = "0.8", features = ["prime"] }
num-prime = "*"
rug = "1.22.0"

num-bigint = { version = "*", features = [] } #"prime", "rand"
num-bigint-dig = { version = "*", features = ["prime", "rand"], default-features=false }
num-integer = "*"

indicatif = { version = "0.17", optional = true }
primal = "0.3"
Expand All @@ -42,4 +40,4 @@ doc = true
[[bin]]
# This can be whatever name makes sense for your project, but the rest of this tutorial assumes uniffi-bindgen.
name = "uniffi-bindgen"
path = "uniffi-bindgen.rs"
path = "uniffi-bindgen.rs"
77 changes: 48 additions & 29 deletions cryptatools-core/src/maths/ECC.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
use num_bigint::{BigUint, BigInt};
use num_bigint_dig as num_bigint;
use num_bigint_dig::ModInverse;
//use num_bigint_dig as num_bigint;
use num_traits;

use num_bigint_dig::{BigUint, BigInt};
use num_bigint_dig::ModInverse;
use num_bigint_dig::prime::probably_prime;
use num_bigint_dig::ToBigInt;
use num_bigint_dig::RandBigInt;
use num_traits::Pow;
use num_integer::Integer;

#[cfg(feature = "progress-bar")]
use indicatif::ProgressBar;
use primal::Primes;
use std::collections::HashMap;




struct ECC {

}
Expand Down Expand Up @@ -104,6 +106,23 @@ impl Point {
/// assert_eq!(p2.x_cord, BigInt::from(13));
/// assert_eq!(p2.z_cord, BigInt::from(10));
/// ```
///
/// ```
/// use num_bigint::{BigUint, BigInt};
/// use num_bigint_dig as num_bigint;
/// use num_bigint_dig::ModInverse;
/// use num_traits;
/// use num_traits::cast::FromPrimitive;
/// use cryptatools_core::maths::ECC::*;
///
/// let modulus: BigInt = BigInt::from(101);
/// let a: BigInt = BigInt::from(10);
/// let a_24: BigInt = (a + BigInt::from(2)) * BigInt::from(4).mod_inverse(&modulus).unwrap();
/// let p1 = Point::new(BigInt::from(10), BigInt::from(17), a_24.clone(), modulus.clone());
/// let p2 = p1.double();
/// assert_eq!(p2, Point::new(BigInt::from(68), BigInt::from(56), a_24.clone(), modulus.clone()));
/// ```
///
pub fn double(&self) -> Point {
let u = BigInt::from(&self.x_cord + &self.z_cord).sqrt();
let v = BigInt::from(&self.x_cord - &self.z_cord).sqrt();
Expand Down Expand Up @@ -206,7 +225,7 @@ pub enum Error {
/// - `max_curve`: Maximum number of curves generated.
/// - `rgen`: Random number generator.
pub fn ecm_one_factor(
n: &BigUint,
n: &BigInt,
b1: usize,
b2: usize,
max_curve: usize,
Expand All @@ -217,7 +236,7 @@ pub fn ecm_one_factor(
return Err(Error::BoundsNotEven);
}

if probably_prime(n, 0) == true {
if probably_prime(&n.to_biguint().unwrap(), 0) == true {
return Err(Error::NumberIsPrime);
}

Expand Down Expand Up @@ -247,28 +266,28 @@ pub fn ecm_one_factor(
}

// Suyama's Parametrization
let sigma = (n - BigInt::from(1).to_biguint().unwrap()).to_bigint().unwrap().random_below(rgen);
let sigma = BigInt::from(rand::thread_rng().gen_biguint_below(&BigUint::from(rgen))); //let sigma = (n - BigInt::from(1).to_biguint().unwrap()).to_bigint().unwrap().gen_biguint_below(&BigUint::from(rgen));
let u = (&sigma * &sigma - BigInt::from(5)) % n;
let v = (BigInt::from(4) * sigma) % n;
let v : BigInt = (BigInt::from(4) * sigma) % n;
let diff = v.clone() - u.clone();
let u_3 = u.clone().pow(3) % n;
let u_3 : BigInt = u.clone().pow(3 as u32) % n;

let c = match (BigInt::from(4) * &u_3 * &v).invert(n) {
Ok(c) => {
(diff.pow_mod(&BigInt::from(3), n).unwrap() * (BigInt::from(4) * &u + &v) * c
let c = match (BigInt::from(4) * &u_3 * &v).mod_inverse(n) {
Some(c) => {
(diff.modpow(&BigInt::from(3), n) * (BigInt::from(4) * &u + &v) * c
- BigInt::from(2))
% n
}
_ => return Ok((BigInt::from(4) * u_3 * v).gcd(n)),
};

let a24 = (c + 2) * BigInt::from(4).invert(n).unwrap() % n;
let q = Point::new(u_3, v.pow(3) % n, a24, n.clone());
let a24 = (c + 2) * BigInt::from(4).mod_inverse(n).unwrap() % n;
let q = Point::new(u_3, v.pow(3 as u32) % n, a24, n.clone());
let q = q.mont_ladder(&k);
let g = q.z_cord.clone().gcd(n);

// Stage 1 factor
if &g != n && g != 1 {
if &g != n && g != BigInt::from(1) {
return Ok(g);
}

Expand Down Expand Up @@ -311,7 +330,7 @@ pub fn ecm_one_factor(
g = g.gcd(n);

// Stage 2 Factor found
if &g != n && g != 1 {
if &g != n && g != BigInt::from(1) {
return Ok(g);
}
}
Expand Down Expand Up @@ -348,7 +367,7 @@ fn optimal_b1(digits: usize) -> usize {
///
/// - `n`: Number to be factored.
pub fn ecm(
n: &BigUint,
n: &BigInt,
#[cfg(feature = "progress-bar")] pb: Option<&ProgressBar>,
) -> Result<HashMap<BigInt, usize>, Error> {
ecm_with_params(
Expand Down Expand Up @@ -376,7 +395,7 @@ pub fn ecm(
/// - `max_curve`: Maximum number of curves generated.
/// - `seed`: Initialize pseudorandom generator.
pub fn ecm_with_params(
n: &BigUint,
n: &BigInt,
b1: usize,
b2: usize,
max_curve: usize,
Expand All @@ -387,31 +406,31 @@ pub fn ecm_with_params(

let mut n: BigInt = n.clone();
for prime in Primes::all().take(100_000) {
if n.is_divisible_u(prime as u32) {
let prime = BigInt::from(prime);
while n.is_divisible(&prime) {
n /= &prime;
if n.is_multiple_of(&BigInt::from(prime)) {
let prime = BigInt::from(prime.clone());
while n.is_multiple_of(&prime) {
n /= prime.clone();
*factors.entry(prime.clone()).or_insert(0) += 1;
}
}
}

let mut rand_state = RandState::new();
rand_state.seed(&seed.into());
//let mut rand_state = RandState::new();
//rand_state.seed(&seed.into());

while n != 1 {
while n.to_bigint().unwrap() != BigInt::from(1) {
let factor = ecm_one_factor(
&n,
&n.to_bigint().unwrap(),
b1,
b2,
max_curve,
16,// 16 is an hardcoded random generated number
#[cfg(feature = "progress-bar")]
pb,
)
.unwrap_or(n.clone());
.unwrap_or(n.to_bigint().unwrap().clone());

while n.is_divisible(&factor) {
while n.is_multiple_of(&factor) {
n /= &factor;
*factors.entry(factor.clone()).or_insert(0) += 1;
}
Expand Down

0 comments on commit 887e124

Please sign in to comment.