Reduce an integer polynomial coefficientwise into WordMod ctx.
Equations
- Hex.ZPoly.toWP ctx x = Hex.DensePoly.ofCoeffs (Array.map (fun (c : Int) => Hex.WordMod.ofNat (Hex.ZPoly.intModNat c m.toNat)) (Hex.DensePoly.toArray x))
Instances For
Read the canonical [0, M) residues of a WordMod polynomial back into ZPoly.
Equations
- Hex.ZPoly.ofWP ctx p = Hex.DensePoly.ofCoeffs (Array.map (fun (w : Hex.WordMod ctx) => Int.ofNat w.toNat) p.toArray)
Instances For
@[simp]
@[simp]
theorem
Hex.ZPoly.coeff_ofWP
{m : UInt64}
(ctx : _root_.MontCtx m)
(p : DensePoly (WordMod ctx))
(j : Nat)
:
theorem
Hex.DensePoly.mulCoeffStep_ge
{R : Type u_1}
[Lean.Grind.CommRing R]
[DecidableEq R]
(p q : DensePoly R)
(n i : Nat)
(acc : R)
(j : Nat)
(hj : q.size ≤ j)
:
An inner schoolbook step past the divisor's support is the identity.
theorem
Hex.DensePoly.mulCoeffStep_inner_extend
{R : Type u_1}
[Lean.Grind.CommRing R]
[DecidableEq R]
(p q : DensePoly R)
(n i : Nat)
(acc : R)
(t : Nat)
(ht : q.size ≤ t)
:
List.foldl (p.mulCoeffStep q n i) acc (List.range t) = List.foldl (p.mulCoeffStep q n i) acc (List.range q.size)
Extending the inner fold past q.size changes nothing.
theorem
Hex.DensePoly.mulCoeffStep_inner_all_zero
{R : Type u_1}
[Lean.Grind.CommRing R]
[DecidableEq R]
(p q : DensePoly R)
(n i : Nat)
(acc : R)
(hi : p.size ≤ i)
(L : List Nat)
:
Past p.size, the whole inner fold is the identity.
theorem
Hex.DensePoly.mulCoeffStep_outer_extend
{R : Type u_1}
[Lean.Grind.CommRing R]
[DecidableEq R]
(p q : DensePoly R)
(n : Nat)
(acc : R)
(s : Nat)
(hs : p.size ≤ s)
:
List.foldl (fun (acc : R) (i : Nat) => List.foldl (p.mulCoeffStep q n i) acc (List.range q.size)) acc (List.range s) = List.foldl (fun (acc : R) (i : Nat) => List.foldl (p.mulCoeffStep q n i) acc (List.range q.size)) acc
(List.range p.size)
Extending the outer fold past p.size changes nothing.
theorem
Hex.DensePoly.mulCoeffSum_norm
{R : Type u_1}
[Lean.Grind.CommRing R]
[DecidableEq R]
(p q : DensePoly R)
(n s t : Nat)
(hs : p.size ≤ s)
(ht : q.size ≤ t)
:
p.mulCoeffSum q n = List.foldl (fun (acc : R) (i : Nat) => List.foldl (p.mulCoeffStep q n i) acc (List.range t)) 0 (List.range s)
mulCoeffSum computed over any large enough common range s × t.
theorem
Hex.ZPoly.ofWP_toWP_of_canonical
{m : UInt64}
(ctx : _root_.MontCtx m)
(z : ZPoly)
(hz : ∀ (i : Nat), 0 ≤ DensePoly.coeff z i ∧ DensePoly.coeff z i < ↑m.toNat)
:
On a polynomial whose coefficients are already canonical in [0, M),
ofWP ∘ toWP is the identity.
theorem
Hex.ZPoly.toWP_size_eq_of_monic
{m : UInt64}
(ctx : _root_.MontCtx m)
{z : ZPoly}
(hz : DensePoly.Monic z)
(hzpos : 0 < DensePoly.size z)
(h1 : 1 < m.toNat)
:
theorem
Hex.ZPoly.toWP_monic
{m : UInt64}
(ctx : _root_.MontCtx m)
{z : ZPoly}
(hz : DensePoly.Monic z)
(hzpos : 0 < DensePoly.size z)
(h1 : 1 < m.toNat)
:
Reduction to a nontrivial Montgomery modulus preserves monicity.
theorem
Hex.ZPoly.toWP_degree_eq_of_monic
{m : UInt64}
(ctx : _root_.MontCtx m)
{z : ZPoly}
(hz : DensePoly.Monic z)
(hzpos : 0 < DensePoly.size z)
(h1 : 1 < m.toNat)
:
A monic polynomial keeps its degree after reduction to a nontrivial Montgomery modulus.
Modular conversion cannot increase polynomial degree.