Balanced MIP-8 page commitments
induced schedule from commitment.v:
Node
/ \
Node Leaf 32
/ \
Node Leaf 8
/ \
Leaf 0 Leaf 1
balanced schedule in this file:
Node
/ \
Node Node
/ \ / \
Leaf 0 Leaf 1 Leaf 8 Leaf 32
active pair indices [0], [8], [32]:
Node
/ \
Leaf 0 Node
/ \
Leaf 8 Leaf 32
Extract the nonempty pair leaves together with their original 0-based pair
positions. The positions are not used to choose the balanced merge shape;
they are retained so leaf hash calls can still be aligned with the original
page geometry.
Fixpoint pair_entries_from
(start : nat) (pairs : list (option pair_leaf))
: list (nat × pair_leaf) :=
match pairs with
| [] ⇒ []
| Some value :: rest ⇒
(start, value) :: pair_entries_from (S start) rest
| None :: rest ⇒
pair_entries_from (S start) rest
end.
Definition active_pair_entries (slots : slot_values)
: list (nat × pair_leaf) :=
pair_entries_from 0 (pair_options slots).
(start : nat) (pairs : list (option pair_leaf))
: list (nat × pair_leaf) :=
match pairs with
| [] ⇒ []
| Some value :: rest ⇒
(start, value) :: pair_entries_from (S start) rest
| None :: rest ⇒
pair_entries_from (S start) rest
end.
Definition active_pair_entries (slots : slot_values)
: list (nat × pair_leaf) :=
pair_entries_from 0 (pair_options slots).
Split by median. For odd lengths, the right side has one more element.
Build a balanced located tree from the ordered active pair entries. fuel
is just structural recursion fuel; the exported builder below supplies
length entries. Internal node locations are balanced-tree coordinates:
depth counts median-split levels from the root, and index is the
horizontal index at that depth.
Fixpoint balanced_located_tree_from_entries_fuel
(fuel depth index : nat) (entries : list (nat × pair_leaf))
: option located_value_tree :=
match fuel with
| O ⇒
match entries with
| [(pair_index, value)] ⇒ Some (LocatedTreeLeaf pair_index value)
| _ ⇒ None
end
| S fuel' ⇒
match entries with
| [] ⇒ None
| [(pair_index, value)] ⇒ Some (LocatedTreeLeaf pair_index value)
| _ ⇒
let split := median_split entries in
match
balanced_located_tree_from_entries_fuel
fuel' (S depth) (2 × index) (firstn split entries),
balanced_located_tree_from_entries_fuel
fuel' (S depth) (2 × index + 1) (skipn split entries)
with
| Some lhs, Some rhs ⇒
Some (LocatedTreeNode depth index lhs rhs)
| _, _ ⇒ None
end
end
end.
Definition balanced_located_tree_from_entries
(entries : list (nat × pair_leaf)) : option located_value_tree :=
balanced_located_tree_from_entries_fuel (length entries) 0 0 entries.
Definition balanced_located_tree_from_slots
(slots : slot_values) : option located_value_tree :=
balanced_located_tree_from_entries (active_pair_entries slots).
Definition balanced_value_tree_from_slots
(slots : slot_values) : option value_tree :=
option_map erase_located_tree (balanced_located_tree_from_slots slots).
Section BalancedTreeDemo.
Variables (v0 v1 v8 v32 v32' : slot_word).
Let zero : slot_word := bytes32_of_N 0.
Let singleton_pair_slot (value : slot_word) : slot_values :=
[Some value; None].
Let four_leaf_slots : slot_values :=
singleton_pair_slot v0 ++
singleton_pair_slot v1 ++
repeat None 12 ++
singleton_pair_slot v8 ++
repeat None 46 ++
[Some v32; Some v32'].
Let pair0 : pair_leaf := (v0, zero).
Let pair1 : pair_leaf := (v1, zero).
Let pair8 : pair_leaf := (v8, zero).
Let pair32 : pair_leaf := (v32, v32').
Let four_leaf_tree : located_value_tree :=
LocatedTreeNode 0 0
(LocatedTreeNode 1 0
(LocatedTreeLeaf 0 pair0)
(LocatedTreeLeaf 1 pair1))
(LocatedTreeNode 1 1
(LocatedTreeLeaf 8 pair8)
(LocatedTreeLeaf 32 pair32)).
(fuel depth index : nat) (entries : list (nat × pair_leaf))
: option located_value_tree :=
match fuel with
| O ⇒
match entries with
| [(pair_index, value)] ⇒ Some (LocatedTreeLeaf pair_index value)
| _ ⇒ None
end
| S fuel' ⇒
match entries with
| [] ⇒ None
| [(pair_index, value)] ⇒ Some (LocatedTreeLeaf pair_index value)
| _ ⇒
let split := median_split entries in
match
balanced_located_tree_from_entries_fuel
fuel' (S depth) (2 × index) (firstn split entries),
balanced_located_tree_from_entries_fuel
fuel' (S depth) (2 × index + 1) (skipn split entries)
with
| Some lhs, Some rhs ⇒
Some (LocatedTreeNode depth index lhs rhs)
| _, _ ⇒ None
end
end
end.
Definition balanced_located_tree_from_entries
(entries : list (nat × pair_leaf)) : option located_value_tree :=
balanced_located_tree_from_entries_fuel (length entries) 0 0 entries.
Definition balanced_located_tree_from_slots
(slots : slot_values) : option located_value_tree :=
balanced_located_tree_from_entries (active_pair_entries slots).
Definition balanced_value_tree_from_slots
(slots : slot_values) : option value_tree :=
option_map erase_located_tree (balanced_located_tree_from_slots slots).
Section BalancedTreeDemo.
Variables (v0 v1 v8 v32 v32' : slot_word).
Let zero : slot_word := bytes32_of_N 0.
Let singleton_pair_slot (value : slot_word) : slot_values :=
[Some value; None].
Let four_leaf_slots : slot_values :=
singleton_pair_slot v0 ++
singleton_pair_slot v1 ++
repeat None 12 ++
singleton_pair_slot v8 ++
repeat None 46 ++
[Some v32; Some v32'].
Let pair0 : pair_leaf := (v0, zero).
Let pair1 : pair_leaf := (v1, zero).
Let pair8 : pair_leaf := (v8, zero).
Let pair32 : pair_leaf := (v32, v32').
Let four_leaf_tree : located_value_tree :=
LocatedTreeNode 0 0
(LocatedTreeNode 1 0
(LocatedTreeLeaf 0 pair0)
(LocatedTreeLeaf 1 pair1))
(LocatedTreeNode 1 1
(LocatedTreeLeaf 8 pair8)
(LocatedTreeLeaf 32 pair32)).
The active leaves are pair indices 0, 1, 8, and 32. Unlike the
induced tree in commitment.v, the balanced schedule merges (0,1) and
(8,32) in parallel before the final root merge.
The example lemma balanced_located_tree_four_leaf_demo proves that the
algorithm returns exactly this balanced located tree.
active leaves:
pair 0 = (v0, 0)
pair 1 = (v1, 0)
pair 8 = (v8, 0)
pair 32 = (v32, v32')
balanced located tree:
LocatedTreeNode 0 0
/ \
LocatedTreeNode 1 0 LocatedTreeNode 1 1
/ \ / \
LocatedTreeLeaf LocatedTreeLeaf LocatedTreeLeaf LocatedTreeLeaf
0 (v0, 0) 1 (v1, 0) 8 (v8, 0) 32 (v32, v32')
Example balanced_located_tree_four_leaf_demo :
balanced_located_tree_from_slots four_leaf_slots = Some four_leaf_tree.
Proof.
reflexivity.
Qed.
Let three_leaf_slots : slot_values :=
singleton_pair_slot v0 ++
repeat None 14 ++
singleton_pair_slot v8 ++
repeat None 46 ++
[Some v32; Some v32'].
Let three_leaf_tree : located_value_tree :=
LocatedTreeNode 0 0
(LocatedTreeLeaf 0 pair0)
(LocatedTreeNode 1 1
(LocatedTreeLeaf 8 pair8)
(LocatedTreeLeaf 32 pair32)).
balanced_located_tree_from_slots four_leaf_slots = Some four_leaf_tree.
Proof.
reflexivity.
Qed.
Let three_leaf_slots : slot_values :=
singleton_pair_slot v0 ++
repeat None 14 ++
singleton_pair_slot v8 ++
repeat None 46 ++
[Some v32; Some v32'].
Let three_leaf_tree : located_value_tree :=
LocatedTreeNode 0 0
(LocatedTreeLeaf 0 pair0)
(LocatedTreeNode 1 1
(LocatedTreeLeaf 8 pair8)
(LocatedTreeLeaf 32 pair32)).
With three leaves, the median split puts one leaf on the left and two on
the right.
The example lemma balanced_located_tree_three_leaf_demo proves that the
odd-size median split is reflected in the returned tree.
active leaves:
pair 0 = (v0, 0)
pair 8 = (v8, 0)
pair 32 = (v32, v32')
balanced located tree:
LocatedTreeNode 0 0
/ \
LocatedTreeLeaf LocatedTreeNode 1 1
0 (v0, 0) / \
LocatedTreeLeaf LocatedTreeLeaf
8 (v8, 0) 32 (v32, v32')
Example balanced_located_tree_three_leaf_demo :
balanced_located_tree_from_slots three_leaf_slots = Some three_leaf_tree.
Proof.
reflexivity.
Qed.
End BalancedTreeDemo.
balanced_located_tree_from_slots three_leaf_slots = Some three_leaf_tree.
Proof.
reflexivity.
Qed.
End BalancedTreeDemo.
Final seal step. Empty pages are sealed by bitmap alone; nonempty pages
seal the same bitmap with the balanced merge-tree root.
Definition balanced_root (slots : slot_values) : digest :=
match balanced_located_tree_from_slots slots with
| None ⇒ seal_empty (bitmap_to_bytes16 (slot_bitmap slots))
| Some tree ⇒
seal_nonempty
(bitmap_to_bytes16 (slot_bitmap slots))
(eval_located_tree tree)
end.
match balanced_located_tree_from_slots slots with
| None ⇒ seal_empty (bitmap_to_bytes16 (slot_bitmap slots))
| Some tree ⇒
seal_nonempty
(bitmap_to_bytes16 (slot_bitmap slots))
(eval_located_tree tree)
end.
Trace-producing version used by the binding theorem.
Definition balanced_root_with_trace (slots : slot_values) : root_trace :=
match balanced_located_tree_from_slots slots with
| None ⇒
{|
traced_root :=
seal_empty (bitmap_to_bytes16 (slot_bitmap slots));
traced_calls :=
[mk_located_call
LocSeal
(InputSealEmpty (bitmap_to_bytes16 (slot_bitmap slots)))]
|}
| Some tree ⇒
let tree_root := eval_located_tree tree in
{|
traced_root :=
seal_nonempty (bitmap_to_bytes16 (slot_bitmap slots)) tree_root;
traced_calls :=
tree_located_calls tree ++
[mk_located_call
LocSeal
(InputSealNonempty
(bitmap_to_bytes16 (slot_bitmap slots))
tree_root)]
|}
end.
End BalancedAlgorithm.
match balanced_located_tree_from_slots slots with
| None ⇒
{|
traced_root :=
seal_empty (bitmap_to_bytes16 (slot_bitmap slots));
traced_calls :=
[mk_located_call
LocSeal
(InputSealEmpty (bitmap_to_bytes16 (slot_bitmap slots)))]
|}
| Some tree ⇒
let tree_root := eval_located_tree tree in
{|
traced_root :=
seal_nonempty (bitmap_to_bytes16 (slot_bitmap slots)) tree_root;
traced_calls :=
tree_located_calls tree ++
[mk_located_call
LocSeal
(InputSealNonempty
(bitmap_to_bytes16 (slot_bitmap slots))
tree_root)]
|}
end.
End BalancedAlgorithm.
Correctness
Section BalancedCorrectness.
Lemma Nat_div2_le n :
Nat.div2 n ≤ n.
Lemma pair_entries_from_values start pairs :
map snd (pair_entries_from start pairs) =
pair_option_values pairs.
Lemma pair_entries_from_indices_same start pairs pairs' :
pair_option_bitmap pairs = pair_option_bitmap pairs' →
map fst (pair_entries_from start pairs) =
map fst (pair_entries_from start pairs').
Lemma active_pair_entries_values slots :
map snd (active_pair_entries slots) =
active_pair_values slots.
Lemma active_pair_entries_indices_same slots slots' :
slot_bitmap slots = slot_bitmap slots' →
map fst (active_pair_entries slots) =
map fst (active_pair_entries slots').
Lemma balanced_located_tree_from_entries_values_fuel
fuel depth index entries tree :
balanced_located_tree_from_entries_fuel
fuel depth index entries = Some tree →
located_tree_values tree = map snd entries.
Lemma balanced_located_tree_from_entries_values entries tree :
balanced_located_tree_from_entries entries = Some tree →
located_tree_values tree = map snd entries.
Lemma balanced_located_tree_from_entries_some_fuel fuel depth index entries :
length entries ≤ fuel →
entries ≠ [] →
∃ tree,
balanced_located_tree_from_entries_fuel
fuel depth index entries = Some tree.
Lemma balanced_located_tree_from_entries_some entries :
entries ≠ [] →
∃ tree, balanced_located_tree_from_entries entries = Some tree.
Lemma balanced_located_tree_from_entries_same_shape_fuel
fuel depth index entries entries' tree tree' :
map fst entries = map fst entries' →
balanced_located_tree_from_entries_fuel
fuel depth index entries = Some tree →
balanced_located_tree_from_entries_fuel
fuel depth index entries' = Some tree' →
same_located_tree_shape tree tree'.
Lemma balanced_located_tree_from_entries_same_shape entries entries' tree tree' :
map fst entries = map fst entries' →
balanced_located_tree_from_entries entries = Some tree →
balanced_located_tree_from_entries entries' = Some tree' →
same_located_tree_shape tree tree'.
Lemma balanced_located_tree_from_slots_values slots tree :
balanced_located_tree_from_slots slots = Some tree →
located_tree_values tree = active_pair_values slots.
Lemma balanced_located_tree_from_slots_empty_values slots :
balanced_located_tree_from_slots slots = None →
active_pair_values slots = [].
Lemma balanced_located_tree_from_slots_same_shape
slots slots' tree tree' :
slot_bitmap slots = slot_bitmap slots' →
balanced_located_tree_from_slots slots = Some tree →
balanced_located_tree_from_slots slots' = Some tree' →
same_located_tree_shape tree tree'.
Theorem balanced_root_with_trace_root slots :
(balanced_root_with_trace slots).(traced_root) = balanced_root slots.
Theorem Balanced_Root_injective_no_collision slots slots' :
no_aligned_collisions
(balanced_root_with_trace slots)
(balanced_root_with_trace slots') →
balanced_root slots = balanced_root slots' →
normalize_slots slots = normalize_slots slots'.
Theorem Balanced_Root_binding_break_extracts_aligned_collision slots slots' :
(balanced_root_with_trace slots).(traced_root) =
(balanced_root_with_trace slots').(traced_root) →
normalize_slots slots ≠ normalize_slots slots' →
exists_aligned_collision
(balanced_root_with_trace slots)
(balanced_root_with_trace slots').
Theorem Balanced_Root_distinct_no_collision slots slots' :
no_aligned_collisions
(balanced_root_with_trace slots)
(balanced_root_with_trace slots') →
normalize_slots slots ≠ normalize_slots slots' →
balanced_root slots ≠ balanced_root slots'.
End BalancedCorrectness.
Lemma Nat_div2_le n :
Nat.div2 n ≤ n.
Lemma pair_entries_from_values start pairs :
map snd (pair_entries_from start pairs) =
pair_option_values pairs.
Lemma pair_entries_from_indices_same start pairs pairs' :
pair_option_bitmap pairs = pair_option_bitmap pairs' →
map fst (pair_entries_from start pairs) =
map fst (pair_entries_from start pairs').
Lemma active_pair_entries_values slots :
map snd (active_pair_entries slots) =
active_pair_values slots.
Lemma active_pair_entries_indices_same slots slots' :
slot_bitmap slots = slot_bitmap slots' →
map fst (active_pair_entries slots) =
map fst (active_pair_entries slots').
Lemma balanced_located_tree_from_entries_values_fuel
fuel depth index entries tree :
balanced_located_tree_from_entries_fuel
fuel depth index entries = Some tree →
located_tree_values tree = map snd entries.
Lemma balanced_located_tree_from_entries_values entries tree :
balanced_located_tree_from_entries entries = Some tree →
located_tree_values tree = map snd entries.
Lemma balanced_located_tree_from_entries_some_fuel fuel depth index entries :
length entries ≤ fuel →
entries ≠ [] →
∃ tree,
balanced_located_tree_from_entries_fuel
fuel depth index entries = Some tree.
Lemma balanced_located_tree_from_entries_some entries :
entries ≠ [] →
∃ tree, balanced_located_tree_from_entries entries = Some tree.
Lemma balanced_located_tree_from_entries_same_shape_fuel
fuel depth index entries entries' tree tree' :
map fst entries = map fst entries' →
balanced_located_tree_from_entries_fuel
fuel depth index entries = Some tree →
balanced_located_tree_from_entries_fuel
fuel depth index entries' = Some tree' →
same_located_tree_shape tree tree'.
Lemma balanced_located_tree_from_entries_same_shape entries entries' tree tree' :
map fst entries = map fst entries' →
balanced_located_tree_from_entries entries = Some tree →
balanced_located_tree_from_entries entries' = Some tree' →
same_located_tree_shape tree tree'.
Lemma balanced_located_tree_from_slots_values slots tree :
balanced_located_tree_from_slots slots = Some tree →
located_tree_values tree = active_pair_values slots.
Lemma balanced_located_tree_from_slots_empty_values slots :
balanced_located_tree_from_slots slots = None →
active_pair_values slots = [].
Lemma balanced_located_tree_from_slots_same_shape
slots slots' tree tree' :
slot_bitmap slots = slot_bitmap slots' →
balanced_located_tree_from_slots slots = Some tree →
balanced_located_tree_from_slots slots' = Some tree' →
same_located_tree_shape tree tree'.
Theorem balanced_root_with_trace_root slots :
(balanced_root_with_trace slots).(traced_root) = balanced_root slots.
Theorem Balanced_Root_injective_no_collision slots slots' :
no_aligned_collisions
(balanced_root_with_trace slots)
(balanced_root_with_trace slots') →
balanced_root slots = balanced_root slots' →
normalize_slots slots = normalize_slots slots'.
Theorem Balanced_Root_binding_break_extracts_aligned_collision slots slots' :
(balanced_root_with_trace slots).(traced_root) =
(balanced_root_with_trace slots').(traced_root) →
normalize_slots slots ≠ normalize_slots slots' →
exists_aligned_collision
(balanced_root_with_trace slots)
(balanced_root_with_trace slots').
Theorem Balanced_Root_distinct_no_collision slots slots' :
no_aligned_collisions
(balanced_root_with_trace slots)
(balanced_root_with_trace slots') →
normalize_slots slots ≠ normalize_slots slots' →
balanced_root slots ≠ balanced_root slots'.
End BalancedCorrectness.
This page has been generated by coqdoc