src/Certificate.bend source
src/Certificate.bend on the hub · documented module
import Baseimport ./Reading.bend as Readingimport ./StateTree.bend as StateTreeimport ./History.bend as Historyimport ./Merging.bend as Mergingimport ./Store.bend as Store# Independent merge verification. The pure core re-derives everything from# entry lists: strategy known, result hash matches recomputed hash, merge# recomputation yields the same entry set, every recorded law passed and at# least one law recorded (empty evidence rejects). The shell loads the trees# named by the certificate — a tampered cert names trees whose content# contradicts its claims.# A key/value pair counts as present only when both match.def decide_entry_present(key_matches: Bool, +head_value: String, +target_value: String, tail_result: Bool) -> Bool: match key_matches: case True{}: String.eq(head_value, target_value) case False{}: tail_result# Scans entries for an exact key/value pair.def entry_present_in(+target_key: String, +target_value: String, entries: List<&2, Reading.ChainEntry>) -> Bool: match entries: case Nil{}: False{} case Con{+head_entry, remaining_entries}: decide_entry_present(String.eq(Reading.entry_key_of(head_entry), target_key), Reading.entry_value_of(head_entry), target_value, entry_present_in(target_key, target_value, remaining_entries))# Conjunction step: a missing head fails the whole check.def decide_all_present(head_present: Bool, tail_result: Bool) -> Bool: match head_present: case True{}: tail_result case False{}: False{}# Every source entry must occur in the target list.def all_present_in(source_entries: List<&2, Reading.ChainEntry>, +target_entries: List<&2, Reading.ChainEntry>) -> Bool: match source_entries: case Nil{}: True{} case Con{+head_entry, remaining_entries}: decide_all_present(entry_present_in(Reading.entry_key_of(head_entry), Reading.entry_value_of(head_entry), target_entries), all_present_in(remaining_entries, target_entries))# Set equality both directions; exact because lists are unique-keyed.def entries_equal(+first_entries: List<&2, Reading.ChainEntry>, +second_entries: List<&2, Reading.ChainEntry>) -> Bool: all_present_in(first_entries, second_entries) && all_present_in(second_entries, first_entries)# Conjunction step over law evidence.def decide_law_step(head_passed: Bool, tail_result: Bool) -> Bool: match head_passed: case True{}: tail_result case False{}: False{}# Every remaining check must have passed.def all_remaining_pass(remaining_checks: List<&2, Merging.LawCheck>) -> Bool: match remaining_checks: case Nil{}: True{} case Con{head_check, tail_checks}: decide_law_step(Merging.law_check_passed(head_check), all_remaining_pass(tail_checks))# Non-empty evidence with every check passed; empty evidence rejects.def verify_laws_step(checked_laws: List<&2, Merging.LawCheck>) -> Bool: match checked_laws: case Nil{}: False{} case Con{head_check, remaining_checks}: decide_law_step(Merging.law_check_passed(head_check), all_remaining_pass(remaining_checks))# Matching entries unlock the law-evidence check.def verify_entries_step(entries_match: Bool, +certificate: Merging.MergeCertificate) -> Bool: match entries_match: case False{}: False{} case True{}: verify_laws_step(Merging.cert_checked_laws(certificate))# A clean recomputation unlocks the entry-set check; conflicts reject.def verify_recompute_step(recomputed_outcome: Merging.MergeOutcome, +merged_entries: List<&2, Reading.ChainEntry>, +certificate: Merging.MergeCertificate) -> Bool: match recomputed_outcome: case Merging.ConflictingKeys{conflicting_keys}: False{} case Merging.MergedEntries{recomputed_entries}: verify_entries_step(entries_equal(recomputed_entries, merged_entries), certificate)# A matching result hash unlocks the merge recomputation; mismatch rejects.def verify_hash_step(hash_matches: Bool, +base_entries: List<&2, Reading.ChainEntry>, +first_entries: List<&2, Reading.ChainEntry>, +second_entries: List<&2, Reading.ChainEntry>, +merged_entries: List<&2, Reading.ChainEntry>, +certificate: Merging.MergeCertificate) -> Bool: match hash_matches: case False{}: False{} case True{}: verify_recompute_step(Merging.merge_entry_lists(base_entries, first_entries, second_entries), merged_entries, certificate)# Only the union-disjoint strategy verifies; anything else rejects.def decide_strategy_known(strategy_known: Bool, +base_entries: List<&2, Reading.ChainEntry>, +first_entries: List<&2, Reading.ChainEntry>, +second_entries: List<&2, Reading.ChainEntry>, +merged_entries: List<&2, Reading.ChainEntry>, +certificate: Merging.MergeCertificate) -> Bool: match strategy_known: case False{}: False{} case True{}: verify_hash_step(String.eq(Merging.cert_result_tree(certificate), StateTree.compute_tree_hash(merged_entries)), base_entries, first_entries, second_entries, merged_entries, certificate)# Pure verification core: re-derives strategy, hash, merge and law evidence.def verify_merge_certificate_pure(+base_entries: List<&2, Reading.ChainEntry>, +first_entries: List<&2, Reading.ChainEntry>, +second_entries: List<&2, Reading.ChainEntry>, +merged_entries: List<&2, Reading.ChainEntry>, +certificate: Merging.MergeCertificate) -> Bool: decide_strategy_known(String.eq(Merging.cert_strategy_name(certificate), "union-disjoint"), base_entries, first_entries, second_entries, merged_entries, certificate)# A present result tree unlocks the pure core; a missing one rejects.def decide_verify_result(+certificate: Merging.MergeCertificate, base_tree: StateTree.StateTreeNode, first_tree: StateTree.StateTreeNode, second_tree: StateTree.StateTreeNode, result_maybe: Maybe<&2, StateTree.StateTreeNode>) -> Bool: match result_maybe: case None{}: False{} case Some{result_tree}: verify_merge_certificate_pure(StateTree.tree_entries(base_tree), StateTree.tree_entries(first_tree), StateTree.tree_entries(second_tree), StateTree.tree_entries(result_tree), certificate)# Unpacks the second tree or rejects when missing.def decide_verify_second(+certificate: Merging.MergeCertificate, base_tree: StateTree.StateTreeNode, first_tree: StateTree.StateTreeNode, second_maybe: Maybe<&2, StateTree.StateTreeNode>, result_maybe: Maybe<&2, StateTree.StateTreeNode>) -> Bool: match second_maybe: case None{}: False{} case Some{second_tree}: decide_verify_result(certificate, base_tree, first_tree, second_tree, result_maybe)# Unpacks the first tree or rejects when missing.def decide_verify_first(+certificate: Merging.MergeCertificate, base_tree: StateTree.StateTreeNode, first_maybe: Maybe<&2, StateTree.StateTreeNode>, second_maybe: Maybe<&2, StateTree.StateTreeNode>, result_maybe: Maybe<&2, StateTree.StateTreeNode>) -> Bool: match first_maybe: case None{}: False{} case Some{first_tree}: decide_verify_second(certificate, base_tree, first_tree, second_maybe, result_maybe)# Unpacks the base tree or rejects when missing.def decide_verify_trees(+certificate: Merging.MergeCertificate, base_maybe: Maybe<&2, StateTree.StateTreeNode>, first_maybe: Maybe<&2, StateTree.StateTreeNode>, second_maybe: Maybe<&2, StateTree.StateTreeNode>, result_maybe: Maybe<&2, StateTree.StateTreeNode>) -> Bool: match base_maybe: case None{}: False{} case Some{base_tree}: decide_verify_first(certificate, base_tree, first_maybe, second_maybe, result_maybe)# Shell: loads the four trees named by the certificate and runs the core.def verify_certificate(+certificate: Merging.MergeCertificate) -> Store.Op<&2, Bool>: do Store.Op<&2, Bool>: base_tree_maybe : Maybe<&2, StateTree.StateTreeNode> <- History.read_tree_at(Merging.cert_base_commit(certificate)) first_tree_maybe : Maybe<&2, StateTree.StateTreeNode> <- History.read_tree_at(Merging.cert_first_parent(certificate)) second_tree_maybe : Maybe<&2, StateTree.StateTreeNode> <- History.read_tree_at(Merging.cert_second_parent(certificate)) result_tree_maybe : Maybe<&2, StateTree.StateTreeNode> <- History.load_tree_text(Merging.cert_result_tree(certificate)) return decide_verify_trees(certificate, base_tree_maybe, first_tree_maybe, second_tree_maybe, result_tree_maybe)