FLINT3.7.0-dev
Module · 156 functions

ulong_extras.h

#include <flint/ulong_extras.h>

This module works with ulong, an unsigned integer of FLINT_BITS bits (64 on all common platforms). It provides division and modular arithmetic with precomputed inverses, primality testing, factoring, integer roots and elementary number-theoretic functions. Most higher-level modules (nmod, fmpz, the polynomial and matrix modules) rely on it.

For background, Choosing a method for modular arithmetic compares the ways of computing modulo a word-size integer, and Primality testing for word-size integers and Factoring word-size integers describe the algorithms behind n_is_prime and n_factor.

Conventions#

Throughout, B=2FLINT_BITSB = 2^{\mathtt{FLINT\_BITS}}.

  • Functions ending in _preinv take a precomputed inverse of type ulong computed by n_preinvert_limb. Functions ending in _precomp take a double inverse computed by n_precompute_inverse.
  • A 2 in the name (n_mod2_preinv, n_mulmod2_preinv) marks the variant with no size restrictions on its inputs. Variants without it are faster but may require reduced operands, a normalised modulus or a modulus below 2532^{53}.
  • n_ll_ and n_lll_ functions take operands of two or three limbs.
  • Precomputed inverses are assumed to match the modulus, and operands of modular functions are assumed to be reduced. None of this is checked.
OverviewChoosing a method for modular arithmeticFLINT has a dozen ways to compute modulo a word-size nn, for single values, vectors, SIMD lanes and matrices. This page compares their requirements and costs and says which to use.

Basic arithmetic#

Returns the high word ⌊ab/B⌋\lfloor ab / B \rfloor of the double-word product abab.

Sets *a to b+cb + c, b−cb - c or bcbc modulo BB and returns 1 if the exact result does not fit in a ulong, otherwise 0.

Returns nexpn^{\mathit{exp}}, with 00=10^0 = 1. Overflow is not detected.

Returns ⌊log⁡bn⌋\lfloor \log_b n \rfloor and ⌈log⁡bn⌉\lceil \log_b n \rceil respectively. Requires n≥1n \ge 1 and b≥2b \ge 2.

Returns ⌈log⁡b2n⌉\lceil \log_b 2^n \rceil. Requires b≥2b \ge 2.

Returns nn with its lowest bb bits in reverse order; for example the 6-bit number 0101102010110_2 becomes 0110102011010_2.

int n_sizeinbase(ulong n, int base)

Returns the number of digits of nn in the given base (2≤base≤362 \le \mathit{base} \le 36); n_sizeinbase returns 1 for n=0n = 0. n_nonzero_sizeinbase10 is a branch-free version for base 10 and requires n≠0n \ne 0.

Integer roots and perfect powers#

Returns ⌊a⌋\lfloor \sqrt a \rfloor. n_sqrtrem also sets *r to a−⌊a⌋2a - \lfloor \sqrt a \rfloor^2.

More

Returns 1 if xx is a perfect square, otherwise 0.

More
ulong n_rootrem(ulong * remainder, ulong n, ulong root)

Returns r=⌊n1/k⌋r = \lfloor n^{1/k} \rfloor for k=rootk = \mathit{root}, or 0 if nn or kk is 0. n_rootrem also sets the remainder n−rkn - r^k.

ulong n_cbrtrem(ulong * remainder, ulong n)

Returns ⌊n1/3⌋\lfloor n^{1/3} \rfloor; n_cbrtrem also sets the remainder.

More
double n_cbrt_estimate(double a)

Alternative cube root algorithms used by n_cbrt: a bit-manipulation estimate in the spirit of the fast inverse square root, a binary search, and a Chebyshev approximation (requires n≠0n \ne 0).

More

n_is_perfect_power235 returns whether nn is a square, cube or fifth power. n_factor_power235 returns the root rr and sets *exp to k∈{2,3,5}k \in \{2, 3, 5\} if n=rkn = r^k, and otherwise returns 0.

More

If n=rkn = r^k with k≥2k \ge 2, returns kk and sets *root to rr; otherwise returns 0. Both 0 and 1 count as squares. The kk found is not necessarily the largest possible.

Division and remainder#

These functions compute a mod na \bmod n (and possibly the quotient) from a precomputed approximation of 1/n1/n, which is much faster than a hardware division when the same nn is used repeatedly. The approximation is either a ulong (_preinv functions), a double (_precomp functions) or the data for Barrett or Lemire reduction. For a comparison of the methods see Choosing a method for modular arithmetic.

With a ulong inverse#

Returns the precomputed inverse of n≠0n \ne 0 used by all _preinv functions [GraMol2010]. n_preinvert_limb_prenorm is a faster version for normalised nn (top bit set).

Full documentation

Returns a mod na \bmod n. No restrictions on aa; n≠0n \ne 0.

Full documentation
ulong n_divrem_preinv(ulong * q, ulong a, ulong n, ulong ninv, unsigned int norm)
ulong n_divrem_preinv_unnorm(ulong * q, ulong a, ulong n, ulong ninv, unsigned int norm)

Returns a mod na \bmod n and sets *q to ⌊a/n⌋\lfloor a/n \rfloor. The last two variants take the number of leading zero bits of nn as norm; n_divrem_preinv_unnorm requires norm>0\mathit{norm} > 0.

Full documentation

Returns the quotient ⌊a/n⌋\lfloor a/n \rfloor. No restrictions on aa; n≠0n \ne 0.

Full documentation

Returns a mod na \bmod n for the two-limb integer a=ahiB+aloa = a_{hi} B + a_{lo}. No restrictions on aa; n≠0n \ne 0.

Full documentation
ulong n_lll_mod_preinv(ulong a_hi, ulong a_mi, ulong a_lo, ulong n, ulong ninv)

Returns a mod na \bmod n for the three-limb integer a=ahiB2+amiB+aloa = a_{hi} B^2 + a_{mi} B + a_{lo}. Requires ahi<na_{hi} < n.

Full documentation

Returns a mod na \bmod n and sets *q to the quotient (0 or 1), assuming nn is normalised. No inverse is needed: the quotient is a single comparison.

With a double inverse#

Returns 1/n1/n as a double, the precomputed inverse used by all _precomp functions. Requires n>0n > 0.

ulong n_mod_precomp(ulong a, ulong n, double ninv)

Returns a mod na \bmod n. Requires n<253n < 2^{53}, a<n2a < n^2 and a<2FLINT_BITS−1a < 2^{\mathtt{FLINT\_BITS} - 1}.

More
ulong n_mod2_precomp(ulong a, ulong n, double ninv)

Returns a mod na \bmod n with no restrictions on aa or nn.

More
ulong n_divrem2_precomp(ulong * q, ulong a, ulong n, double npre)

Returns a mod na \bmod n and sets *q to the quotient. No restrictions on aa or nn.

Barrett and Lemire reduction#

Returns the precomputed inverse for n_mod_barrett. Requires n≥2n \ge 2.

Returns x mod nx \bmod n using Barrett reduction [Bar1987]. The lazy version returns a residue in [0,2n)[0, 2n) instead of [0,n)[0, n). No restrictions on xx. Both support n=1n = 1 if npre is set to UWORD_MAX.

Returns the precomputed inverse for n_mod_lemire. Requires n≥1n \ge 1.

Returns x mod nx \bmod n using the method of Lemire, Kaser and Kurz [LKK2019]. Only correct for n,x<2FLINT_BITS/2n, x < 2^{\mathtt{FLINT\_BITS} / 2}.

Divisibility#

int n_divides(ulong * q, ulong n, ulong p)

Returns 1 and sets *q to n/pn/p if pp divides nn; otherwise returns 0 and sets *q to 0.

int n_divisible_odd_gm(ulong n, ulong inv1, ulong inv2)

Returns whether the odd number dd divides nn, given inv1=d−1 mod B\mathit{inv1} = d^{-1} \bmod B and inv2=⌊(B−1)/d⌋\mathit{inv2} = \lfloor (B - 1)/d \rfloor. Costs one multiplication. See Divisibility testing by multiplication.

int n_remove(ulong * n, ulong p)
int n_remove2_precomp(ulong * n, ulong p, double ppre)

Divides *n by the largest possible power of p>1p > 1 and returns the exponent. Requires n≠0n \ne 0. n_remove2_precomp takes ppre = n_precompute_inverse(p).

More

Greatest common divisor#

Returns gcd⁡(x,y)\gcd(x, y), with gcd⁡(x,0)=gcd⁡(0,x)=x\gcd(x, 0) = \gcd(0, x) = x.

More
ulong n_xgcd(ulong * a, ulong * b, ulong x, ulong y)

Returns g=gcd⁡(x,y)g = \gcd(x, y) and sets *a, *b to unsigned values with ax−by=gax - by = g. Requires x≥yx \ge y.

More

Modular addition and inversion#

Returns (a+b) mod n(a + b) \bmod n, (a−b) mod n(a - b) \bmod n and −a mod n-a \bmod n for reduced operands.

Returns x−1 mod yx^{-1} \bmod y. Throws an exception if the inverse does not exist.

Returns g=gcd⁡(x,y)g = \gcd(x, y) and sets *a to the 0≤a<y0 \le a < y with ax≡g(mody)ax \equiv g \pmod y. Requires x<yx < y. When y=1y = 1, returns 1 and sets *a to 0.

Returns the inverse of odd nn modulo BB; the result is meaningless for even nn.

More

Modular multiplication#

Returns ab mod nab \bmod n. No restrictions on aa, bb or nn.

Full documentation

Returns ab mod nab \bmod n, computing the inverse of nn on the fly. Use n_mulmod2_preinv when nn is reused.

Full documentation

Returns ⌊a/2norm⌋ b mod n\lfloor a / 2^{\mathit{norm}} \rfloor \, b \bmod n for normalised nn and reduced a,ba, b. If aa, bb and nn are the operands and modulus shifted left by norm bits, this is their product modulo the unshifted modulus, shifted left by norm bits.

Full documentation
ulong n_mulmod_precomp(ulong a, ulong b, ulong n, double ninv)

Returns ab mod nab \bmod n. Requires n<253n < 2^{53} and a,b<na, b < n.

More

Multiplication by a fixed operand#

These functions speed up computing abi mod na b_i \bmod n for fixed aa and nn and many bib_i, as in scalar multiplication of vectors and matrices [Sho2021; Har2014]. They require n<2FLINT_BITS−1n < 2^{\mathtt{FLINT\_BITS} - 1}.

Returns ⌊aB/n⌋\lfloor a B / n \rfloor, the precomputed data for n_mulmod_shoup. Requires a<na < n.

Full documentation

Returns ab mod nab \bmod n given a_precomp from n_mulmod_precomp_shoup. Requires a<na < n; bb is arbitrary.

Full documentation
void n_mulmod_precomp_shoup_quo_rem(ulong * a_pr_quo, ulong * a_pr_rem, ulong a, ulong n)

Compute both the quotient ⌊aB/n⌋\lfloor aB/n \rfloor and the remainder aB mod naB \bmod n, as needed by n_mulmod_and_precomp_shoup. The second function recovers the remainder from a known quotient.

Full documentation
void n_mulmod_and_precomp_shoup(ulong * ab, ulong * ab_precomp, ulong a, ulong b, ulong a_pr_quo, ulong a_pr_rem, ulong b_precomp, ulong n)

Sets *ab to ab mod nab \bmod n and *ab_precomp to its precomputed data ⌊(ab mod n)B/n⌋\lfloor (ab \bmod n) B / n \rfloor, without a division. Requires a,b<na, b < n. Useful for building tables of powers a,a2,a3,…a, a^2, a^3, \ldots together with their precomputed data.

Full documentation

Modular exponentiation#

Returns aexp mod na^{\mathit{exp}} \bmod n for a<na < n. Negative exponents are allowed; an exception is thrown if aa is then not invertible.

Full documentation

Returns aexp mod na^{\mathit{exp}} \bmod n for an unsigned exponent and a<na < n. n_powmod_ui_preinv requires normalised nn, like n_mulmod_preinv.

Full documentation

Returns aexp mod na^{\mathit{exp}} \bmod n for a nonnegative multiprecision exponent and a<na < n.

Full documentation
ulong n_powmod_precomp(ulong a, slong exp, ulong n, double npre)
ulong n_powmod_ui_precomp(ulong a, ulong exp, ulong n, double npre)

Returns aexp mod na^{\mathit{exp}} \bmod n using a double inverse. Require n<253n < 2^{53} and a<na < n.

Chinese remaindering#

ulong n_CRT(ulong r1, ulong m1, ulong r2, ulong m2)

Returns the unique 0≤x<m1m20 \le x < m_1 m_2 with x≡r1(modm1)x \equiv r_1 \pmod{m_1} and x≡r2(modm2)x \equiv r_2 \pmod{m_2}. Requires coprime m1,m2>1m_1, m_2 > 1 with m1m2m_1 m_2 fitting in a ulong, and reduced r1,r2r_1, r_2. Nothing is checked.

Jacobi symbols#

int n_jacobi(slong x, ulong y)

Returns the Jacobi symbol (xy)\left(\frac{x}{y}\right) for odd yy (not checked), with a binary algorithm [ShaSor1993]. n_jacobi_unsigned accepts a full-limb xx.

Primes#

Finding, counting and enumerating primes. To run through consecutive primes, use a prime iterator (n_primes_t); the first primes and their inverses are also available from a per-thread cache.

ulong n_nextprime(ulong n, int proved)

Returns the smallest prime greater than nn. Throws an exception if it does not fit in a ulong. The flag proved has no effect: the result is always a proved prime.

void n_prime_pi_bounds(ulong * lo, ulong * hi, ulong n)

Return the number π(n)\pi(n) of primes p≤np \le n, or set lo≤π(n)≤hi\mathit{lo} \le \pi(n) \le \mathit{hi}.

More
void n_nth_prime_bounds(ulong * lo, ulong * hi, ulong n)

Return the nn-th prime pnp_n (with p1=2p_1 = 2; n=0n = 0 throws an exception), or set lo≤pn≤hi\mathit{lo} \le p_n \le \mathit{hi}.

More
void n_primes_init(n_primes_t iter)
void n_primes_clear(n_primes_t iter)

Initialise and clear a prime iterator.

ulong n_primes_next(n_primes_t iter)

Returns the next prime and advances the iterator. The first call returns 2.

More
void n_primes_jump_after(n_primes_t iter, ulong n)

Makes the iterator continue with the first prime greater than nn.

void n_compute_primes(ulong num_primes)
const ulong * n_primes_arr_readonly(ulong num_primes)
void n_cleanup_primes(void)

Maintain a per-thread cache of the first primes and their double inverses. The _readonly functions return pointers into the cache, which stay valid until n_cleanup_primes is called in the same thread.

void n_primes_extend_small(n_primes_t iter, ulong bound)
void n_primes_sieve_range(n_primes_t iter, ulong a, ulong b)

Internal helpers of the prime iterator: extend its table of small primes until the second-largest entry is at least bound, or sieve the odd numbers in [a,b][a, b] and point the iterator at the start of that block.

Primality testing#

n_is_prime, and n_ll_is_prime for two-limb integers, are the functions to use. The others are individual probable prime tests and two alternative primality proofs, of interest mainly for testing and experiments.

OverviewPrimality testing for word-size integersHow n_is_prime proves primality of any 64-bit integer with at most two strong probable prime tests, using table lookups, vectorised trial division and a hashed table of witnesses.

Returns 1 if nn is prime and 0 otherwise. Deterministic for all nn.

Full documentation

Like n_is_prime for odd nn, but skips trial division. Faster when nn is already known to have no small factors.

Full documentation
int n_ll_is_prime(ulong nhi, ulong nlo)

Primality test for the two-limb integer n=nhiB+nlon = n_{hi} B + n_{lo} with nhi≠0n_{hi} \ne 0. Returns 1 (prime), 0 (composite) or −1-1 (unknown). The answer is always definite below about 2812^{81} on 64-bit machines.

More

Test whether odd nn is a strong probable prime to base aa [Mil1976; Rab1980], given the odd part dd of n−1n - 1 and 0<a<n0 < a < n. The _precomp version requires n<253n < 2^{53}. See Strong probable prime test.

Returns whether in−1≡1(modn)i^{n-1} \equiv 1 \pmod n. Requires 1<i<n1 < i < n and i∤ni \nmid n.

Fibonacci probable prime test: checks Fn−(n/5)≡0(modn)F_{n - (n/5)} \equiv 0 \pmod n, where (n/5)(n/5) is a Jacobi symbol [CraPom2005]. Requires gcd⁡(n,10)=1\gcd(n, 10) = 1.

Lucas probable prime test, similar to the one of Baillie and Wagstaff [BaiWag1980].

Baillie–PSW probable prime test [PSW1980; BaiWag1980]. No composite passing it is known, and it has been checked against tables of pseudoprimes up to 2642^{64}, so it is a primality test for word-size nn.

More

Pocklington–Lehmer test [Poc1914; BLS1975]. Returns 1 if nn is proved prime, 0 if it is composite, and −1-1 if nothing was proved because the bases 2,…,iterations−12, \ldots, \mathit{iterations} - 1 were not enough. If iterations\mathit{iterations} is 0 or 1, the number of bases is not limited and −1-1 is never returned for this reason.

More

Primality test based on pseudosquares, following Theorem 2.7 of [LukPatWil1996].

More

Obsolete; calls n_is_prime.

Factoring#

OverviewFactoring word-size integersHow n_factor combines trial division, primality testing, perfect power detection, Pollard–Brent rho, Hart's one-line method and SQUFOF to factor any 64-bit integer.

A factorisation p1e1⋯pkekp_1^{e_1} \cdots p_k^{e_k} into distinct primes, with fields num (the number kk of distinct primes), p[] (the primes) and exp[] (the exponents).

Full documentation
void n_factor_init(n_factor_t * factors)

Initialises factors to the empty factorisation.

Full documentation
void n_factor(n_factor_t * factors, ulong n, int proved)

Sets factors to the complete factorisation of nn (empty for n≤1n \le 1); factors need not be initialised. The flag proved has no effect, as all primality tests used are deterministic for word-size integers.

Full documentation

Returns p1e1⋯pkekp_1^{e_1} \cdots p_k^{e_k}, or 0 if it does not fit in a ulong.

void n_factor_insert(n_factor_t * factors, ulong p, ulong exp)

Multiplies the factorisation by pexpp^{\mathit{exp}}, adding to the exponent of pp if it is already present.

ulong n_factor_trial(n_factor_t * factors, ulong n, ulong num_primes)
ulong n_factor_trial_range(n_factor_t * factors, ulong n, ulong start, ulong num_primes)

Trial division by the first num_primes primes (starting at the prime with index start). Factors found are added to factors, which must be initialised; the unfactored cofactor is returned.

More
ulong n_factor_trial_partial(n_factor_t * factors, ulong n, ulong * prod, ulong num_primes, ulong limit)
ulong n_factor_partial(n_factor_t * factors, ulong n, ulong limit, int proved)

Partial factorisation: like n_factor_trial and n_factor, but stop as soon as the product of the prime factors found exceeds limit. Return the cofactor; n_factor_trial_partial also sets *prod to the product of the factors found.

Hart's one-line factoring algorithm [Har2012], a variant of Fermat's method. Returns a factor of nn or 0. Faster than SQUFOF below about 2402^{40}.

Lehman's algorithm [Leh1974]. Always returns a factor of nn, but works only up to 101610^{16} and is not used by n_factor.

Shanks' square form factorisation as described by Gower and Wagstaff [GowWag2008]. Returns a factor of nn that fits in one limb, or 0 if none was found within iters iterations. The ll version takes a two-limb n=nhiB+nlon = n_{hi} B + n_{lo}.

More

Williams' p+1p + 1 method [Wil1982] with prime bound B1B_1 and a random starting value 2<c<n2 < c < n. Returns a factor, or 0 or 1 on failure. The wrapper chooses parameters tuned for 31 to 64-bit nn.

More
int n_factor_pollard_brent_single(ulong * factor, ulong n, ulong ai, ulong xi, ulong max_iters)
int n_factor_pollard_brent(ulong * factor, flint_rand_t state, ulong n_in, ulong max_tries, ulong max_iters)

Pollard's rho method [Pol1975] with Brent's cycle detection [Bre1980], for composite nn. Return 1 and set *factor to a nontrivial (not necessarily prime) factor on success, otherwise 0. The first function uses the polynomial x2+aix^2 + a_i and starting value xix_i; the second tries up to max_tries random choices.

int n_ll_factor_rho(nn_ptr factor, ulong nhi, ulong nlo, ulong max_tries, ulong max_iters)

Pollard–Brent rho for an odd two-limb nn with nhi≠0n_{hi} \ne 0. Returns 1 and writes a nontrivial two-limb factor on success, otherwise 0.

More
int n_ll_factor_ecm(nn_ptr factor, ulong nhi, ulong nlo, ulong curves, ulong B1, ulong B2, flint_rand_t state)

The elliptic curve method for an odd two-limb nn with nhi≠0n_{hi} \ne 0, trying up to curves curves with bounds B1B_1, B2B_2 (if B2<B1B_2 < B_1, then 100B1100 B_1 is used). Returns 1 and writes a factor on success, otherwise 0.

More
int n_factor_ecm(ulong * f, ulong curves, ulong B1, ulong B2, flint_rand_t state, ulong n)

The elliptic curve method [Len1987; ZD2006] for a single-limb nn, trying up to curves random curves with stage bounds B1B_1 and B2B_2. Returns 1 or 2 if a factor was found in stage I or II, −1-1 if one was found while selecting a curve, and 0 on failure. The factor is stored in *f.

Arithmetic functions#

void n_moebius_mu_vec(int * mu, ulong len)

Compute the Möbius function μ(n)\mu(n), with μ(0)=0\mu(0) = 0, or the values μ(0),…,μ(len−1)\mu(0), \ldots, \mu(\mathit{len} - 1).

More

Returns whether nn is squarefree, that is, μ(n)≠0\mu(n) \ne 0. By convention 1 is squarefree and 0 is not.

Returns Euler's totient φ(n)\varphi(n), the number of 1≤k≤n1 \le k \le n coprime to nn.

Factorials#

Return n! mod pn! \bmod p for any modulus pp (no optimisations for composite pp). The fast version uses fast multipoint evaluation in about O(n1/2)O(n^{1/2}) operations up to logarithmic factors [Pol1974; BGS2007]; the other chooses between table lookup, a direct product and the fast algorithm depending on nn.

Square roots modulo n#

Returns the square root of aa modulo the prime pp that lies in [0,p/2][0, p/2], or 0 if aa is not a square. Requires a<pa < p.

More

Compute all square roots of aa modulo 2exp2^{\mathit{exp}}, modulo pexpp^{\mathit{exp}}, or modulo an integer mm given by its factorisation, and return their number. The roots are written to a newly allocated array stored in *sqrt, which the caller frees with flint_free. If aa is not a square, 0 is returned and *sqrt is set to NULL.

Primitive roots and discrete logarithms#

For odd non-square nn, returns some aa with Jacobi symbol (an)=−1\left(\frac{a}{n}\right) = -1; for prime nn this is a quadratic nonresidue.

Return a primitive root modulo the prime pp. The prefactor version takes the prime factors qq of p−1p - 1 (exponents are ignored) and returns an aa with a(p−1)/q≠1a^{(p-1)/q} \ne 1 for every qq given.

Returns xx with ax≡b(modn)a^x \equiv b \pmod n by baby-step giant-step [Sha1971], assuming (Z/nZ)×(\mathbb{Z}/n\mathbb{Z})^\times is cyclic, that is, nn is 2, 4, pkp^k or 2pk2p^k for an odd prime pp.

Random numbers#

All functions draw from a flint_rand_t state. Those with randtest in the name make corner cases such as 0, 1 and values with few set bits more likely, and are meant for test code.

Returns a uniformly random limb. _n_randlimb is an inline version for tight loops.

More
ulong n_randbits(flint_rand_t state, unsigned int bits)

Returns a uniformly random integer with exactly bits bits (the top bit is set), or 0 if bits is 0.

Like n_randbits, but values with sparse binary representations are more likely.

Returns a uniformly random integer in [0,limit)[0, \mathit{limit}), or a random limb if limit is 0. The three functions are equivalent; _n_randint is inline.

Returns a random integer of random bit length between 0 and FLINT_BITS, with 0, 1, COEFF_MAX, WORD_MAX, UWORD_MAX and sparse values made more likely.

Like n_randtest, but never returns 0.

ulong n_randprime(flint_rand_t state, ulong bits, int proved)

Returns a random prime with exactly bits bits, where 2≤bits≤FLINT_BITS2 \le \mathit{bits} \le \mathtt{FLINT\_BITS}. The result is always a proved prime; the flag proved has no effect.

Returns a random prime whose bit length is chosen at random between 2 and FLINT_BITS.

Double-limb modular exponentiation#

Low-level helpers for the base-2 and small-base strong probable prime tests in n_ll_is_prime. The modulus mm has two limbs (m>Bm > B) but must be below roughly 23FLINT_BITS/22^{3 \mathtt{FLINT\_BITS} / 2}.

Computes the two-limb inverse ⌊23FLINT_BITS/m⌋\lfloor 2^{3 \mathtt{FLINT\_BITS}} / m \rfloor of a two-limb m>Bm > B, as needed by n_ll_small_2_powmod and n_ll_small_powmod_triple.

void n_ll_small_powmod_triple(nn_ptr res1, nn_ptr res2, nn_ptr res3, ulong b1, ulong b2, ulong b3, nn_srcptr exp, nn_srcptr m, nn_srcptr minv)

Compute be mod mb^e \bmod m for small single-limb bases bb and two-limb ee and m>Bm > B: the first function for b=2b = 2, the second for three bases b1≤b2≤b3b_1 \le b_2 \le b_3 at once. Helpers for n_ll_is_prime.

More

ECM internals#

Building blocks of n_factor_ecm. Points are in Montgomery projective coordinates (x:z)(x : z) on curves in Montgomery form [Mon1987], and arithmetic is modulo nn using the parameters stored in n_ecm_inf.

void n_factor_ecm_double(ulong * x, ulong * z, ulong x0, ulong z0, ulong n, n_ecm_t n_ecm_inf)

Sets (x:z)=2(x0:z0)(x : z) = 2 (x_0 : z_0), using x=(x0+z0)2(x0−z0)2x = (x_0 + z_0)^2 (x_0 - z_0)^2 and z=4x0z0((x0−z0)2+4a24x0z0)z = 4 x_0 z_0 \left((x_0 - z_0)^2 + 4 a_{24} x_0 z_0\right).

void n_factor_ecm_add(ulong * x, ulong * z, ulong x1, ulong z1, ulong x2, ulong z2, ulong x0, ulong z0, ulong n, n_ecm_t n_ecm_inf)

Sets (x:z)=(x1:z1)+(x2:z2)(x : z) = (x_1 : z_1) + (x_2 : z_2) given their difference (x0:z0)(x_0 : z_0).

void n_factor_ecm_mul_montgomery_ladder(ulong * x, ulong * z, ulong x0, ulong z0, ulong k, ulong n, n_ecm_t n_ecm_inf)

Sets (x:z)=k(x0:z0)(x : z) = k (x_0 : z_0) with the Montgomery ladder.

int n_factor_ecm_select_curve(ulong * f, ulong sigma, ulong n, n_ecm_t n_ecm_inf)

Selects a curve and starting point from sigma with Suyama's parametrisation, storing x0x_0, z0z_0 and (a+2)/4(a + 2)/4 in n_ecm_inf. Returns 1 if a factor of nn turned up along the way (stored in *f), otherwise 0.

int n_factor_ecm_stage_I(ulong * f, const ulong * prime_array, ulong num, ulong B1, ulong n, n_ecm_t n_ecm_inf)
int n_factor_ecm_stage_II(ulong * f, ulong B1, ulong B2, ulong P, ulong n, n_ecm_t n_ecm_inf)

Stage I with the num primes up to B1B_1 in prime_array, and stage II up to B2B_2 with primorial P≈B2P \approx \sqrt{B_2}. Return 1 and set *f if a factor is found, otherwise 0.

References#

  • [GraMol2010] N. Möller and T. Granlund, "Improved division by invariant integers", IEEE Transactions on Computers 60 (2011), 165–175, https://gmplib.org/~tege/division-paper.pdf
  • [Bar1987] P. Barrett, "Implementing the Rivest Shamir and Adleman public key encryption algorithm on a standard digital signal processor", Advances in Cryptology – CRYPTO '86, LNCS 263 (1987), 311–323
  • [LKK2019] D. Lemire, O. Kaser and N. Kurz, "Faster remainder by direct computation: applications to compilers and software libraries", Software: Practice and Experience 49 (2019), 953–970, https://arxiv.org/abs/1902.01961
  • [Sho2021] V. Shoup, "Arithmetic software libraries", chapter 9 of Computational Cryptography, Cambridge University Press (2021), https://doi.org/10.1017/9781108854207.012
  • [Har2014] D. Harvey, "Faster arithmetic for number-theoretic transforms", Journal of Symbolic Computation 60 (2014), 113–119, https://doi.org/10.1016/j.jsc.2013.09.002
  • [ShaSor1993] J. Shallit and J. Sorenson, "A binary algorithm for the Jacobi symbol", ACM SIGSAM Bulletin 27 (1993), 4–11
  • [Mil1976] G. L. Miller, "Riemann's hypothesis and tests for primality", Journal of Computer and System Sciences 13 (1976), 300–317
  • [Rab1980] M. O. Rabin, "Probabilistic algorithm for testing primality", Journal of Number Theory 12 (1980), 128–138
  • [CraPom2005] R. Crandall and C. Pomerance, Prime Numbers: A Computational Perspective, second edition, Springer (2005).
  • [BaiWag1980] Robert Baillie; Samuel S. Wagstaff, Jr. (October 1980). "Lucas Pseudoprimes". Mathematics of Computation. 35 (152): 1391–1417.
  • [PSW1980] C. Pomerance, J. L. Selfridge and S. S. Wagstaff, Jr., "The pseudoprimes to 25·10^9", Mathematics of Computation 35 (1980), 1003–1026
  • [Poc1914] H. C. Pocklington, "The determination of the prime or composite nature of large numbers by Fermat's theorem", Proceedings of the Cambridge Philosophical Society 18 (1914), 29–30
  • [BLS1975] J. Brillhart, D. H. Lehmer and J. L. Selfridge, "New primality criteria and factorizations of 2^m ± 1", Mathematics of Computation 29 (1975), 620–647
  • [LukPatWil1996] R. F. Lukes and C. D. Patterson and H. C. Williams "Some results on pseudosquares" Math. Comp. 1996, no. 65, 361–372
  • [Har2012] Hart, William B.. (2012) A one line factoring algorithm. Journal of the Australian Mathematical Society, Volume 92 (Number 1). pp. 61-69.
  • [Leh1974] R. S. Lehman, "Factoring large integers", Mathematics of Computation 28 (1974), 637–646
  • [GowWag2008] Jason Gower and Sam Wagstaff : "Square form factoring" Math. Comp. 77, 2008, pp 551-588, https://doi.org/10.1090/S0025-5718-07-02010-8
  • [Wil1982] H. C. Williams, "A p+1 method of factoring", Mathematics of Computation 39 (1982), 225–234
  • [Pol1975] J. M. Pollard, "A Monte Carlo method for factorization", BIT 15 (1975), 331–334
  • [Bre1980] R. P. Brent, "An improved Monte Carlo factorization algorithm", BIT 20 (1980), 176–184
  • [Len1987] H. W. Lenstra, Jr., "Factoring integers with elliptic curves", Annals of Mathematics 126 (1987), 649–673
  • [ZD2006] P. Zimmermann and B. Dodson, "20 years of ECM", Algorithmic Number Theory (ANTS VII), LNCS 4076 (2006), 525–542
  • [Pol1974] J. M. Pollard, "Theorems on factorization and primality testing", Proceedings of the Cambridge Philosophical Society 76 (1974), 521–528
  • [BGS2007] A. Bostan, P. Gaudry and É. Schost, "Linear recurrences with polynomial coefficients and application to integer factorization and Cartier–Manin operator", SIAM Journal on Computing 36 (2007), 1777–1806
  • [Sha1971] D. Shanks, "Class number, a theory of factorization, and genera", Proc. Symp. Pure Math. 20, American Mathematical Society (1971), 415–440
  • [Mon1987] P. L. Montgomery, "Speeding the Pollard and elliptic curve methods of factorization", Mathematics of Computation 48 (1987), 243-264, https://doi.org/10.1090/S0025-5718-1987-0866113-7
Cite this page

The FLINT team, “ulong_extras.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/ulong_extras/index.html (generated 2026-11-02).