mirror of
https://github.com/saymrwulf/ltl-accumulator-verified.git
synced 2026-09-04 20:03:44 +00:00
The single hardest proof in the corpus is complete, no sorry. Under the value-equality invariant y = MTH D₁, an accepting ConsRec fold either makes extractConsNode output a genuine collision or its first component is the honest prefix root MTH(D₁.take n₀). - ConsRec base changed from list-match to decidable if (if C=[] / if C.length=1) — same root-cause fix as Root, avoids WF-unfold exhaustiveness obligations; more faithful to the deployed Python. Whole chain (Basic..Consistency) rebuilt clean. - consRecBinding by ConsRec.induct (10 cases): 4 base/singleton, 3 rejection/none contradictions, 2 recursive (n₀≤k, n₀>k). The n₀>k none-branch is where all S5.1 infrastructure interlocks: kbelow_prefix_eq (prefix splits at same k) + take_take_le + take_drop_prefix assemble x = hnode s xx into MTH(D₁.take n₀). The collision branches use append_inj (fixed-width Hash) + MTH_split. - take_all helper (take-whole-list). Cone [propext, Classical.choice, LTLAcc.sha256, Quot.sound] — single hash axiom. 24 certs green. Fable statement-audit: matches paper Thm 3 steps 1-2. LTL untouched (12 leaves, bcd15f9d). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
153 lines
7.4 KiB
Text
153 lines
7.4 KiB
Text
/- S5.3 — consRecBinding: the paper's Theorem 3 steps 1-2, as a statement
|
|
about the extractor's output. Under the maintained value-equality
|
|
invariant `y = MTH D₁`, an accepting ConsRec fold either makes
|
|
`extractConsNode` output a genuine collision, or its first component is
|
|
the honest prefix root `MTH (D₁.take n₀)`. -/
|
|
import Proofs.Consistency
|
|
|
|
namespace LTLAcc
|
|
|
|
theorem take_all (l : List Bytes) (n : Nat) (h : l.length = n) : l.take n = l := by
|
|
subst h; exact List.take_length
|
|
|
|
theorem consRecBinding (r : Hash) :
|
|
∀ (n₀ n : Nat) (C : List Hash) (b : Bool) (D₁ : List Bytes) (x y : Hash),
|
|
D₁.length = n → 0 < n₀ → n₀ ≤ n →
|
|
ConsRec n₀ n C b r = some (x, y) → y = MTH D₁ →
|
|
(match extractConsNode n₀ n C b r D₁ with
|
|
| some c => IsCollision c.1 c.2
|
|
| none => x = MTH (D₁.take n₀)) := by
|
|
intro n₀ n C b
|
|
induction n₀, n, C, b using ConsRec.induct r with
|
|
| case1 n =>
|
|
intro D₁ x y hlen hn0 hle hcons hy
|
|
rw [ConsRec] at hcons; simp at hcons
|
|
obtain ⟨hx, hyr⟩ := hcons
|
|
have hext : extractConsNode n n [] true r D₁ = none := by rw [extractConsNode]; simp
|
|
simp only [hext]
|
|
rw [← hx, hyr, hy, take_all D₁ n hlen]
|
|
| case2 n C hCne =>
|
|
intro D₁ x y hlen hn0 hle hcons hy
|
|
rw [ConsRec] at hcons; simp [hCne] at hcons
|
|
| case3 n C b hb hC1 =>
|
|
intro D₁ x y hlen hn0 hle hcons hy
|
|
rw [ConsRec] at hcons; simp [hb, hC1] at hcons
|
|
obtain ⟨hx, hyr⟩ := hcons
|
|
have hext : extractConsNode n n C b r D₁ = none := by rw [extractConsNode]; simp
|
|
simp only [hext]
|
|
rw [← hx, hyr, hy, take_all D₁ n hlen]
|
|
| case4 n C b hb hC1 =>
|
|
intro D₁ x y hlen hn0 hle hcons hy
|
|
rw [ConsRec] at hcons; simp [hb, hC1] at hcons
|
|
| case5 n₀ n C b hne hrej =>
|
|
intro D₁ x y hlen hn0 hle hcons hy
|
|
exfalso; omega
|
|
| case6 n₀ n C b hne hrej hgl =>
|
|
intro D₁ x y hlen hn0 hle hcons hy
|
|
rw [ConsRec] at hcons
|
|
simp only [if_neg hne, if_neg hrej, hgl] at hcons
|
|
exact absurd hcons (by simp)
|
|
| case7 n₀ n C b hne hrej s hgl k hle2 hsubnone _ih =>
|
|
intro D₁ x y hlen hn0 hle hcons hy
|
|
rw [ConsRec] at hcons
|
|
have hk : kbelow n = k := rfl
|
|
simp only [if_neg hne, if_neg hrej, hgl, hk, if_pos hle2, hsubnone] at hcons
|
|
exact absurd hcons (by simp)
|
|
| case8 n₀ n C b hne hrej s hgl k hle2 xx yy hsub ih =>
|
|
intro D₁ x y hlen hn0 hle hcons hy
|
|
have h2 : 2 ≤ n := by omega
|
|
have hk : kbelow n = k := rfl
|
|
have hkl : k < n := by rw [← hk]; exact kbelow_lt n h2
|
|
rw [ConsRec] at hcons
|
|
simp only [if_neg hne, if_neg hrej, hgl, hk, if_pos hle2, hsub,
|
|
Option.some.injEq, Prod.mk.injEq] at hcons
|
|
obtain ⟨hx, hyv⟩ := hcons
|
|
have hsplit : MTH D₁ = hnode (MTH (D₁.take k)) (MTH (D₁.drop k)) := by
|
|
have := MTH_split D₁ (by omega); rw [hlen, hk] at this; exact this
|
|
have hnodeeq : hnode yy s = hnode (MTH (D₁.take k)) (MTH (D₁.drop k)) := by
|
|
rw [hyv, hy, hsplit]
|
|
have htklen : (D₁.take k).length = k := by rw [List.length_take, hlen]; omega
|
|
rw [extractConsNode]
|
|
simp only [if_neg hne, if_neg hrej, hgl, hk, if_pos hle2]
|
|
have hy' : (Option.map Prod.snd (ConsRec n₀ k C.dropLast b r)).getD default = yy := by
|
|
rw [hsub]; rfl
|
|
rw [hy']
|
|
by_cases hpair : yy = MTH (D₁.take k) ∧ s = MTH (D₁.drop k)
|
|
· simp only [if_pos hpair]
|
|
have hih := ih (D₁.take k) xx yy htklen hn0 hle2 hsub hpair.1
|
|
cases hrec : extractConsNode n₀ k C.dropLast b r (D₁.take k) with
|
|
| some c => rw [hrec] at hih; exact hih
|
|
| none =>
|
|
rw [hrec] at hih
|
|
have htt : (D₁.take k).take n₀ = D₁.take n₀ := by
|
|
rw [List.take_take]; congr 1; omega
|
|
rw [← hx, hih, htt]
|
|
· simp only [if_neg hpair]
|
|
refine ⟨?_, ?_⟩
|
|
· intro hc
|
|
injection hc with _ happ
|
|
have hln : yy.val.length = (MTH (D₁.take k)).val.length := by
|
|
rw [yy.property, (MTH (D₁.take k)).property]
|
|
obtain ⟨e1, e2⟩ := List.append_inj happ hln
|
|
exact hpair ⟨Subtype.ext e1, Subtype.ext e2⟩
|
|
· show sha256 _ = sha256 _
|
|
have el : sha256 (0x01 :: (yy.val ++ s.val)) = hnode yy s := rfl
|
|
have er : sha256 (0x01 :: ((MTH (D₁.take k)).val ++ (MTH (D₁.drop k)).val))
|
|
= hnode (MTH (D₁.take k)) (MTH (D₁.drop k)) := rfl
|
|
rw [el, er, hnodeeq]
|
|
| case9 n₀ n C b hne hrej s hgl k hle2 hsubnone _ih =>
|
|
intro D₁ x y hlen hn0 hle hcons hy
|
|
rw [ConsRec] at hcons
|
|
have hk : kbelow n = k := rfl
|
|
simp only [if_neg hne, if_neg hrej, hgl, hk, if_neg hle2, hsubnone] at hcons
|
|
exact absurd hcons (by simp)
|
|
| case10 n₀ n C b hne hrej s hgl k hle2 xx yy hsub ih =>
|
|
intro D₁ x y hlen hn0 hle hcons hy
|
|
have h2 : 2 ≤ n := by omega
|
|
have hk : kbelow n = k := rfl
|
|
have hkl : k < n := by rw [← hk]; exact kbelow_lt n h2
|
|
have hkp : 0 < k := by rw [← hk]; exact kbelow_pos n
|
|
rw [ConsRec] at hcons
|
|
simp only [if_neg hne, if_neg hrej, hgl, hk, if_neg hle2, hsub,
|
|
Option.some.injEq, Prod.mk.injEq] at hcons
|
|
obtain ⟨hx, hyv⟩ := hcons
|
|
have hsplit : MTH D₁ = hnode (MTH (D₁.take k)) (MTH (D₁.drop k)) := by
|
|
have := MTH_split D₁ (by omega); rw [hlen, hk] at this; exact this
|
|
have hnodeeq : hnode s yy = hnode (MTH (D₁.take k)) (MTH (D₁.drop k)) := by
|
|
rw [hyv, hy, hsplit]
|
|
have hdklen : (D₁.drop k).length = n - k := by rw [List.length_drop, hlen]
|
|
rw [extractConsNode]
|
|
simp only [if_neg hne, if_neg hrej, hgl, hk, if_neg hle2]
|
|
have hy' : (Option.map Prod.snd (ConsRec (n₀ - k) (n - k) C.dropLast false r)).getD default = yy := by
|
|
rw [hsub]; rfl
|
|
rw [hy']
|
|
by_cases hpair : s = MTH (D₁.take k) ∧ yy = MTH (D₁.drop k)
|
|
· simp only [if_pos hpair]
|
|
have hih := ih (D₁.drop k) xx yy hdklen (by omega) (by omega) hsub hpair.2
|
|
cases hrec : extractConsNode (n₀ - k) (n - k) C.dropLast false r (D₁.drop k) with
|
|
| some c => rw [hrec] at hih; exact hih
|
|
| none =>
|
|
rw [hrec] at hih
|
|
have hn2 : 2 ≤ n₀ := by omega
|
|
have hkbn0 : kbelow n₀ = k := kbelow_prefix_eq h2 hk.symm (by omega) hle
|
|
have htn0len : (D₁.take n₀).length = n₀ := by rw [List.length_take, hlen]; omega
|
|
have hspn0 : MTH (D₁.take n₀)
|
|
= hnode (MTH ((D₁.take n₀).take k)) (MTH ((D₁.take n₀).drop k)) := by
|
|
have := MTH_split (D₁.take n₀) (by omega); rw [htn0len, hkbn0] at this; exact this
|
|
rw [take_take_le D₁ k n₀ (by omega), take_drop_prefix D₁ k n₀] at hspn0
|
|
rw [← hx, hspn0, hpair.1, hih]
|
|
· simp only [if_neg hpair]
|
|
refine ⟨?_, ?_⟩
|
|
· intro hc
|
|
injection hc with _ happ
|
|
have hln : s.val.length = (MTH (D₁.take k)).val.length := by
|
|
rw [s.property, (MTH (D₁.take k)).property]
|
|
obtain ⟨e1, e2⟩ := List.append_inj happ hln
|
|
exact hpair ⟨Subtype.ext e1, Subtype.ext e2⟩
|
|
· show sha256 _ = sha256 _
|
|
have el : sha256 (0x01 :: (s.val ++ yy.val)) = hnode s yy := rfl
|
|
have er : sha256 (0x01 :: ((MTH (D₁.take k)).val ++ (MTH (D₁.drop k)).val))
|
|
= hnode (MTH (D₁.take k)) (MTH (D₁.drop k)) := rfl
|
|
rw [el, er, hnodeeq]
|
|
|
|
end LTLAcc
|