Documentation

Atlas.EllipticCurves.code.BerlekampRabin

def BerlekampRabin.DifferentType (F : Type u_1) [Field F] [Fintype F] (α β : F) :

Two nonzero elements α, β of a finite field F are of different type if their (q-1)/2-th powers differ, where q = |F|. By Euler's criterion this means exactly one of α, β is a quadratic residue.

Instances For
    @[implicit_reducible]
    noncomputable instance BerlekampRabin.differentTypeDecidable (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (α β : F) :

    Decidability of DifferentType (since equality in a finite field with decidable equality is decidable).

    noncomputable def BerlekampRabin.differentTypeSet (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (α β : F) :

    The set of shifts δ ∈ F such that α + δ and β + δ are of different type (in the sense of DifferentType). Used in Rabin's root-finding algorithm (Algorithm 3.45 / Theorem 3.44).

    Instances For
      noncomputable def BerlekampRabin.phi {F : Type u_1} [Field F] (α β δ : F) :
      F

      The map δ ↦ (α + δ)/(β + δ), used to put the different-type set in bijection with the set of γ whose (q-1)/2-th power is -1.

      Instances For
        noncomputable def BerlekampRabin.psi {F : Type u_1} [Field F] (α β γ : F) :
        F

        Inverse of phi: given γ, the unique δ with phi α β δ = γ (when α ≠ β and γ ≠ 1).

        Instances For
          theorem BerlekampRabin.phi_psi {F : Type u_1} [Field F] (α β γ : F) (hαβ : α β) ( : γ 1) :
          phi α β (psi α β γ) = γ

          phipsi = id on the locus where α ≠ β and γ ≠ 1.

          theorem BerlekampRabin.psi_phi {F : Type u_1} [Field F] (α β δ : F) (hαβ : α β) (hβδ : β + δ 0) :
          psi α β (phi α β δ) = δ

          psiphi = id on the locus where α ≠ β and β + δ ≠ 0.

          theorem BerlekampRabin.phi_ne_one {F : Type u_1} [Field F] (α β δ : F) (hαβ : α β) (hβδ : β + δ 0) :
          phi α β δ 1

          phi α β δ ≠ 1 whenever α ≠ β and β + δ ≠ 0, since equality would force α = β.

          theorem BerlekampRabin.psi_add_ne_zero {F : Type u_1} [Field F] (α β γ : F) (hαβ : α β) ( : γ 1) :
          β + psi α β γ 0

          β + psi α β γ ≠ 0 whenever α ≠ β and γ ≠ 1; this is the denominator nonvanishing needed to make phi and psi mutually inverse.

          theorem BerlekampRabin.card_pow_eq_const_le {F : Type u_1} [Field F] [Fintype F] [DecidableEq F] (s : ) (hs : 0 < s) (c : F) :
          {x : F | x ^ s = c}.card s

          For any c ∈ F and s ≥ 1, the number of solutions to x^s = c is at most s, since the polynomial X^s - c has at most s roots.

          theorem BerlekampRabin.card_pow_eq_neg_one {F : Type u_1} [Field F] [Fintype F] [DecidableEq F] (hF : ringChar F 2) :
          {x : F | x ^ (Fintype.card F / 2) = -1}.card = Fintype.card F / 2

          In a finite field F of odd characteristic, exactly (q-1)/2 elements satisfy x^((q-1)/2) = -1 (the quadratic nonresidues), where q = |F|.

          theorem BerlekampRabin.rabin_card_differentTypeSet {F : Type u_1} [Field F] [Fintype F] [DecidableEq F] (hF : ringChar F 2) (α β : F) (hαβ : α β) :

          Theorem 3.44 (Rabin 1980): for any pair of distinct elements α, β ∈ F_q with char F ≠ 2, the number of shifts δ such that α + δ and β + δ are of different type equals (q-1)/2. Proved by exhibiting a bijection with the set of γ such that γ^((q-1)/2) = -1.

          noncomputable def BerlekampRabin.berlekampRabinStep (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (g : Polynomial F) (δ : F) :

          Step 4b of Algorithm 3.45: compute gcd(g, (X + δ)^((q-1)/2) - 1), a candidate nontrivial factor of g.

          Instances For
            noncomputable def BerlekampRabin.berlekampRabinInit (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (f : Polynomial F) :

            Step 2 of Algorithm 3.45: compute gcd(f, X^q - X), the product of (X - α) over all roots α ∈ F_q of f.

            Instances For
              theorem BerlekampRabin.berlekampRabinStep_root_of_g (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (g : Polynomial F) (δ r : F) (hr : (berlekampRabinStep F g δ).IsRoot r) :
              g.IsRoot r

              Any root of berlekampRabinStep F g δ in F is also a root of g, because the step output divides g.

              theorem BerlekampRabin.berlekampRabinInit_root_of_f (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (f : Polynomial F) (r : F) (hr : (berlekampRabinInit F f).IsRoot r) :
              f.IsRoot r

              Any root of berlekampRabinInit F f in F is a root of f.

              Conversely, every root of f in F_q is a root of gcd(f, X^q - X), since X^q - X vanishes on all of F_q by Fermat's little theorem.

              theorem BerlekampRabin.berlekampRabinStep_shift_pow (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (g : Polynomial F) (δ r : F) (hr : (berlekampRabinStep F g δ).IsRoot r) :
              (r + δ) ^ (Fintype.card F / 2) = 1

              If r is a root of berlekampRabinStep F g δ, then (r + δ)^((q-1)/2) = 1, which means r + δ is a quadratic residue in F_q.

              noncomputable def BerlekampRabin.extractRoot (F : Type u_1) [Field F] (g : Polynomial F) :
              F

              Read off the unique root from a monic linear polynomial g = X - r: extractRoot g = -coeff 0 / leadingCoeff.

              Instances For
                noncomputable def BerlekampRabin.chooseFactor (F : Type u_1) [Field F] (g h : Polynomial F) :

                Step 4c of Algorithm 3.45: replace g by whichever of h or g/h has lower degree, provided h is a nontrivial proper factor.

                Instances For
                  noncomputable def BerlekampRabin.berlekampRabinIteration (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (g : Polynomial F) (δ : F) :

                  A single iteration of the inner loop in Algorithm 3.45: run berlekampRabinStep with shift δ, then chooseFactor.

                  Instances For
                    noncomputable def BerlekampRabin.berlekampRabinLoop (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] :
                    Polynomial FList FPolynomial F

                    The inner while-loop of Algorithm 3.45: iterate berlekampRabinIteration over a supplied list of random shifts δ, stopping early once deg g ≤ 1.

                    Instances For
                      noncomputable def BerlekampRabin.berlekampRabinAlgorithm (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (f : Polynomial F) (deltas : List F) :

                      Algorithm 3.45 (Rabin 1980): given a monic polynomial f ∈ F_q[X], return some root of f in F_q if one exists. Returns 0 if f(0) = 0; otherwise reduces to the squarefree part g = gcd(f, X^q - X) containing exactly the roots, and iteratively splits g using random shifts.

                      Instances For
                        theorem BerlekampRabin.extractRoot_isRoot (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (g : Polynomial F) (hg : g.natDegree = 1) (hm : g.Monic) :

                        For a monic linear polynomial g, extractRoot g is indeed a root of g.

                        theorem BerlekampRabin.chooseFactor_root_of_g (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (g h : Polynomial F) (r : F) (hd : h g) (hr : (chooseFactor F g h).IsRoot r) :
                        g.IsRoot r

                        If h ∣ g, then every root of chooseFactor F g h is also a root of g, regardless of which branch (h, g/h, or g) is taken.

                        noncomputable def BerlekampRabin.yunLoop (F : Type u_1) [Field F] [DecidableEq F] :

                        Inner loop of Yun's squarefree factorization (Algorithm 3.46): given v, w and a fuel bound, repeatedly compute g_i = gcd(v_i, w_i - v_i') and refresh v_{i+1} = v_i / g_i, w_{i+1} = (w_i - v_i') / g_i.

                        Instances For
                          noncomputable def BerlekampRabin.yunSquarefreeFactor (F : Type u_1) [Field F] [DecidableEq F] (f : Polynomial F) :

                          Algorithm 3.46 (Yun): squarefree factorization of f ∈ F_q[X] (in characteristic not dividing deg f). Returns a list [g_1, …, g_m] of squarefree pairwise coprime polynomials with f = g_1 · g_2^2 · ⋯ · g_m^m.

                          Instances For
                            noncomputable def BerlekampRabin.sqfreeProduct (F : Type u_1) [Field F] (factors : List (Polynomial F)) :

                            Reconstruct f from its squarefree factorization [g_1, …, g_m] as the product ∏_i g_i^i (with 1-based indexing).

                            Instances For
                              structure BerlekampRabin.IsSquarefreeFactorization (F : Type u_1) [Field F] (f : Polynomial F) (factors : List (Polynomial F)) :

                              The correctness predicate for a squarefree factorization (output of Algorithm 3.46): the list is nonempty, recovers f as ∏ g_i^i, each g_i is squarefree, the factors are pairwise coprime, and the last factor is not 1.

                              Instances For

                                If g^2 ∣ f, then g divides gcd(f, f'). This is the easy direction used in proving correctness of Yun's algorithm.

                                Characterization underlying Yun's algorithm: for an irreducible g (over a perfect field), g^2 ∣ f iff g ∣ gcd(f, f'). The nontrivial direction uses separability of irreducible polynomials over perfect fields.

                                Over a finite field (which is perfect), a polynomial is separable iff it is squarefree.

                                The initial gcd gcd(f, f') computed in Yun's algorithm divides f.

                                noncomputable def BerlekampRabin.equalDegreeSplitStep (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (g u : Polynomial F) (j : ) :

                                One probabilistic splitting step in equal-degree (Cantor-Zassenhaus) factorization (Step 3 of Algorithm 3.47): try h₁ = gcd(g, u); if it is a proper factor, return it; otherwise try h₂ = gcd(g, u^((q^j - 1)/2) - 1); otherwise return g.

                                Instances For

                                  equalDegreeSplitStep F g u j always divides g, in each of the three branches.

                                  theorem BerlekampRabin.equalDegreeSplitStep_root_of_g (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (g u : Polynomial F) (j : ) (r : F) (hr : (equalDegreeSplitStep F g u j).IsRoot r) :
                                  g.IsRoot r

                                  Any root in F of equalDegreeSplitStep F g u j is a root of g, since the output divides g.

                                  noncomputable def BerlekampRabin.equalDegreeFactorLoop (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (j : ) :

                                  The recursive splitting loop in equal-degree factorization (Step 3 of Algorithm 3.47): given g of degree > j, repeatedly split using equalDegreeSplitStep and recurse on both pieces, until each factor has degree j.

                                  Instances For
                                    noncomputable def BerlekampRabin.distinctDegreeStep (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (g : Polynomial F) (j : ) :

                                    Distinct-degree factorization step (Step 2 of Algorithm 3.47): compute g_j = gcd(g, X^(q^j) - X), the product of irreducible factors of g of degree j, and return the pair (g_j, g / g_j).

                                    Instances For
                                      noncomputable def BerlekampRabin.factorSquarefree (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (g : Polynomial F) (randomPolys : List (Polynomial F)) :

                                      Cantor-Zassenhaus factorization of a squarefree polynomial g (Steps 2–3 of Algorithm 3.47): iterate distinctDegreeStep for j = 1, 2, …, then split each g_j further using equalDegreeFactorLoop if needed.

                                      Instances For
                                        @[irreducible]
                                        noncomputable def BerlekampRabin.factorSquarefree.loop (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (randomPolys : List (Polynomial F)) (remaining : Polynomial F) (j fuel : ) (acc : List (Polynomial F)) :
                                        Instances For
                                          noncomputable def BerlekampRabin.cantorZassenhausAlgorithm (F : Type u_1) [Field F] [Fintype F] [DecidableEq F] (f : Polynomial F) (randomPolys : List (Polynomial F)) :

                                          Algorithm 3.47 (Cantor-Zassenhaus): compute the complete irreducible factorization of a monic f ∈ F_q[X] as a list of pairs (p, i), where p is an irreducible factor with multiplicity i. Uses Yun for the squarefree factorization and factorSquarefree for each squarefree piece.

                                          Instances For
                                            structure BerlekampRabin.IsIrreducibleFactorization (F : Type u_1) [Field F] (f : Polynomial F) (n : ) (factors : Fin nPolynomial F) (multiplicities : Fin n) :

                                            Correctness predicate for the output of cantorZassenhausAlgorithm: the indexed family factors : Fin n → F[X] consists of irreducibles, f = ∏ (factors i)^(mult i), multiplicities are positive, and distinct indices give non-associated factors.

                                            • irred (i : Fin n) : Irreducible (factors i)
                                            • prod_eq : f = i : Fin n, factors i ^ multiplicities i
                                            • mult_pos (i : Fin n) : 0 < multiplicities i
                                            • pairwise (i j : Fin n) : i j¬Associated (factors i) (factors j)
                                            Instances For

                                              The first component of distinctDegreeStep F g j, namely gcd(g, X^(q^j) - X), divides g.