@@ -5,7 +5,7 @@ Authors: Quang Dao
55-/
66
77import VCVio
8- import ArkLib.Data.Math.Operations
8+ import ArkLib.Data.Math.Basic
99import ArkLib.CommitmentScheme.Basic
1010import Mathlib.Data.Vector.Snoc
1111
@@ -181,72 +181,112 @@ def verifyProof {n : ℕ} (i : Fin (2 ^ n)) (leaf : α) (root : α) (proof : Lis
181181 let putative_root ← getPutativeRoot α i leaf proof
182182 guard (putative_root = root)
183183
184- -- Belongs in VCVio, not sure if its already there somewhwere
185- def implement_with_function (hash : α × α -> α) : QueryImpl (spec α) (StateT Unit (OracleComp (emptySpec))) where
186- impl q := match q with
187- | ⟨_, ⟨left, right⟩⟩ =>
188- do
189- let out := hash (left, right)
190- return out
191184
185+ theorem buildLayer_neverFails (α : Type ) [inst : DecidableEq α] [inst_1 : SelectableType α]
186+ (preexisting_cache : (spec α).QueryCache) (n : ℕ)
187+ (leaves : List.Vector α (2 ^ (n + 1 ))) :
188+ ((simulateQ randomOracle (buildLayer α n leaves)).run preexisting_cache).neverFails := by
189+ simp_rw [buildLayer]
190+ simp [neverFails_query_bind]
191+ -- I now require a "neverFails_mmap_iff" lemma, but I don't see one in VCVio.
192+ -- Feels like evidence for avoiding Vector-based merkle trees in favor of inductive-based ones.
193+ sorry
194+
195+ /--
196+ Building a Merkle tree never results in failure
197+ (no matter what queries have already been made to the oracle before it runs).
198+ -/
199+ theorem buildMerkleTree_neverFails (α : Type ) [DecidableEq α] [SelectableType α] {n : ℕ}
200+ (leaves : List.Vector α (2 ^ n)) (preexisting_cache : (spec α).QueryCache) :
201+ ((simulateQ randomOracle (buildMerkleTree α n leaves)).run preexisting_cache).neverFails := by
202+ -- It feels like there should be some kind of tactic that inspects the structure of the
203+ -- `buildMerkleTree` definition to see that it never even mentions failure,
204+ -- and therefore can't fail.
205+ induction n generalizing preexisting_cache with
206+ | zero =>
207+ simp [buildMerkleTree, getRoot, generateProof, verifyProof, getPutativeRoot]
208+ | succ n ih =>
209+ simp [buildMerkleTree, neverFails_bind_iff]
210+ constructor
211+ · exact buildLayer_neverFails α preexisting_cache n leaves
212+ · intro next_leaves next_cache h_mem_support
213+ apply ih
192214
193215/-- Completeness theorem for Merkle trees: for any full binary tree with `2 ^ n` leaves, and for any
194- index `i`, the verifier accepts the opening proof at index `i` generated by the prover. -/
195- theorem completeness {n : ℕ} (leaves : List.Vector α (2 ^ n)) (i : Fin (2 ^ n)) (hash : α × α -> α) :
196- ((do
216+ index `i`, the verifier accepts the opening proof at index `i` generated by the prover.
217+ -/
218+ theorem completeness [SelectableType α] {n : ℕ}
219+ (leaves : List.Vector α (2 ^ n)) (i : Fin (2 ^ n)) (hash : α × α -> α)
220+ (preexisting_cache : (spec α).QueryCache) :
221+ (((do
197222 let cache ← buildMerkleTree α n leaves
198223 let proof := generateProof α i cache
199224 let verif ← verifyProof α i leaves[i] (getRoot α cache) proof).simulateQ
200- (implement_with_function α hash)
201- ()).neverFails := by
202- induction n with
203- | zero =>
204- simp [buildMerkleTree, getRoot, generateProof, verifyProof, getPutativeRoot]
205- have : i = 0 := by aesop
206- subst i
207- simp [Fin.instGetElemFinVal]
208- -- TODO: the below is not necessary once `neverFails` lemmas are (re-)added
209- unfold neverFails neverFailsWhen allWhen OracleComp.construct FreeMonad.construct
210- simp [pure, StateT.pure, OptionT.pure, OptionT.mk]
211- | succ n ih =>
212- -- simp_all [Fin.getElem_fin, Vector.getElem_eq_get, Fin.eta, getRoot, Fin.val_zero,
213- -- Nat.pow_zero, Fin.zero_eta, Vector.get_zero, bind_pure_comp, id_map', probFailure_eq_zero_iff,
214- -- neverFails_bind_iff, buildMerkleTree, generateProof, LawfulMonad.bind_assoc, bind_map_left,
215- -- Cache.upper_cons, Cache.leaves_cons]
216- -- refine ⟨?_, ?_ ⟩
217- -- ·
218- simp [buildLayer, simulateQ, simulateQ, implement_with_function]
219- sorry
220-
221- -- · intro newLeaves h_newLeaves
222- -- let i' : Fin (2 ^ n) := i.val / 2
223- -- specialize ih newLeaves i'
224- -- rcases ih with ⟨ih', ih⟩
225- -- sorry
226- -- refine ⟨?_, ?_ ⟩
227- -- · exact ih'
228- -- · intro cache h_cache
229- -- specialize ih cache h_cache
230- -- unfold verifyProof
231- -- simp only [guard_eq, neverFails_bind_iff]
232- -- unfold verifyProof at ih
233- -- simp only [guard_eq, neverFails_bind_iff] at ih
234- -- rcases ih with ⟨ih_getroot, ih_cmp⟩
235- -- refine ⟨?_, ?_ ⟩
236- -- · -- I think this just needs a simple lemma about `getPutativeRoot`
237- -- sorry
238- -- · intro root h_root
239- -- specialize ih_cmp root
240- -- have : root ∈ (getPutativeRoot α i'
241- -- (newLeaves.get i') (generateProof α i' cache)).support := by
242-
243- -- sorry
244- -- specialize ih_cmp this
245- -- simp [ apply_ite ] at ih_cmp
246- -- rw [ ih_cmp ]
247- -- simp [ apply_ite ]
248- -- simp [ Cache.cons ]
249- -- sorry
225+ (randomOracle)).run preexisting_cache).neverFails := by
226+ simp [neverFails_bind_iff]
227+ constructor
228+ · -- buildMerkleTree never fails
229+ exact buildMerkleTree_neverFails α leaves preexisting_cache
230+ · -- verifyProof never fails on the output of generateProof after buildMerkleTree
231+ intros merkle_tree_cache query_cache h_mem_support
232+ -- Need a theorem to characterize
233+ -- `((simulateQ randomOracle (buildMerkleTree α n leaves)).run preexisting_cache).support`
234+ -- i.e.
235+ -- - All merkle_tree_cache parent-child relationships are in the query_cache
236+ -- - Everything in the preexisting_cache is in the query_cache
237+ -- - Nothing else is in the query_cache
238+ sorry
239+
240+
241+
242+
243+
244+
245+ -- induction n with
246+ -- | zero =>
247+ -- simp [buildMerkleTree, getRoot, generateProof, verifyProof, getPutativeRoot]
248+ -- have : i = 0 := by aesop
249+ -- subst i
250+ -- simp [ Fin.instGetElemFinVal ]
251+ -- | succ n ih =>
252+ -- -- simp_all [Fin.getElem_fin, Vector.getElem_eq_get, Fin.eta, getRoot, Fin.val_zero,
253+ -- -- Nat.pow_zero, Fin.zero_eta, Vector.get_zero, bind_pure_comp, id_map', probFailure_eq_zero_iff,
254+ -- -- neverFails_bind_iff, buildMerkleTree, generateProof, LawfulMonad.bind_assoc, bind_map_left,
255+ -- -- Cache.upper_cons, Cache.leaves_cons]
256+ -- -- refine ⟨?_, ?_ ⟩
257+ -- -- ·
258+ -- simp [buildLayer, simulateQ, simulateQ, implement_with_function]
259+ -- sorry
260+
261+ -- -- · intro newLeaves h_newLeaves
262+ -- -- let i' : Fin (2 ^ n) := i.val / 2
263+ -- -- specialize ih newLeaves i'
264+ -- -- rcases ih with ⟨ih', ih⟩
265+ -- -- sorry
266+ -- -- refine ⟨?_, ?_ ⟩
267+ -- -- · exact ih'
268+ -- -- · intro cache h_cache
269+ -- -- specialize ih cache h_cache
270+ -- -- unfold verifyProof
271+ -- -- simp only [guard_eq, neverFails_bind_iff]
272+ -- -- unfold verifyProof at ih
273+ -- -- simp only [guard_eq, neverFails_bind_iff] at ih
274+ -- -- rcases ih with ⟨ih_getroot, ih_cmp⟩
275+ -- -- refine ⟨?_, ?_ ⟩
276+ -- -- · -- I think this just needs a simple lemma about `getPutativeRoot`
277+ -- -- sorry
278+ -- -- · intro root h_root
279+ -- -- specialize ih_cmp root
280+ -- -- have : root ∈ (getPutativeRoot α i'
281+ -- -- (newLeaves.get i') (generateProof α i' cache)).support := by
282+
283+ -- -- sorry
284+ -- -- specialize ih_cmp this
285+ -- -- simp [ apply_ite ] at ih_cmp
286+ -- -- rw [ ih_cmp ]
287+ -- -- simp [ apply_ite ]
288+ -- -- simp [ Cache.cons ]
289+ -- -- sorry
250290
251291
252292-- theorem soundness (i : Fin (2 ^ n)) (leaf : α) (proof : Vector α n) :
0 commit comments