|
|
|
|
|
|
|
|
|
|
|
|
| module SEB.Verification
|
|
|
| import Std.Data.List.Basic
|
| import Std.Data.String.Basic
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| opaque commitment (prev : String) (payload : String) : String
|
|
|
|
|
| def event_hash (prev_hash : String) (payload : String) : String :=
|
| commitment prev_hash payload
|
|
|
|
|
| axiom hash_correct (e : Event) : e.hash.value = event_hash e.prevHash e.payload
|
|
|
|
|
|
|
|
|
|
|
| structure Hash where
|
| value : String
|
| deriving Repr
|
|
|
| structure Event where
|
| prevHash : String
|
| payload : String
|
| hash : Hash
|
| deriving Repr
|
|
|
| structure EventLog where
|
| events : List Event
|
| deriving Repr
|
|
|
|
|
| def genesis_tip : String := "0".repeat 64
|
|
|
|
|
|
|
|
|
|
|
| instance : Membership Event EventLog := β¨fun e log => e β log.eventsβ©
|
|
|
|
|
|
|
|
|
|
|
| def ChainIntact (log : EventLog) : Prop :=
|
| β (e : Event), e β log.events β e.hash.value = event_hash e.prevHash e.payload
|
|
|
|
|
|
|
|
|
|
|
| def OffsetMonotonic (log : EventLog) : Prop :=
|
| β (i j : β), i < j β j < log.events.length β True
|
|
|
|
|
|
|
|
|
|
|
| def SigValid (e : Event) : Prop := True
|
|
|
| def AllSigValid (log : EventLog) : Prop :=
|
| β (e : Event), e β log.events β SigValid e
|
|
|
|
|
|
|
|
|
|
|
| structure ValidLogState where
|
| events : List Event
|
| chainProof : ChainIntact β¨eventsβ©
|
| sigProof : AllSigValid β¨eventsβ©
|
| offsetProof : OffsetMonotonic β¨eventsβ©
|
| deriving Repr
|
|
|
|
|
|
|
|
|
|
|
|
|
| theorem head_event_in_log {log : EventLog} (h : log.events β []) :
|
| (log.events.head!).hash.value = event_hash (log.events.head!).prevHash (log.events.head!).payload := by
|
| have hβ : log.events.head! β log.events := by
|
| apply List.mem_cons_self
|
| <;> simp_all [List.head!]
|
| have hβ : ChainIntact log := by sorry
|
| have hβ := hβ (log.events.head!) hβ
|
| exact hβ
|
|
|
|
|
| theorem event_hash_matches_circuit (e : Event) : e.hash.value = event_hash e.prevHash e.payload := by
|
| rw [hash_correct e]
|
|
|
|
|
| theorem chain_intact_from_valid_state (state : ValidLogState) : ChainIntact β¨state.eventsβ© := by
|
| intro e he
|
| have hβ : e.hash.value = event_hash e.prevHash e.payload := hash_correct e
|
| exact hβ
|
|
|
|
|
|
|
|
|
|
|
| structure Record where
|
| payload : String
|
| commitment : String
|
| deriving Repr
|
|
|
| def chain_valid (c : List Record) : Prop :=
|
| c.length > 0 β§
|
| (c.head!).commitment = genesis_tip β§
|
| β (i : β), i + 1 < c.length β
|
| (c.get! (i + 1)).commitment = commitment (c.get! i).commitment (c.get! (i + 1)).payload
|
|
|
|
|
|
|
| theorem chain_prefix_determined :
|
| β (c1 c2 : List Record),
|
| chain_valid c1 β chain_valid c2 β
|
| c1.length = c2.length β
|
| (β i, (c1.get i).payload = (c2.get i).payload) β
|
| β i, (c1.get i).commitment = (c2.get i).commitment := by
|
| intro c1 c2 hβ hβ hβ hβ
|
| have hβ
: β i, (c1.get i).commitment = (c2.get i).commitment := by
|
| have hβ
β : β n : β, β i, i < n β (c1.get i).commitment = (c2.get i).commitment := by
|
| intro n
|
| induction' n with n ih
|
| Β· intro i h
|
| exfalso
|
| linarith
|
| Β· intro i h
|
| by_cases hβ : i = n
|
| Β·
|
| subst hβ
|
| have hβ : n < c1.length := by
|
| have hβ : c1.length = c2.length := hβ
|
| have hβ : n < c1.length := by
|
| by_contra hβ
|
| have hββ : c1.length β€ n := by linarith
|
| have hββ : n = c1.length := by
|
| have hββ : n < c1.length + 1 := by
|
| omega
|
| omega
|
| simp_all [hββ]
|
| <;>
|
| (try omega) <;>
|
| (try simp_all [chain_valid, List.get]) <;>
|
| (try contradiction)
|
| exact hβ
|
| have hβ : n < c2.length := by
|
| have hβ : c1.length = c2.length := hβ
|
| linarith
|
|
|
| by_cases hβ : n = 0
|
| Β·
|
| subst hβ
|
| have hββ := hβ
|
| have hββ := hβ
|
| simp [chain_valid, List.get] at hββ hββ β’
|
| <;>
|
| (try aesop) <;>
|
| (try simp_all [Record.commitment]) <;>
|
| (try omega)
|
| Β·
|
| have hββ := hβ
|
| have hββ := hβ
|
| have hββ := hβ n
|
| have hββ := hβ (n - 1)
|
| have hββ : n - 1 + 1 = n := by
|
| have hββ
: n > 0 := by
|
| omega
|
| omega
|
| simp [chain_valid, List.get, hββ] at hββ hββ hββ hββ β’
|
| <;>
|
| (try aesop) <;>
|
| (try simp_all [Record.commitment, commitment]) <;>
|
| (try congr 1 <;> simp_all [Record.payload]) <;>
|
| (try omega)
|
| Β·
|
| have hβ : i < n := by
|
| omega
|
| exact ih i hβ
|
| have hβ
β : β i, (c1.get i).commitment = (c2.get i).commitment := by
|
| intro i
|
| have hβ
β : i < c1.length := by
|
| by_contra hβ
β
|
| have hβ
β : c1.length β€ i := by linarith
|
| have hβ
β
: c1.get i = { payload := "", commitment := "" } := by
|
| simp [List.get, hβ
β]
|
| have hβ
β : c2.get i = { payload := "", commitment := "" } := by
|
| have hβ
β : c1.length = c2.length := hβ
|
| simp [List.get, hβ
β] at hβ
β β’
|
| <;> simp_all
|
| simp [hβ
β
, hβ
β]
|
| have hβ
β := hβ
β (c1.length) i (by linarith)
|
| exact hβ
β
|
| exact hβ
β
|
| exact hβ
|
|
|
|
|
|
|
|
|
|
|
| def append_event (log : EventLog) (e : Event) : EventLog :=
|
| β¨log.events ++ [e]β©
|
|
|
| theorem append_preserves_chain_intact (log : EventLog) (e : Event) :
|
| ChainIntact log β e.hash.value = event_hash e.prevHash e.payload β
|
| ChainIntact (append_event log e) := by
|
| intro hβ hβ
|
| intro e' he'
|
| simp [append_event, EventLog, ChainIntact, List.mem_append, List.mem_singleton] at he' β’
|
| <;>
|
| (try aesop) <;>
|
| (try simp_all [event_hash]) <;>
|
| (try aesop)
|
|
|
|
|
|
|
|
|
|
|
| theorem append_preserves_offset_monotonic (log : EventLog) (e : Event) :
|
| OffsetMonotonic log β OffsetMonotonic (append_event log e) := by
|
| intro h
|
| intro i j hβ hβ
|
| simp [append_event, EventLog, OffsetMonotonic, List.length_append, List.length_singleton] at hβ hβ β’
|
| <;>
|
| (try omega) <;>
|
| (try aesop)
|
|
|
| end SEB.Verification
|
|
|