Skip to main content

Find any nontrivial factor of a number

Project description

FindAFactor

Find any nontrivial factor of a number

Copyright and license

(c) Daniel Strano and the Qrack contributors 2017-2024. All rights reserved.

Installation

From PyPi:

pip3 install FindAFactor

From Source: install pybind11, then

pip3 install .

in the root source directory (with setup.py).

Windows users might find Windows Subsystem Linux (WSL) to be the easier and preferred choice for installation.

Usage

from FindAFactor import find_a_factor

to_factor = 1000

factor = find_a_factor(
    to_factor,
    use_congruence_of_squares=False,
    node_count=1, node_id=0,
    gear_factorization_level=11,
    wheel_factorization_level=5,
    thread_count=0,
    batch_multiplier=3.0,
    smoothness_bound_multiplier=1.0
)

The find_a_factor() function should return any nontrivial factor of to_factor (that is, any factor besides 1 or to_factor) if it exists. If a nontrivial factor does not exist (i.e., the number to factor is prime), the function will return 1 or the original to_factor.

  • use_congruence_of_squares (default value: False): This attempts to check congruence of squares with Gaussian elimination for Quadratic Sieve.
  • node_count (default value: 1): FindAFactor can perform factorization in a distributed manner, across nodes, without network communication! When node_count is set higher than 1, the search space for factors is segmented equally per node. If the number to factor is semiprime, and brute-force search is used instead of congruence of squares, for example, all nodes except the one that happens to contain the (unknown) prime factor less than the square root of to_factor will ultimately return 1, while one node will find and return this factor. For best performance, every node involved in factorization should have roughly the same CPU throughput capacity.
  • node_id (default value: 0): This is the identifier of this node, when performing distributed factorization with node_count higher than 1. node_id values start at 0 and go as high as (node_count - 1).
  • gear_factorization_level (default value: 11): This is the value up to which "wheel (and gear) factorization" and trial division are used to check factors and optimize "brute force," in general. The default value of 11 includes all prime factors of 11 and below and works well in general, though significantly higher might be preferred in certain cases.
  • wheel_factorization_level (default value: 5): "Wheel" vs. "gear" factorization balances two types of factorization wheel ("wheel" vs. "gear" design) that often work best when the "wheel" is only a few prime number levels lower than gear factorization. Optimized implementation for wheels is only available up to 13. The primes above "wheel" level, up to "gear" level, are the primes used specifically for "gear" factorization.
  • thread_count (default value: 0 for auto): Control the number of threads used for separate Gaussian elimination or parallel brute-force instances. For value of 0, the total number of hyper threads on the system will be detedted and used. When use_congruence_of_squares=True, this acts as a multiplier on overall memory usage. If you exceed system memory, turn it down to some manual value. (Gaussian elimination is not easily parallelizable, except to run as many separate instances as will fit in memory.)
  • batch_multiplier (default value: 3.0): controls how many items are processed in a batch before Gaussian elimination. batch_multiplier times the number of "smooth" primes is the batch size for "semi-smooth" numbers, to be collected before sieving and then Gaussian elimination. Besides thread count, this batch_multiplier can help tune overall memory usage and multiprocessor utilization.
  • smoothness_bound_multiplier (default value: 1.0): starting with the first prime number after wheel factorization, the congruence of squares approach (with Quadratic Sieve) takes a default "smoothness bound" with as many distinct prime numbers as bits in the number to factor (for default argument of 1.0 multiplier). To increase or decrease this number, consider it multiplied by the value of smoothness_bound_multiplier.

All variables defaults can also be controlled by environment variables:

  • FINDAFACTOR_USE_CONGRUENCE_OF_SQUARES (any value makes True, while default is False)
  • FINDAFACTOR_NODE_COUNT
  • FINDAFACTOR_NODE_ID
  • FINDAFACTOR_GEAR_FACTORIZATION_LEVEL
  • FINDAFACTOR_WHEEL_FACTORIZATION_LEVEL
  • FINDAFACTOR_SMOOTHNESS_BOUND_MULTIPLIER

Factoring parameter strategy

The developer anticipates this single-function set of parameters, as API, is the absolutely most complicated FindAFactor likely ever needs to get. The only required argument is to_factor, and it just works, for any number that should reasonably take about less than a second to a few minutes. However, if you're running larger numbers for longer than that, of course, it's worth investing 15 to 30 minutes to read the explanation above in the README of every argument and play with the settings, a little. But, with these options, you have total control to tune the algorithm in any all ways necessary to adapt to system resource footprint.

Advantage for use_congruence_of_squares is beyond the hardware scale of the developer's experiments, in practicality, but it can be shown to work correctly (at disadvantage, at small factoring bit-width scales). The anticipated use case is to turn this option on when approaching the size of modern-day RSA semiprimes in use.

If this is your use case, you want to specifically consider smoothness_bound_multiplier, batch_multiplier, and thread_count. By default, as many primes are kept for "smooth" number sieving as bits in the number to factor. This is multiplied by smooth_bound_multiplier (and cast to a discrete number of primes in total). batch_multiplier is how many times this count of primes, after smooth_bound_multiplier, is multiplied for "smooth number part" batching. Turning this down uses less memory and gets to Gaussian elimination faster but might or might not decrease CPU utilization. However, the higher batch_multiplier is set, as to maximize CPU utilization, the higher the memory used is.

Hence, you only want to set a manual thread_count below default to recover full CPU utilization within available system memory footprint. Ideally, you don't want to have to change thread_count from 0/default, indicating to automatically use all hyper threads, but keeping full utilization depends on both available system memory footprint and the scale of the number to factor, inherently.

wheel_factorization_level and gear_factorization_level are common to both use_congruence_of_squares (i.e., Gaussian elimination for perfect squares) and "brute force." 11 for gear and 5 for wheel limit works well for small numbers. You'll definitely want to consider (gear/wheel) 13/7 or 17/11 (or even other values, maybe system-dependent) as your numbers to factor approach cryptographic relevance.

As for node_count and node_id, believe it or not, factoring parallelism can truly be that simple: just run different node IDs in the set on different (roughly homogenous) isolated CPUs, without networking. The only caveat is that you must manually detect when any single node has found an answer (which is trivial to verify) and manually interrupt other nodes still working (or leave them to complete on their own).

About

This library was originally called "Qimcifa" and demonstrated a (Shor's-like) "quantum-inspired" algorithm for integer factoring. It has since been developed into a general factoring algorithm and tool.

FindAFactor uses heavily wheel-factorized brute-force "exhaust" numbers as "smooth" inputs to Quadratic Sieve, widely regarded as the asymptotically second fastest algorithm class known for cryptographically relevant semiprime factoring. Actually, the primary difference between Quadratic Sieve (QS, regarded second-fastest) and General Number Field Sieve (GNFS, fastest) is based in how "smooth" numbers are generated as intermediate inputs to Gaussian elimination, and the "brute-force exhaust" of Qimcifa provides smooth numbers rather than canonical polynomial generators for QS or GNFS, so whether FindAFactor is theoretically fastest depends on how good its smooth number generation is (which is an open question). FindAFactor is C++ based, with pybind11, which tends to make it faster than pure Python approaches. For the quick-and-dirty application of finding any single nontrivial factor, something like at least 80% of positive integers will factorize in a fraction of a second, but the most interesting cases to consider are semiprime numbers, for which FindAFactor should be about as asymptotically competitive as similar Quadratic Sieve implementations.

Our original contribution to Quadratic Sieve seems to be wheel factorization to 13 or 17 and maybe the idea of using the "exhaust" of a brute-force search for smooth number inputs for Quadratic Sieve. For wheel factorization (or "gear factorization"), we collect a short list of the first primes and remove all of their multiples from a "brute-force" guessing range by mapping a dense contiguous integer set, to a set without these multiples, relying on both a traditional "wheel," up to a middle prime number (of 11), and a "gear-box" that stores increment values per prime according to the principles of wheel factorization, but operating semi-independently, to reduce space of storing the full wheel.

Beyond this, we gain a functional advantage of a square-root over a more naive approach, by setting the brute force guessing range only between the highest prime in wheel factorization and the (modular) square root of the number to factor: if the number is semiprime, there is exactly one correct answer in this range, but including both factors in the range to search would cost us the square root advantage.

Factoring this way is surprisingly easy to distribute: basically 0 network communication is needed to coordinate an arbitrarily high amount of parallelism to factor a single number. Each brute-force trial division instance is effectively 100% independent of all others (i.e. entirely "embarrassingly parallel"), and these guesses can seed independent Gaussian elimination matrices, so FindAFactor offers an extremely simply interface that allows work to be split between an arbitrarily high number of nodes with absolutely no network communication at all. In terms of incentives of those running different, cooperating nodes in the context of this specific number of integer factoring, all one ultimately cares about is knowing the correct factorization answer by any means. For pratical applications, there is no point at all in factoring a number whose factors are already known. When a hypothetical answer is forwarded to the (0-communication) "network" of collaborating nodes, it is trivial to check whether the answer is correct (such as by simply entering the multiplication and equality check with the original number into a Python shell console)! Hence, collaborating node operators only need to trust that all participants in the "network" are actually performing their alloted segment of guesses and would actually communicate the correct answer to the entire group of collaborating nodes if any specific invidual happened to find the answer, but any purported answer is still trivial to verify.

Special thanks to OpenAI GPT "Elara," for indicated region of contributed code!

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

findafactor-1.11.2.tar.gz (38.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

FindAFactor-1.11.2-cp312-cp312-win_amd64.whl (152.4 kB view details)

Uploaded CPython 3.12Windows x86-64

FindAFactor-1.11.2-cp312-cp312-manylinux_2_39_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.39+ x86-64

FindAFactor-1.11.2-cp310-cp310-manylinux_2_35_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.35+ x86-64

FindAFactor-1.11.2-cp310-cp310-macosx_15_0_arm64.whl (308.3 kB view details)

Uploaded CPython 3.10macOS 15.0+ ARM64

FindAFactor-1.11.2-cp310-cp310-macosx_14_0_arm64.whl (311.0 kB view details)

Uploaded CPython 3.10macOS 14.0+ ARM64

FindAFactor-1.11.2-cp310-cp310-macosx_13_0_x86_64.whl (165.2 kB view details)

Uploaded CPython 3.10macOS 13.0+ x86-64

FindAFactor-1.11.2-cp38-cp38-manylinux_2_31_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.8manylinux: glibc 2.31+ x86-64

File details

Details for the file findafactor-1.11.2.tar.gz.

File metadata

  • Download URL: findafactor-1.11.2.tar.gz
  • Upload date:
  • Size: 38.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.3

File hashes

Hashes for findafactor-1.11.2.tar.gz
Algorithm Hash digest
SHA256 896101b10dc4d7b97ec27831f773ae4d3efc3c3d47f605274df7ce33a3b6f6ae
MD5 a6d6c4a06fe0a56687c9e417476d8674
BLAKE2b-256 9560405e4ccd533a4b01ea511be5e90dafff851bed6a18a63b3ff6f630bfc7dd

See more details on using hashes here.

File details

Details for the file FindAFactor-1.11.2-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for FindAFactor-1.11.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 ebbb6774f4d97edcd0dec140084d18aa630e736ce6dc953d54fb43f7b7e3030f
MD5 09e6d757b9ef64e03851e3067962515c
BLAKE2b-256 a1c0e76c0d89b417ef7636324fffbd10ad45d791cf0c63634f0a84731e18663d

See more details on using hashes here.

File details

Details for the file FindAFactor-1.11.2-cp312-cp312-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for FindAFactor-1.11.2-cp312-cp312-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 329e9fe0ed607a2cee9fd8c0db9bc1983d5d901b6d21c8cc72035bf33071e9a1
MD5 a34994cfe2b08ea74feb175863d9bfc8
BLAKE2b-256 50a7e5bb21e01a4ea5de378a9b046954d446d806136171276da2f6e85b851f61

See more details on using hashes here.

File details

Details for the file FindAFactor-1.11.2-cp310-cp310-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for FindAFactor-1.11.2-cp310-cp310-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 6748de31266ae0b9ead0e806ec37d211d0190b6db1eea48ee99ecdd3f26f9d25
MD5 48ca5287e80196a016264393ffeb5598
BLAKE2b-256 be1eac4057832a28433a0129c987c5597dc01f7c0026b419ed51e9412642d1ae

See more details on using hashes here.

File details

Details for the file FindAFactor-1.11.2-cp310-cp310-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for FindAFactor-1.11.2-cp310-cp310-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 b0dd65b7f7413996b184293375a6fd0eeb3bea59ebfdbaab93c0c59368e6ce37
MD5 e81d5d3ec4d6da2b4a56a67adac520c4
BLAKE2b-256 d13578219a1b763d0d91263ce15139604bd7e6234cfe11d2f9d61d2ff5d9cb53

See more details on using hashes here.

File details

Details for the file FindAFactor-1.11.2-cp310-cp310-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for FindAFactor-1.11.2-cp310-cp310-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 ef725c848f9ee54a2f38ea719a76312a55ee87abed2c71faa3df435388778770
MD5 95d235a82ccc8187ff724ba54088fb8f
BLAKE2b-256 4eaaac5957817cc332de5e8539ce4e882e0958e53ba72fdbc3738dc7e66f3ed2

See more details on using hashes here.

File details

Details for the file FindAFactor-1.11.2-cp310-cp310-macosx_13_0_x86_64.whl.

File metadata

File hashes

Hashes for FindAFactor-1.11.2-cp310-cp310-macosx_13_0_x86_64.whl
Algorithm Hash digest
SHA256 b35a954a19d184f3dcab0a37409fd52b2d0ba2b9832309a05f254876a5e01f76
MD5 6cea55cc1f89f610d2202c9c46845c4b
BLAKE2b-256 523649eac90e57323fa970803e4d8d3dd6c2a341c287376f544c58e2c6057321

See more details on using hashes here.

File details

Details for the file FindAFactor-1.11.2-cp38-cp38-manylinux_2_31_x86_64.whl.

File metadata

File hashes

Hashes for FindAFactor-1.11.2-cp38-cp38-manylinux_2_31_x86_64.whl
Algorithm Hash digest
SHA256 b219bfc946328028eab2c7a4f334f8977625f2ed75bd476c167193f01e05808b
MD5 9667e125c757f1e536a786e36ff3ec63
BLAKE2b-256 a60088a26811e42325c00bb782f713096d50dbd04070ebb37155d72b556cc42c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page