-rw-r--r-- 36198 leangoppa-20230726/Goppadecoding/goppa_closer.lean raw
import Mathlib.RingTheory.Polynomial.Basic
import Goppadecoding.nat
import Goppadecoding.zero
import Goppadecoding.sq
import Goppadecoding.poly
import Goppadecoding.shiftpoly
import Goppadecoding.vanishing
import Goppadecoding.goppa_binary
import Goppadecoding.goppa_parity
open Polynomial BigOperators Finset
namespace Goppadecoding
section goppa_closer
variable {U: Type _} [DecidableEq U]
variable {k: Type _} [Field k] [CharP k 2] [DecidableEq k]
theorem goppa_checking_2_lemma_coeff
{α r d: U → k} {S: Finset U} {g f: k[X]} {t: ℕ}
(fdeg: f.degree < ((2*t:ℕ):WithBot ℕ))
: coeff (f*∑ s in S, ∑ j in range (2*t), C ((r s / (g^2).eval (α s)) * (d s)^j) * X^(2*t-1-j)) (2*t-1) = ∑ s in S, (r s / (g^2).eval (α s)) * f.eval (d s) :=
by
rw[coeff_mul_sum_sum_geom fdeg]
theorem goppa_checking_2_lemma_WfEhb
{α: U → k} (z: U) {b E F W h f: k[X]} {t21: ℕ}
{bar: k[X] → k[X]}
(bardef: bar = shiftpoly k (α z))
(Wdef: W = (f*E:k[X]) - ((X:k[X])^t21*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21+1)*(F*f):k[X]))
: coeff W t21 = coeff (f*E:k[X]) t21 - (h*b:k[X]).eval (α z) :=
by calc
_ = coeff ((f*E:k[X]) - ((X:k[X])^t21*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21+1)*(F*f):k[X])) t21 := by rw[Wdef]
_ = coeff (f*E:k[X]) t21 - coeff ((X:k[X])^t21*bar (h*b:k[X]):k[X]) t21 - coeff ((X:k[X])^(t21+1)*(F*f):k[X]) t21 := by repeat rw[coeff_sub]
_ = coeff (f*E:k[X]) t21 - (bar (h*b:k[X])).eval (0:k) - 0 := by rw[coeff_X_pow_eq_eval_zero,coeff_X_pow_add_one_eq_zero]
_ = coeff (f*E:k[X]) t21 - (h*b:k[X]).eval (0 + α z) - 0 := by rw[bardef,shiftpoly_eval]
_ = coeff (f*E:k[X]) t21 - (h*b:k[X]).eval (α z) := by group
theorem goppa_checking_2_lemma_hbfE
{α: U → k} (z: U) {b E F W h f: k[X]} {t21: ℕ}
{bar: k[X] → k[X]}
(bardef: bar = shiftpoly k (α z))
(Wdef: W = (f*E:k[X]) - ((X:k[X])^t21*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21+1)*(F*f):k[X]))
(Wdeg: W.degree < (t21:WithBot ℕ))
: (h*b:k[X]).eval (α z) = coeff (f*E:k[X]) t21 :=
by
have W0: coeff W t21 = 0 := coeff_eq_zero_of_degree_lt Wdeg
rw[goppa_checking_2_lemma_WfEhb z bardef Wdef] at W0
exact (eq_if_sub_zero W0).symm
theorem goppa_checking_2_lemma_hbsum
{α r d: U → k} {S: Finset U} (z: U) {A b D E F W h f q: k[X]} {t t21: ℕ}
(Adef: A = monic_vanishing_at α S)
{bar: k[X] → k[X]}
(t2t1: 2*t-1 = t21)
(bardef: bar = shiftpoly k (α z))
(ddef: ∀ s, d s = α s - α z)
(Ddef: D = bar A)
(fdef: f = bar (h*q:k[X]))
(fdeg: f.degree < ((2*t:ℕ):WithBot ℕ))
(Edef: E = ∑ s in S, ∑ j in range (2*t), C ((r s / (g^2:k[X]).eval (α s)) * (d s)^j) * (X:k[X])^(2*t-1-j:ℕ))
(Wdef: W = (f*E:k[X]) - ((X:k[X])^t21*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21+1)*(F*f):k[X]))
(DWdeg: (D*W).degree < (t21:WithBot ℕ) + (S.card:WithBot ℕ))
: (h*b).eval (α z) = ∑ s in S, r s / (g^2:k[X]).eval (α s) * (h*q).eval (α s) :=
by
have bar_degree (p: k[X]): (bar p:k[X]).degree = p.degree := by
repeat rw[bardef]; apply shiftpoly_degree
have dsaz s: d s + α z = α s := by rw[ddef]; group
have Ddeg: D.degree = S.card := by calc
_ = (monic_vanishing_at α S).degree := by rw[Ddef,bar_degree,Adef]
_ = _ := degree_monic_vanishing_at α S
have DWdeg2: W.degree + S.card < (t21:WithBot ℕ) + S.card := by calc
_ = W.degree + D.degree := by rw[Ddeg]
_ = (W*D).degree := by rw[degree_mul]
_ = (D*W).degree := by rw[mul_comm]
_ < _ := DWdeg
have Wdeg: W.degree < (t21:WithBot ℕ) := lt_of_add_lt_add_right DWdeg2
rw[goppa_checking_2_lemma_hbfE z bardef Wdef Wdeg]
rw[← t2t1,Edef,goppa_checking_2_lemma_coeff fdeg]
rw[fdef,bardef]
simp only [shiftpoly_eval,dsaz]
theorem goppa_checking_2_lemma_DWdeg
{α: U → k} {S: Finset U} (z: U) {A B a b D R Q E F W h f q: k[X]} {t t21: ℕ}
{bar: k[X] → k[X]}
(tt1: ((t-1)+t:ℕ) = t21)
(adeg: a.degree ≤ (t:WithBot ℕ))
(bardef: bar = shiftpoly k (α z))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(Ddef: D = bar A)
(XRQ: (X:k[X])^(t21+1)*R - Q = (D*E:k[X]))
(RBDF: R - bar B = (D*F:k[X]))
(fdef: f = bar (h*q:k[X]))
(Wdef: W = (f*E:k[X]) - ((X:k[X])^t21*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21+1)*(F*f):k[X]))
(hdeg: h.degree ≤ (t:WithBot ℕ))
(Qdeg: Q.degree < (S.card:WithBot ℕ))
(qdeg: q.degree ≤ ((t-1:ℕ):WithBot ℕ))
: (D*W).degree < (t21:WithBot ℕ) + (S.card:WithBot ℕ) :=
by
have bar_sub (p q: k[X]): bar (p-q:k[X]) = bar p - bar q := by
repeat rw[bardef]; apply shiftpoly_sub
have bar_mul (p q: k[X]): bar (p*q:k[X]) = bar p * bar q := by
repeat rw[bardef]; apply shiftpoly_mul
have bar_X_sub_C (c: k): bar ((X:k[X]) - C c:k[X]) = (X:k[X]) - C (c - α z) := by
repeat rw[bardef]; apply shiftpoly_X_sub_C
have bar_degree (p: k[X]): (bar p:k[X]).degree = p.degree := by
repeat rw[bardef]; apply shiftpoly_degree
have Xt21: ((X:k[X])^t21*(X:k[X]):k[X]) = ((X:k[X])^(t21+1):k[X]) := by calc
_ = ((X:k[X])^t21*(X:k[X])^1:k[X]) := by rw[pow_one]
_ = ((X:k[X])^(t21+1):k[X]) := by rw[pow_add]
have aBbAdeg2: ((t:WithBot ℕ) + ((a*B:k[X])-(b*A:k[X]):k[X]).degree) + (t:WithBot ℕ) < (S.card:WithBot ℕ) + (t:WithBot ℕ) := by calc
_ = 2*(t:WithBot ℕ) + ((a*B:k[X])-(b*A:k[X]):k[X]).degree := by group
_ < (S.card:WithBot ℕ) + a.degree := aBbAdeg
_ ≤ (S.card:WithBot ℕ) + (t:WithBot ℕ) := add_le_add_left adeg S.card
have aBbAdeg3: (t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) := lt_of_add_lt_add_right aBbAdeg2
have haBbAdeg: (h*(a*B-b*A:k[X]):k[X]).degree < (S.card:WithBot ℕ) := by calc
_ = h.degree + (a*B-b*A:k[X]).degree := degree_mul
_ ≤ (t:WithBot ℕ) + (a*B-b*A:k[X]).degree := add_le_add_right hdeg (a*B-b*A:k[X]).degree
_ < (S.card:WithBot ℕ) := aBbAdeg3
have shifthaBbAdeg: (bar (h*(a*B-b*A:k[X])):k[X]).degree < (S.card:WithBot ℕ) := by calc
_ = (h*(a*B-b*A:k[X]):k[X]).degree := bar_degree (h*(a*B-b*A:k[X]))
_ < (S.card:WithBot ℕ) := haBbAdeg
have shifthaBbAdeg2: (bar ((X:k[X]) - C (α z)) * bar B * bar (h*q) - D * bar (h*b):k[X]).degree < (S.card:WithBot ℕ) := by calc
_ = (bar ((X:k[X]) - C (α z):k[X]) * bar B * bar (h*q) - bar A * bar (h*b:k[X]):k[X]).degree := by rw[Ddef]
_ = (bar (((X:k[X]) - C (α z):k[X]) * B * (h*q:k[X]):k[X]) - bar (A*(h*b:k[X])):k[X]).degree := by repeat rw[bar_mul]
_ = (bar ((((X:k[X]) - C (α z):k[X]) * B * (h*q:k[X]):k[X]) - (A*(h*b:k[X]):k[X]):k[X]):k[X]).degree := by repeat rw[bar_sub]
_ = (bar (h * ((q*((X:k[X]) - C (α z):k[X])*B:k[X]) - (b*A:k[X]))):k[X]).degree := by ring_nf
_ = (bar (h * (a*B - b*A:k[X]):k[X]):k[X]).degree := by rw[aq]
_ < (S.card:WithBot ℕ) := shifthaBbAdeg
have shifthaBbAdeg3: (X^(t21) * (bar ((X:k[X]) - C (α z):k[X]) * bar B * bar (h*q:k[X]) - D * bar (h*b:k[X])):k[X]).degree < (t21 + S.card:WithBot ℕ) := by calc
_ = (X^(t21):k[X]).degree + (bar ((X:k[X]) - C (α z):k[X]) * bar B * bar (h*q:k[X]) - D * bar (h*b:k[X]):k[X]).degree := degree_mul
_ = (t21) + (bar ((X:k[X]) - C (α z):k[X]) * bar B * bar (h*q:k[X]) - D * bar (h*b:k[X]):k[X]).degree := by rw[degree_X_pow]
_ < (t21:WithBot ℕ) + (S.card:WithBot ℕ) := add_left_nat_lt_if_lt t21 shifthaBbAdeg2
have Qfdeg: (Q*bar (h*q):k[X]).degree < (t21:WithBot ℕ) + (S.card:WithBot ℕ) := by calc
_ = Q.degree + (bar (h*q:k[X]):k[X]).degree := degree_mul
_ = Q.degree + (h*q:k[X]).degree := by rw[bar_degree]
_ = Q.degree + (h.degree + q.degree:WithBot ℕ) := by rw[degree_mul]
_ = h.degree + (q.degree + Q.degree:WithBot ℕ) := by group
_ ≤ (t:WithBot ℕ) + (q.degree + Q.degree:WithBot ℕ) := add_le_add_right hdeg (q.degree + Q.degree)
_ = q.degree + (Q.degree + (t:WithBot ℕ)) := by group
_ ≤ ((t-1:ℕ):WithBot ℕ) + (Q.degree + (t:WithBot ℕ)) := add_le_add_right qdeg (Q.degree + (t:WithBot ℕ))
_ = (((t-1:ℕ):WithBot ℕ) + t:WithBot ℕ) + Q.degree := by group
_ = (((t-1:ℕ) + t:ℕ):WithBot ℕ) + Q.degree := by norm_cast
_ = (t21:WithBot ℕ) + Q.degree := by rw[tt1]
_ < (t21:WithBot ℕ) + (S.card:WithBot ℕ) := add_left_nat_lt_if_lt t21 Qdeg
calc
_ = (D*((f*E:k[X]) - ((X:k[X])^(t21)*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21+1)*(F*f):k[X]):k[X]):k[X]).degree := by rw[Wdef]
_ = ((D*E:k[X])*f - ((X:k[X])^(t21)*D*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21+1)*(D*F)*f:k[X]):k[X]).degree := by ring_nf
_ = (((X:k[X])^t21*(X:k[X])*R-Q:k[X])*bar (h*q:k[X]) - ((X:k[X])^(t21)*D*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21)*(X:k[X]) * (R-bar B) * bar (h*q):k[X]):k[X]).degree := by rw[← RBDF,← XRQ,Xt21,fdef]
_ = ((X:k[X])^(t21) * ((((X:k[X]) - (C (α z) - C (α z)):k[X]) * bar B * bar (h*q:k[X]):k[X]) - (D * bar (h*b:k[X]):k[X]):k[X]) - Q*bar (h*q:k[X]):k[X]).degree := by ring_nf
_ = ((X:k[X])^(t21) * (((X:k[X]) - (C (α z - α z))) * bar B * bar (h*q:k[X]) - (D * bar (h*b:k[X]):k[X]):k[X]) - Q*bar (h*q:k[X]):k[X]).degree := by rw[C_sub]
_ = ((X:k[X])^(t21) * (bar ((X:k[X]) - C (α z)) * bar B * bar (h*q:k[X]) - (D * bar (h*b:k[X]):k[X]):k[X]) - Q*bar (h*q:k[X]):k[X]).degree := by rw[bar_X_sub_C]
_ ≤ max ((X:k[X])^(t21) * (bar ((X:k[X]) - C (α z):k[X]) * bar B * bar (h*q:k[X]) - D * bar (h*b:k[X])):k[X]).degree (Q*bar (h*q:k[X]):k[X]).degree := degree_sub_le (X^(t21) * (bar (X - C (α z):k[X]) * bar B * bar (h*q:k[X]) - D * bar (h*b:k[X]):k[X])) (Q*bar (h*q:k[X]))
_ < (t21:WithBot ℕ) + (S.card:WithBot ℕ) := max_lt shifthaBbAdeg3 Qfdeg
theorem goppa_checking_2_lemma_hbsum2
{α r d: U → k} {S: Finset U} (z: U) {A B a b D R Q E F W h f q: k[X]} {t t21: ℕ}
(tt1: ((t-1)+t:ℕ) = t21)
(t2t1: 2*t-1 = t21)
(Adef: A = monic_vanishing_at α S)
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(adeg: a.degree ≤ (t:WithBot ℕ))
(aq: a = q*((X:k[X]) - C (α z):k[X]))
{bar: k[X] → k[X]}
(bardef: bar = shiftpoly k (α z))
(ddef: ∀ s, d s = α s - α z)
(Ddef: D = bar A)
(fdef: f = bar (h*q:k[X]))
(fdeg: f.degree < ((2*t:ℕ):WithBot ℕ))
(Edef: E = ∑ s in S, ∑ j in range (2*t), C ((r s / (g^2:k[X]).eval (α s)) * (d s)^j) * (X:k[X])^(2*t-1-j:ℕ))
(XRQ: (X:k[X])^(t21+1)*R - Q = (D*E:k[X]))
(RBDF: R - bar B = (D*F:k[X]))
(Wdef: W = (f*E:k[X]) - ((X:k[X])^t21*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21+1)*(F*f):k[X]))
(hdeg: h.degree ≤ (t:WithBot ℕ))
(Qdeg: Q.degree < (S.card:WithBot ℕ))
(qdeg: q.degree ≤ ((t-1:ℕ):WithBot ℕ))
: (h*b).eval (α z) = ∑ s in S, r s / (g^2:k[X]).eval (α s) * (h*q).eval (α s) :=
by
have DWdeg: (D*W).degree < (t21:WithBot ℕ) + (S.card:WithBot ℕ) :=
goppa_checking_2_lemma_DWdeg z tt1 adeg bardef aBbAdeg aq Ddef XRQ RBDF fdef Wdef hdeg Qdeg qdeg
exact goppa_checking_2_lemma_hbsum z Adef t2t1 bardef ddef Ddef fdef fdeg Edef Wdef DWdeg
theorem goppa_checking_2_lemma_hbsum3
{α r d: U → k} {S: Finset U} (z: U) {A B a b g D R Q E F h q: k[X]} {t t21: ℕ}
{bar: k[X] → k[X]}
(tt1: ((t-1)+t:ℕ) = t21)
(t2t1: 2*t-1 = t21)
(t1t: t-1 < t)
(Adef: A = monic_vanishing_at α S)
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(bardef: bar = shiftpoly k (α z))
(qdeg: q.degree ≤ ((t-1:ℕ):WithBot ℕ))
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(ddef: ∀ s, d s = α s - α z)
(Ddef: D = bar A)
(Qdeg: Q.degree < (S.card:WithBot ℕ))
(Edef: E = ∑ s in S, ∑ j in range (2*t), C ((r s / (g^2:k[X]).eval (α s)) * (d s)^j) * (X:k[X])^(2*t-1-j:ℕ))
(XRQ: (X^(t21+1:ℕ)*R - Q:k[X]) = (D*E:k[X]))
(RBDF: (R - bar B:k[X]) = (D*F:k[X]))
(hdeg: h.degree ≤ t)
: (h*b).eval (α z) = ∑ s in S, r s / (g^2:k[X]).eval (α s) * (h*q).eval (α s) :=
by
let f := bar (h*q:k[X])
let W := (f*E:k[X]) - ((X:k[X])^t21*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21+1)*(F*f):k[X])
have fdef: f = bar (h*q:k[X]) := rfl
have Wdef: W = (f*E:k[X]) - ((X:k[X])^t21*bar (h*b:k[X]):k[X]) - ((X:k[X])^(t21+1)*(F*f):k[X]) := rfl
have qdegt: q.degree < t := by calc
_ ≤ ((t-1:ℕ):WithBot ℕ) := qdeg
_ < t := by norm_cast
have fdeg: f.degree < (2*t:ℕ) := by calc
_ = (shiftpoly k (α z) (h*q)).degree := by rw[fdef,bardef]
_ = (h*q).degree := by rw[shiftpoly_degree]
_ = h.degree + q.degree := degree_mul
_ ≤ t + q.degree := add_le_add_right hdeg q.degree
_ < ((t + t):WithBot ℕ) := add_left_nat_lt_if_lt t qdegt
_ = ((t + t:ℕ):WithBot ℕ) := by norm_cast
_ = ((2*t:ℕ):WithBot ℕ) := by norm_cast; exact (Nat.two_mul t).symm
exact goppa_checking_2_lemma_hbsum2 z tt1 t2t1 Adef aBbAdeg adeg aq bardef ddef Ddef fdef fdeg Edef XRQ RBDF Wdef hdeg Qdeg qdeg
theorem goppa_checking_2_lemma_RBD
{α r d: U → k} {S: Finset U} (z: U) {A B g D R: k[X]}
{bar: k[X] → k[X]}
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef : ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(ddef: ∀ s, d s = α s - α z)
(dinjective: Set.InjOn d S)
(bardef: bar = shiftpoly k (α z))
(Ddef: D = bar A)
(Dmv: D = monic_vanishing_at d S)
(Rdef: R = ∑ s in S, C (r s / (g^2:k[X]).eval (α s)) * monic_vanishing_at_except d S s)
: D ∣ R - bar B :=
by
have dsaz s: d s + α z = α s := by rw[ddef]; group
have bar_eval (c: k) (p: k[X]): (bar p).eval c = p.eval (c + α z) := by
repeat rw[bardef]; apply shiftpoly_eval
have bar_diff (p: k[X]): (bar p).diff = bar p.diff := by
repeat rw[bardef]; apply shiftpoly_diff
have Ddiffeval s: D.diff.eval (d s) = A.diff.eval (α s) := by calc
_ = D.diff.eval (d s) := rfl
_ = (bar A.diff).eval (d s) := by rw[Ddef,bar_diff]
_ = A.diff.eval (d s + α z) := by rw[bar_eval]
_ = A.diff.eval (α s) := by rw[dsaz s]
have Rinterp: R = interpolator d S (fun s ↦ r s / (g^2).eval (α s) * D.diff.eval (d s)) := by
rw[Rdef]
exact sum_C_mul_monic_vanishing_at_except_eq_interpolator (fun s ↦ r s / (g^2).eval (α s)) dinjective Dmv
have Reval s (sinS: s ∈ S): R.eval (d s) = B.eval (α s) := by calc
_ = (interpolator d S (fun s ↦ r s / (g^2).eval (α s) * D.diff.eval (d s))).eval (d s) := by rw[Rinterp]
_ = r s / (g^2).eval (α s) * D.diff.eval (d s) := by rw[interpolator_eval dinjective sinS]
_ = r s / (g^2).eval (α s) * A.diff.eval (α s) := by rw[Ddiffeval s]
_ = ((g^2 * B).eval (α s) / A.diff.eval (α s)) / (g^2).eval (α s) * A.diff.eval (α s) := by rw[rdef s sinS]
_ = ((g^2).eval (α s) * B.eval (α s) / A.diff.eval (α s)) / (g^2).eval (α s) * A.diff.eval (α s) := by rw[eval_mul]
_ = B.eval (α s) * ((g^2).eval (α s) / (g^2).eval (α s)) * (A.diff.eval (α s) / A.diff.eval (α s)) := by group
_ = B.eval (α s) * 1 * 1 := by rw[div_self (Aprimeevalnonzero s sinS),div_self (g2nonzero s sinS)]
_ = B.eval (α s) := by repeat rw[mul_one]
have RBbareval s (sinS: s ∈ S): (R - bar B).eval (d s) = 0 := by calc
_ = R.eval (d s) - (bar B).eval (d s) := by rw[eval_sub]
_ = R.eval (d s) - B.eval (d s + α z) := by rw[bar_eval]
_ = R.eval (d s) - B.eval (α s) := by rw[dsaz s]
_ = B.eval (α s) - B.eval (α s) := by rw[Reval s sinS]
_ = 0 := by rw[sub_self]
rw[Dmv]
exact monic_vanishing_at_divides S (R - bar B) dinjective RBbareval
theorem goppa_checking_2_lemma_hbsum4
{α r d: U → k} {S: Finset U} (z: U) {A B a b g D R h q: k[X]} {t t21: ℕ}
{bar: k[X] → k[X]}
(tt1: ((t-1)+t:ℕ) = t21)
(t2t1: 2*t-1 = t21)
(t211: t21+1 = 2*t)
(t1t: t-1 < t)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef : ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(ddef: ∀ s, d s = α s - α z)
(dinjective: Set.InjOn d S)
(bardef: bar = shiftpoly k (α z))
(qdeg: q.degree ≤ ((t-1:ℕ):WithBot ℕ))
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(Ddef: D = bar A)
(Dmv: D = monic_vanishing_at d S)
(hdeg: h.degree ≤ t)
(Edef: E = ∑ s in S, ∑ j in range (2*t), C ((r s / (g^2:k[X]).eval (α s)) * (d s)^j) * (X:k[X])^(2*t-1-j:ℕ))
(Rdef: R = ∑ s in S, C (r s / (g^2).eval (α s)) * monic_vanishing_at_except d S s)
(Qdef: Q = ∑ s in S, C ((r s / (g^2).eval (α s)) * (d s)^(2*t)) * monic_vanishing_at_except d S s)
(Qdeg: Q.degree < (S.card:WithBot ℕ))
: (h*b).eval (α z) = ∑ s in S, r s / (g^2:k[X]).eval (α s) * (h*q).eval (α s) :=
by
have RBD: D ∣ R - bar B := goppa_checking_2_lemma_RBD z Aprimeevalnonzero g2nonzero rdef ddef dinjective bardef Ddef Dmv Rdef
cases RBD with | intro F RBDF =>
have XRQ: (X^(t21+1:ℕ)*R - Q:k[X]) = (D*E:k[X]) := by
rw[t211,Rdef,Qdef,Edef,Dmv]
exact goppa_parity_lemma d (fun s ↦ r s / (g^2).eval (α s)) S (2*t)
exact goppa_checking_2_lemma_hbsum3 z tt1 t2t1 t1t Adef adeg aBbAdeg bardef qdeg aq ddef Ddef Qdeg Edef XRQ RBDF hdeg
theorem goppa_checking_2_lemma_hbsum5
{α r d: U → k} {S: Finset U} (z: U) {A B a b g D R h q: k[X]} {t t21: ℕ}
{bar: k[X] → k[X]}
(tt1: ((t-1)+t:ℕ) = t21)
(t2t1: 2*t-1 = t21)
(t211: t21+1 = 2*t)
(t1t: t-1 < t)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef : ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(ddef: ∀ s, d s = α s - α z)
(dinjective: Set.InjOn d S)
(bardef: bar = shiftpoly k (α z))
(qdeg: q.degree ≤ ((t-1:ℕ):WithBot ℕ))
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(Ddef: D = bar A)
(Dmv: D = monic_vanishing_at d S)
(hdeg: h.degree ≤ t)
(Edef: E = ∑ s in S, ∑ j in range (2*t), C ((r s / (g^2:k[X]).eval (α s)) * (d s)^j) * (X:k[X])^(2*t-1-j:ℕ))
(Rdef: R = ∑ s in S, C (r s / (g^2).eval (α s)) * monic_vanishing_at_except d S s)
(Qdef: Q = ∑ s in S, C ((r s / (g^2).eval (α s)) * (d s)^(2*t)) * monic_vanishing_at_except d S s)
: (h*b).eval (α z) = ∑ s in S, r s / (g^2:k[X]).eval (α s) * (h*q).eval (α s) :=
by
have Qinterp: Q = interpolator d S (fun (s:U) ↦ (((r s / (g^2).eval (α s)) * (d s)^(2*t) * D.diff.eval (d s)):k)) := by
rw[Qdef]
exact sum_C_mul_monic_vanishing_at_except_eq_interpolator (fun (s:U) ↦ (((r s / (g^2).eval (α s)) * (d s)^(2*t)):k)) dinjective Dmv
have Qdeg: Q.degree < S.card := by
rw[Qinterp]
apply degree_interpolator_lt
exact goppa_checking_2_lemma_hbsum4 z tt1 t2t1 t211 t1t Adef Aprimeevalnonzero g2nonzero rdef adeg aBbAdeg ddef dinjective bardef qdeg aq Ddef Dmv hdeg Edef Rdef Qdef Qdeg
theorem goppa_checking_2_lemma_hbsum6
{α r d: U → k} {S: Finset U} (z: U) {A B a b g D h q: k[X]} {t t21: ℕ}
{bar: k[X] → k[X]}
(tt1: ((t-1)+t:ℕ) = t21)
(t2t1: 2*t-1 = t21)
(t211: t21+1 = 2*t)
(t1t: t-1 < t)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef : ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(ddef: ∀ s, d s = α s - α z)
(dinjective: Set.InjOn d S)
(bardef: bar = shiftpoly k (α z))
(qdeg: q.degree ≤ ((t-1:ℕ):WithBot ℕ))
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(Ddef: D = bar A)
(Dmv: D = monic_vanishing_at d S)
(hdeg: h.degree ≤ t)
: (h*b).eval (α z) = ∑ s in S, r s / (g^2:k[X]).eval (α s) * (h*q).eval (α s) :=
by
let E := ∑ s in S, ∑ j in range (2*t), C ((r s / (g^2:k[X]).eval (α s)) * (d s)^j) * (X:k[X])^(2*t-1-j:ℕ)
have Edef: E = ∑ s in S, ∑ j in range (2*t), C ((r s / (g^2:k[X]).eval (α s)) * (d s)^j) * (X:k[X])^(2*t-1-j:ℕ) := rfl
let R := ∑ s in S, C (r s / (g^2).eval (α s)) * monic_vanishing_at_except d S s
have Rdef: R = ∑ s in S, C (r s / (g^2).eval (α s)) * monic_vanishing_at_except d S s := rfl
let Q := ∑ s in S, C ((r s / (g^2).eval (α s)) * (d s)^(2*t)) * monic_vanishing_at_except d S s
have Qdef: Q = ∑ s in S, C ((r s / (g^2).eval (α s)) * (d s)^(2*t)) * monic_vanishing_at_except d S s := rfl
exact goppa_checking_2_lemma_hbsum5 z tt1 t2t1 t211 t1t Adef Aprimeevalnonzero g2nonzero rdef adeg aBbAdeg ddef dinjective bardef qdeg aq Ddef Dmv hdeg Edef Rdef Qdef
theorem goppa_checking_2_lemma_hbsum7
{α r d: U → k} {S: Finset U} (z: U) {A B a b g h q: k[X]} {t t21: ℕ}
(tt1: ((t-1)+t:ℕ) = t21)
(t2t1: 2*t-1 = t21)
(t211: t21+1 = 2*t)
(t1t: t-1 < t)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef : ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(ddef: ∀ s, d s = α s - α z)
(dinjective: Set.InjOn d S)
(qdeg: q.degree ≤ ((t-1:ℕ):WithBot ℕ))
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(hdeg: h.degree ≤ t)
: (h*b).eval (α z) = ∑ s in S, r s / (g^2:k[X]).eval (α s) * (h*q).eval (α s) :=
by
let bar := shiftpoly k (α z)
have bardef: bar = shiftpoly k (α z) := rfl
have bar_X_sub_C (c: k): bar ((X:k[X]) - C c:k[X]) = (X:k[X]) - C (c - α z) := by
repeat rw[bardef]; apply shiftpoly_X_sub_C
have bar_prod {p: U → k[X]}: bar (∏ s in S, p s) = ∏ s in S, bar (p s) := by
repeat rw[bardef]; apply shiftpoly_prod
let D := bar A
have Ddef: D = bar A := rfl
have Dmv: D = monic_vanishing_at d S := by calc
_ = bar A := rfl
_ = bar (monic_vanishing_at α S) := by rw[Adef]
_ = bar (∏ s in S, (X - C (α s))) := by rw[monic_vanishing_at]
_ = ∏ s in S, bar (X - C (α s)) := by rw[bar_prod]
_ = ∏ s in S, (X - C (d s)) := by
apply prod_congr; simp only
intro s _
rw[bar_X_sub_C,ddef s]
_ = monic_vanishing_at d S := by rw[monic_vanishing_at]
exact goppa_checking_2_lemma_hbsum6 z tt1 t2t1 t211 t1t Adef Aprimeevalnonzero g2nonzero rdef adeg aBbAdeg ddef dinjective bardef qdeg aq Ddef Dmv hdeg
theorem goppa_checking_2_lemma_hbsum8
{α r: U → k} {S: Finset U} (z: U) {A B a b g h q: k[X]} {t t21: ℕ}
(tt1: ((t-1)+t:ℕ) = t21)
(t2t1: 2*t-1 = t21)
(t211: t21+1 = 2*t)
(t1t: t-1 < t)
(injective: Set.InjOn α S)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef : ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(qdeg: q.degree ≤ ((t-1:ℕ):WithBot ℕ))
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(hdeg: h.degree ≤ t)
: (h*b).eval (α z) = ∑ s in S, r s / (g^2:k[X]).eval (α s) * (h*q).eval (α s) :=
by
let d := fun s ↦ α s - α z
have ddef s: d s = α s - α z := rfl
have dinjective: Set.InjOn d S := by
rw[Set.InjOn]
intro x xinS y yinS dxdy
have axay: α x = α y := by calc
α x = (α x - α z) + α z := eq_add_of_sub_eq rfl
_ = (α y - α z) + α z := by rw[← ddef x,← ddef y,dxdy]
_ = α y := (eq_add_of_sub_eq rfl).symm
exact injective xinS yinS axay
exact goppa_checking_2_lemma_hbsum7 z tt1 t2t1 t211 t1t Adef Aprimeevalnonzero g2nonzero rdef adeg aBbAdeg ddef dinjective qdeg aq hdeg
theorem goppa_checking_2_lemma_gb2qb
{α r: U → k} {S: Finset U} (z: U) {A B a b g q: k[X]} {t t21: ℕ}
(tt1: ((t-1)+t:ℕ) = t21)
(t2t1: 2*t-1 = t21)
(t211: t21+1 = 2*t)
(t1t: t-1 < t)
(injective: Set.InjOn α S)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef: ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(rsq: ∀ s, (r s)^2 = r s)
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(qdeg: q.degree ≤ ((t-1:ℕ):WithBot ℕ))
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(gdeg: g.degree ≤ t)
: ((g*b).eval (α z))^2 = (q*b).eval (α z) :=
by
have qdegt: q.degree ≤ t := by calc
_ ≤ ((t-1:ℕ):WithBot ℕ) := qdeg
_ ≤ t := by norm_cast; exact Nat.sub_le t 1
have gb: (g*b).eval (α z) = ∑ s in S, r s / (g^2:k[X]).eval (α s) * (g*q).eval (α s) :=
goppa_checking_2_lemma_hbsum8 z tt1 t2t1 t211 t1t injective Adef Aprimeevalnonzero g2nonzero rdef adeg aBbAdeg qdeg aq gdeg
have qb: (q*b).eval (α z) = ∑ s in S, r s / (g^2:k[X]).eval (α s) * (q*q).eval (α s) :=
goppa_checking_2_lemma_hbsum8 z tt1 t2t1 t211 t1t injective Adef Aprimeevalnonzero g2nonzero rdef adeg aBbAdeg qdeg aq qdegt
have rg2gq s: r s / (g^2:k[X]).eval (α s) * (g*q).eval (α s) = r s / g.eval (α s) * q.eval (α s) := by
rw[eval_pow,eval_mul]
rw[div_sq_mul_mul (r s) (g.eval (α s)) (q.eval (α s))]
have sumrg2gq: ∑ s in S, r s / (g^2:k[X]).eval (α s) * (g*q).eval (α s) = ∑ s in S, r s / g.eval (α s) * q.eval (α s) := by
apply sum_congr; rfl; intro s _; rw[rg2gq s]
calc
_ = (∑ s in S, r s / (g^2:k[X]).eval (α s) * (g*q).eval (α s))^2 := by rw[gb]
_ = (∑ s in S, r s / g.eval (α s) * q.eval (α s))^2 := by rw[sumrg2gq]
_ = ∑ s in S, (r s / g.eval (α s) * q.eval (α s))^2 := by rw[CharTwo.sum_sq]
_ = ∑ s in S, (r s / g.eval (α s))^2 * (q.eval (α s))^2 := by simp[mul_sq]
_ = ∑ s in S, (r s)^2 / (g.eval (α s))^2 * (q.eval (α s))^2 := by simp[div_sq]
_ = ∑ s in S, r s / (g.eval (α s))^2 * (q.eval (α s))^2 := by simp[rsq]
_ = ∑ s in S, r s / ((g^2:k[X]).eval (α s)) * (q^2).eval (α s) := by simp[eval_pow]
_ = ∑ s in S, r s / ((g^2:k[X]).eval (α s)) * (q*q).eval (α s) := by rw[← sq]
_ = (q*b).eval (α z) := by rw[qb]
theorem goppa_checking_2_lemma_gb2qb2
{α r: U → k} {S: Finset U} (z: U) {A B a b g q: k[X]} {t: ℕ}
(injective: Set.InjOn α S)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef: ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(rsq: ∀ s, (r s)^2 = r s)
(aA : a ∣ A)
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(gdeg: g.degree ≤ t)
: ((g*b).eval (α z))^2 = (q*b).eval (α z) :=
by
have Anonzero: A ≠ 0 := by rw[Adef]; exact monic_vanishing_at_nonzero α S
have anonzero: a ≠ 0 := nonzero_if_divides_nonzero aA Anonzero
have qnonzero: q ≠ 0 := by
by_cases q0: q = 0
. rw[q0,zero_mul,← not_ne_iff] at aq
rw[q0]
simp only [ne_eq, not_true]
exact aq anonzero
simp[q0]
have qdegnat: 0 ≤ q.degree := zero_le_degree_iff.mpr qnonzero
have adegqdeg: a.degree = q.degree + 1 := by calc
_ = (q*((X:k[X]) - C (α z):k[X])).degree := by rw[aq]
_ = q.degree + (X - C (α z)).degree := degree_mul
_ = q.degree + 1 := by simp
have qdeg1: q.degree + 1 ≤ t := by rw[← adegqdeg]; exact adeg
have t1withbot: 1 ≤ (t:WithBot ℕ) := by calc
_ = (0 + 1:WithBot ℕ) := by rw[zero_add]
_ ≤ q.degree + 1 := add_le_add_right qdegnat 1
_ = a.degree := by rw[adegqdeg]
_ ≤ t := adeg
have t1: 1 ≤ t := WithBot.coe_le_coe.mp t1withbot
let t21 := 2*t-1
have t2t1: 2*t-1 = t21 := rfl
have t1t: t-1 < t := sub_one_lt_if_one_le t1
have tt1: ((t-1)+t:ℕ) = t21 := by rw[← t2t1]; exact sub_one_add_eq_dbl_sub_one
have t211: t21+1 = 2*t := by rw[← t2t1]; exact dbl_sub_one_add_one_eq_dbl_if_one_le t1
have qdeg: q.degree ≤ ((t-1:ℕ):WithBot ℕ) := le_sub_one_if_one_le_and_add_one_le t1 qdeg1
exact goppa_checking_2_lemma_gb2qb z tt1 t2t1 t211 t1t injective Adef Aprimeevalnonzero g2nonzero rdef rsq adeg aBbAdeg qdeg aq gdeg
theorem goppa_checking_2_lemma_gb2qb3
{α r: U → k} {S: Finset U} (z: U) {A B a b g q: k[X]} {t: ℕ}
(injective: Set.InjOn α S)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef: ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(rsq: ∀ s, (r s)^2 = r s)
(ab: IsCoprime a b)
(aA : a ∣ A)
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(zroot: a.eval (α z) = 0)
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(gdeg: g.degree ≤ t)
: (g^2*b - q).eval (α z) = 0 :=
by
have h: ((g*b).eval (α z))^2 = (q*b).eval (α z) :=
goppa_checking_2_lemma_gb2qb2 z injective Adef Aprimeevalnonzero g2nonzero rdef rsq aA adeg aBbAdeg aq gdeg
have h2: (g^2*b - q).eval (α z) * b.eval (α z) = 0 := by calc
_ = ((g^2*b - q)*b).eval (α z) := by rw[eval_mul]
_ = ((g*b)^2 - q*b).eval (α z) := by ring_nf
_ = ((g*b)^2).eval (α z) - (q*b).eval (α z) := by rw[eval_sub]
_ = (g*b).eval (α z)^2 - (q*b).eval (α z) := by rw[eval_pow]
_ = (q*b).eval (α z) - (q*b).eval (α z) := by rw[h]
_ = 0 := by group
have beval: b.eval (α z) ≠ 0 := no_shared_root_if_coprime ab zroot
exact zero_if_mul_right_zero beval h2
theorem goppa_checking_2_lemma_gb2qb4
{α r: U → k} {S: Finset U} (z: U) {A B a b g q: k[X]} {t: ℕ}
(injective: Set.InjOn α S)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef: ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(rsq: ∀ s, (r s)^2 = r s)
(ab: IsCoprime a b)
(aA : a ∣ A)
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(zroot: a.eval (α z) = 0)
(aq: a = q*((X:k[X]) - C (α z):k[X]))
(gdeg: g.degree ≤ t)
: (g^2*b - a.diff).eval (α z) = 0 :=
by
have adiffq: a.diff = q.diff*(X - C (α z)) + q := by
rw[aq,diff,AddHom.toFun_eq_coe,LinearMap.coe_toAddHom]
simp only [derivative_mul, map_sub, derivative_X, derivative_C, sub_zero, mul_one]
have adiffeval: a.diff.eval (α z) = q.eval (α z) := by calc
_ = (q.diff*(X - C (α z)) + q).eval (α z) := by rw[adiffq]
_ = (q.diff*(X - C (α z))).eval (α z) + q.eval (α z) := by simp only [eval_add]
_ = q.diff.eval (α z) * (X - C (α z)).eval (α z) + q.eval (α z) := by simp only [eval_mul]
_ = q.diff.eval (α z) * 0 + q.eval (α z) := by simp only [eval_sub,eval_X,eval_C,sub_self]
_ = q.eval (α z) := by rw[mul_zero,zero_add]
calc
_ = (g^2*b).eval (α z) - a.diff.eval (α z) := by rw[eval_sub]
_ = (g^2*b).eval (α z) - q.eval (α z) := by rw[adiffeval]
_ = (g^2*b-q).eval (α z) := by rw[eval_sub]
_ = 0 := goppa_checking_2_lemma_gb2qb3 z injective Adef Aprimeevalnonzero g2nonzero rdef rsq ab aA adeg aBbAdeg zroot aq gdeg
theorem goppa_checking_2_lemma_gb2qb5
{α r: U → k} {S: Finset U} (z: U) {A B a b g: k[X]} {t: ℕ}
(injective: Set.InjOn α S)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef: ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(rsq: ∀ s, (r s)^2 = r s)
(ab: IsCoprime a b)
(aA : a ∣ A)
(adeg: a.degree ≤ (t:WithBot ℕ))
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
(zinSfilter: z ∈ S.filter (fun s ↦ a.eval (α s) = 0))
(gdeg: g.degree ≤ t)
: (g^2*b - a.diff).eval (α z) = 0 :=
by
let q := C (leadingCoeff a) * monic_vanishing_at_except α (S.filter (fun s ↦ a.eval (α s) = 0)) z
have qdef: q = C (leadingCoeff a) * monic_vanishing_at_except α (S.filter (fun s ↦ a.eval (α s) = 0)) z := rfl
have amv: a ∣ monic_vanishing_at α S := by rw[← Adef]; exact aA
have acm: a = C a.leadingCoeff * monic_vanishing_at α (S.filter (fun s ↦ a.eval (α s) = 0)) := lead_mul_monic_vanishing_at_roots_if_dvd_monic_vanishing_at injective amv
have aq: a = q*((X:k[X]) - C (α z):k[X]) := by rw[acm,qdef,mul_assoc,monic_vanishing_at_except_filter α (S.filter (fun s ↦ a.eval (α s) = 0)) z zinSfilter]
rw[mem_filter] at zinSfilter
have zroot: a.eval (α z) = 0 := by simp[zinSfilter]
exact goppa_checking_2_lemma_gb2qb4 z injective Adef Aprimeevalnonzero g2nonzero rdef rsq ab aA adeg aBbAdeg zroot aq gdeg
theorem goppa_checking_2_lemma_adiv
{α r: U → k} {S: Finset U} {A B a b g: k[X]} {t: ℕ}
(injective: Set.InjOn α S)
(Adef: A = monic_vanishing_at α S)
(Aprimeevalnonzero : ∀ s, s ∈ S → eval (α s) (diff A) ≠ 0)
(g2nonzero : ∀ s, s ∈ S → eval (α s) (g^2) ≠ 0)
(rdef: ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(rsq: ∀ s, (r s)^2 = r s)
(gdeg: g.degree ≤ t)
(ab: IsCoprime a b)
(aA: a ∣ A)
(adeg: a.degree ≤ t)
(aBbAdeg: 2*(t:WithBot ℕ) + (a*B-b*A:k[X]).degree < (S.card:WithBot ℕ) + a.degree)
: a ∣ g^2*b - a.diff :=
by
have amv: a ∣ monic_vanishing_at α S := by rw[← Adef]; exact aA
have acm: a = C a.leadingCoeff * monic_vanishing_at α (S.filter (fun s ↦ a.eval (α s) = 0)) := lead_mul_monic_vanishing_at_roots_if_dvd_monic_vanishing_at injective amv
have leadnonzero: a.leadingCoeff ≠ 0 := lead_nonzero_if_dvd_monic_vanishing_at amv
apply dvd_if_mul_C_nonzero_and_dvd acm leadnonzero
apply monic_vanishing_at_divides
. apply injon_filter _ _ _ injective
intro z zinSfilter
exact goppa_checking_2_lemma_gb2qb5 z injective Adef Aprimeevalnonzero g2nonzero rdef rsq ab aA adeg aBbAdeg zinSfilter gdeg
theorem goppa_checking_2
{α e r: U → k} {S: Finset U} {A B a b g: k[X]} {t: ℕ}
(injective: Set.InjOn α S)
(Adef: A = monic_vanishing_at α S)
(gdeg: g.degree = t)
(gA: IsCoprime g A)
(ab: IsCoprime a b)
(adeg: a.degree ≤ t)
(aA: a ∣ A)
(aBbAdeg: 2*t + (a*B-b*A).degree < S.card + a.degree)
(rdef: ∀ s, s ∈ S → r s = (g^2*B).eval (α s) / A.diff.eval (α s))
(rsq: ∀ s, (r s)^2 = r s)
(ea: (∀ s, s ∈ S → e s = if a.eval (α s) = 0 then 1 else 0))
: (a ∣ g^2*b - a.diff ∧
hamming_weight e S = a.degree ∧
g^2 ∣ ∑ s in S, C (((g^2 * B).eval (α s) / A.diff.eval (α s) - e s)) * monic_vanishing_at_except α S s
) :=
by
have gdegle: g.degree ≤ t := by rw[gdeg]
have Aprimeevalnonzero s (sinS: s ∈ S): A.diff.eval (α s) ≠ 0 := by
rw[Adef]
exact derivative_monic_vanishing_at_eval_nonzero α injective sinS
have g2nonzero s (sinS: s ∈ S): (g^2).eval (α s) ≠ 0 := by
have Ag: IsCoprime A g := isCoprime_comm.mpr gA
have Aeval: A.eval (α s) = 0 := by
rw[Adef]
exact monic_vanishing_at_vanishes α S sinS
have gnonzero: g.eval (α s) ≠ 0 := no_shared_root_if_coprime Ag Aeval
calc
_ = (g.eval (α s))^2 := by rw[eval_pow]
_ ≠ 0 := pow_ne_zero 2 gnonzero
have g2ba: a ∣ g^2*b - a.diff := goppa_checking_2_lemma_adiv injective Adef Aprimeevalnonzero g2nonzero rdef rsq gdegle ab aA adeg aBbAdeg
constructor
. exact g2ba
let G := g^2
have g2G: g^2 = G := rfl
rw[g2G]
have Gba: a ∣ G*b - a.diff := g2ba
have Gdeg: G.degree = 2*t := by calc
G.degree = (g^2).degree := rfl
_ = 2*g.degree := by simp only [degree_pow, nsmul_eq_mul, Nat.cast_ofNat]
_ = 2*t := by rw[gdeg]
exact goppa_checking injective Adef Gdeg aA aBbAdeg Gba ea
end goppa_closer