From 07556eaaa52533d2c2cf586199ddda4c1a439805 Mon Sep 17 00:00:00 2001 From: Gerald Teschl Date: Wed, 23 Oct 2024 17:26:18 +0200 Subject: [PATCH] Small improvements --- doc/kryptools.ipynb | 19 +++++++++++++++---- kryptools/factor.py | 11 ++++++++--- kryptools/factor_ecm.py | 5 +++-- kryptools/factor_pm1.py | 20 +++++++++++++------- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/doc/kryptools.ipynb b/doc/kryptools.ipynb index 6ca55b1..374a5af 100644 --- a/doc/kryptools.ipynb +++ b/doc/kryptools.ipynb @@ -1088,7 +1088,7 @@ "text": [ "Factoring: 340282366920938463463374607431768211457 (39 digits)\n", "Trial division found: []\n", - "Round 1\n", + "Round 1 (B1=5000)\n", "Factors found (ecm): [59649589127497217, 5704689200685129054721]\n" ] }, @@ -1135,7 +1135,7 @@ { "data": { "text/plain": [ - "[3, 19, 1579]" + "[487, 1709]" ] }, "execution_count": 35, @@ -1146,7 +1146,7 @@ "source": [ "from kryptools.factor_fmt import factor_fermat\n", "\n", - "factor_fermat(90003)" + "factor_fermat(832283)" ] }, { @@ -1162,7 +1162,18 @@ "execution_count": 36, "id": "39f76a97-1b88-4b95-aac7-bf403043d7b7", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "1709" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from kryptools.factor_pm1 import factor_pm1\n", "\n", diff --git a/kryptools/factor.py b/kryptools/factor.py index d6bb838..bcf2b46 100644 --- a/kryptools/factor.py +++ b/kryptools/factor.py @@ -107,14 +107,19 @@ def add_factors(m: int, mm: tuple) -> None: fermat_steps = 10 for round, parameters in enumerate(ECM_PARAMETERS): - if verbose: - print(f"Round {round+1}") fermat_steps += 10 B1, B2, num_curves = parameters + p_max = isqrt(max(remaining_factors))+1 + B1 = min(B1, p_max//50) + B2 = min(B2, p_max) num_curves *= 2 D = isqrt(B2) + + if verbose: + print(f"Round {round+1} (B1={B1})") + primes = sieve_eratosthenes(B1 - 1 + ((B2 - B1 + 1) // (2 * D) + 1) * 2 * D) - pm1_parameters = _pm1_parameters(10 * B1, B2, primes = primes) + pm1_parameters = tuple([10 * B1, B2] + list(_pm1_parameters(10 * B1, B2, primes = primes))) ecm_parameters = tuple([B1, B2, num_curves] + list(_ecm_parameters(B1, B2, D, primes = primes))) methods = {_factor_fermat: "fmt", factor_pm1: "pm1", factor_ecm: "ecm"} #, factor_qs: "qs"} diff --git a/kryptools/factor_ecm.py b/kryptools/factor_ecm.py index 024674e..a02ec04 100644 --- a/kryptools/factor_ecm.py +++ b/kryptools/factor_ecm.py @@ -93,7 +93,7 @@ def factor_ecm(n: int, B1: int|None = None, B2: int|None = None, curves: int = 1 B1, B2, curves, D, stage_one, stage_two_deltas = ecm_parameters else: if not B1: - B1 = max(2, isqrt(n//200)) + B1 = min(1000_000, isqrt(n)//200 + 2) if not B2: B2 = 100 * B1 D, stage_one, stage_two_deltas = _ecm_parameters(B1, B2) @@ -159,7 +159,7 @@ def factor_ecm(n: int, B1: int|None = None, B2: int|None = None, curves: int = 1 break if g == 0: break - g =gcd(g,n) + g = gcd(g,n) if 1 < g: if verbose > 1: print("\nFactor found.") @@ -171,6 +171,7 @@ def factor_ecm(n: int, B1: int|None = None, B2: int|None = None, curves: int = 1 if verbose > 1: print("\nFactor found.") return g + if verbose > 1: print(f"\nNo factor after trying {curves} curves.") diff --git a/kryptools/factor_pm1.py b/kryptools/factor_pm1.py index 8805964..456e982 100644 --- a/kryptools/factor_pm1.py +++ b/kryptools/factor_pm1.py @@ -2,7 +2,7 @@ Integer factorization: Pollard's p-1 method """ -from math import gcd, log, floor, log10 +from math import gcd, log, isqrt, floor, log10 from .primes import sieve_eratosthenes def _pm1_parameters(B1: int, B2: int|None = None, primes: tuple = None): @@ -27,24 +27,30 @@ def _pm1_parameters(B1: int, B2: int|None = None, primes: tuple = None): return stage_one, stage_two_deltas -def factor_pm1(n: int, B1: int = 10000, B2: int|None = None, x: int = 2, pm1_parameters: tuple = None, verbose: int = 0): - "Factors a number n using Pollard's p-1 method." - if verbose: - print(f"Factoring (Pollard p-1, B1={B1}, B2={B2}): {n} ({floor(log10(n)) + 1} digits)") - +def factor_pm1(n: int, B1: int|None = None, B2: int|None = None, x: int = 2, pm1_parameters: tuple = None, verbose: int = 0): + "Factors a number n using Pollard's p-1 method." if pm1_parameters: - stage_one, stage_two_deltas = pm1_parameters + B1, B2, stage_one, stage_two_deltas = pm1_parameters else: + if not B1: + B1 = min(1000_000, isqrt(n)//50 + 2) stage_one, stage_two_deltas = _pm1_parameters(B1, B2) + if verbose: + print(f"Factoring (Pollard p-1, B1={B1}, B2={B2}): {n} ({floor(log10(n)) + 1} digits)") + # stage one if verbose > 1: print("Working 1", end= "") x = pow(x, stage_one, n) g = gcd(x - 1, n) if g == n: + if verbose > 1: + print("") return None if 1 < g: + if verbose > 1: + print("\nFactor found.") return g if verbose > 1: