Proofs: General number field sieve
These are the human proofs of General number field sieve, at full length.
Correctness of the general number field sieve full
This proof shows: correctness, termination.
Let be an odd integer, and let be the monic polynomial and the integer of line L1, with . Write , and represent each element by its coefficients on . We prove three things. The output is always or a proper factor of . Every subset that reaches line L9 gives a congruence of squares. The algorithm stops. We do not prove that a proper factor is found; that part is a heuristic. At the end we prove that the driver factorize returns the prime factorization.
Lemma 1 (the homomorphism). There is a ring homomorphism with , and for every of degree below .
Proof. Evaluation at followed by reduction modulo is a ring homomorphism . It maps to , so it maps the ideal to , and it factors through . The value on the class of is .
The proof does not need to be irreducible: Lemma 1 holds for any monic with .
Lemma 2 (exact products). The functions mulmod with no modulus and product_in_order compute products in exactly.
Proof. mulmod forms the product of the two polynomials in , of degree at most . For down to it subtracts , which does not change the class modulo . Since is monic, this sets the coefficient of to and changes only lower coefficients. After the loop the degree is below , so the result is the representative of . product_in_order multiplies pairs level by level; multiplication in a commutative ring is associative and commutative, so the result is the product of all the elements.
Lemma 3 (the rational square). Let be a set of relations whose vectors of line L5 add to modulo , and let be the sum over of the exponents of in . Then with , and the value of line L7 satisfies .
Proof. Each relation has , which line L4 checks by trial division. The product over of the signs is , where is the number of negative ; bit of the vectors is the sign, so is even and the product is positive. Bits for the rational primes are the exponents modulo , so every is even. Hence . Line L7 computes times modulo .
Lemma 4 (the algebraic square). If line L8 returns , then in , where .
Proof. The implementation computes exactly by Lemma 2, and algebraic_sqrt returns a candidate only after the test mulmod(delta, delta, f) == gamma, an exact product by Lemma 2. Otherwise it returns None, and line L8 goes on to the next subset.
Lemma 5 (the congruence of squares). If a subset reaches line L9, then .
Proof. By Lemma 3, . By Lemma 1, and , since has degree . By Lemma 4 and Lemma 1, in . So .
Lemma 6 (the output). gnfs returns or an integer with and .
Proof. There are four return points with a value other than . The trial division returns a prime with only if , and returns otherwise. Line L1 returns only if it lies strictly between and . Line L9 returns only if it lies strictly between and . A gcd with divides . Every other exit returns .
When comes from line L9, Lemma 5 explains why it is a factor: , and is proper exactly when modulo some but not all prime power factors of .
Lemma 7 (inert primes and the square root modulo ). Let be an odd prime with such that is_inert(f, p) is true, where is an odd prime. Then is irreducible modulo , is a field with elements, and . For , satisfies if and only if is a square in .
Proof. The test says that has no root modulo and . The second condition means that divides in . That polynomial is the product of all monic irreducible polynomials over of degree dividing , each once. So every irreducible factor of has degree or , since is prime. There is no root, so no factor of degree , and is irreducible of degree . Hence is a field with elements. Since and is odd, , so is an integer.
is cyclic of order , so is a square if and only if . Now . The value is or , and its cube is the same value. So exactly when is a square.
Lemma 7 explains why line L8 finds the square root when it exists and the precision is high enough. Correctness does not depend on it, since Lemma 4 checks the result.
Lemma 8 (Newton's step). Let be an odd modulus, and let in satisfy . Then satisfies .
Proof. Write with . Then , where is invertible since is odd, and
Both and are modulo .
Lemma 9 (the vector of a relation is defined). For a relation and a prime that divides , , and the pair is in the algebraic factor base.
Proof. Modulo , , since . If and , then , so , against . So , and with , , so and is one of the pairs of line L2.
So relation_vector never takes the inverse of modulo and never looks up a missing pair.
Lemma 10 (termination). gnfs stops on every input.
Proof. Polynomial selection tries at most values of . The trial division and the search for an inert prime run over finite ranges (at most candidates for the inert prime). If an inert prime is found, then is irreducible modulo by Lemma 7, so it is irreducible over (a factorization over gives one over with monic factors, by Gauss's lemma, and it reduces to a factorization modulo ). Then the loop of line L2 for the characters stops. Its discriminant is not , since an irreducible polynomial over has distinct roots. By Schur's theorem, infinitely many primes divide some value with ; for such , is a simple root, so . So enough characters exist, and the search reaches them. The sieve runs over lines of points. Trial division of a nonzero integer by finitely many primes stops. The elimination is a loop over the rows, and each inner loop clears the top bit of or stops, so it runs at most as many times as has bits. The dependency loop is finite. In algebraic_sqrt, the modulus is squared at each step and the loop stops when it passes a fixed bound.
Theorem. gnfs stops and returns either or a proper factor of . When it returns a proper factor from line L9, it has found and with .
Proof. Lemmas 10, 6 and 5.
The driver. factorize(n) returns the prime factors of with multiplicity, in order, provided that is_probable_prime is correct on the numbers it sees. That holds for all numbers below , where the strong test to the prime bases up to is a proof of primality.
Proof. The trial division divides out the primes below in increasing order. If it stops because for the remaining , then has no prime factor below , so is or a prime. Otherwise has no prime factor below . The invariant of the stack is this: the product of the output and of the stack equals the input, every output entry is prime, and every stack entry has no prime factor below . It holds at the start. A popped that is is dropped. A popped with is prime, because a composite with no prime factor below is at least . A popped that passes is_probable_prime is prime by the assumption. Otherwise is composite, and _split(m) returns a proper factor : a perfect power with gives ; gnfs gives a proper factor by the Theorem; and the last resort finds the least odd with , which exists and is below because is odd and composite with no prime factor below . Then and both divide , so they have no prime factor below , and their product is . The invariant holds after each step. Each split replaces by two numbers greater than whose product is , so the total number of prime factors counted with multiplicity bounds the number of splits, and the loop stops. When the stack is empty, the output is a list of primes whose product is the input, and sorting puts it in order.