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