Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keccak verification and InputHash determinism #48

Draft
wants to merge 85 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
88671f8
Wip
Eagle941 Oct 16, 2023
a070614
Updated provenzk
Eagle941 Oct 16, 2023
af764b2
Wip
Eagle941 Oct 19, 2023
54550a8
Added proof insertion_is_set_circuit
Eagle941 Oct 19, 2023
734c520
deletion circuit proof
Eagle941 Oct 21, 2023
ee02265
Added deletion circuit theorems and refactoring
Eagle941 Oct 21, 2023
0d2dc14
Wip
Eagle941 Oct 22, 2023
3df34d3
Wip
Eagle941 Oct 23, 2023
eb5310f
theory of functional gadgets
kustosz Oct 24, 2023
1783a8e
Wip
Eagle941 Oct 24, 2023
2b0644a
wip
Eagle941 Oct 24, 2023
1a54f6e
Wip
Eagle941 Oct 24, 2023
735364a
Wip
Eagle941 Oct 25, 2023
6c4f200
keccak is functional
kustosz Oct 26, 2023
60c097a
checkpoint
kustosz Oct 26, 2023
26f2f0b
progress on uncps
kustosz Oct 26, 2023
ee3a919
WiP
Eagle941 Oct 27, 2023
acf592c
Wip
Eagle941 Oct 27, 2023
ac15034
Wip
Eagle941 Oct 27, 2023
46cc189
Proven deletion_round_prep_uncps
Eagle941 Oct 27, 2023
d394aee
Updated dependencies
Eagle941 Oct 27, 2023
6901f1d
Refactoring
Eagle941 Oct 27, 2023
319c574
Refactoring
Eagle941 Oct 29, 2023
9ae3987
Wip
Eagle941 Oct 29, 2023
0af39dd
After deletion all zeroes
Eagle941 Oct 30, 2023
251b892
Proof refactoring
Eagle941 Oct 30, 2023
d77df03
checkpoint
kustosz Oct 31, 2023
01f6e78
Wip
Eagle941 Nov 1, 2023
ec6bf00
WiP
Eagle941 Nov 2, 2023
a0ca860
cleanup binary proofs
kustosz Nov 2, 2023
acf336d
witness-relevant determinism
kustosz Nov 2, 2023
092cc94
Deletion theorems
Eagle941 Nov 3, 2023
a4bef57
Refactoring deletion circuit proofs
Eagle941 Nov 3, 2023
6c842c9
Moving most important theorems to main file
Eagle941 Nov 3, 2023
77cd96d
Updated provenzk
Eagle941 Nov 3, 2023
6873db9
Split semantic equivalence
Eagle941 Nov 3, 2023
6300bc6
Cleaned comments
Eagle941 Nov 3, 2023
b11f2ee
Refactoring
Eagle941 Nov 3, 2023
c0df4cc
Refactoring insertion circuit
Eagle941 Nov 4, 2023
dd03c59
New insertion proof
Eagle941 Nov 4, 2023
bf17ba0
New insertion proof wip
Eagle941 Nov 5, 2023
8f5b3f9
progress
kustosz Nov 5, 2023
07358dc
Wip
Eagle941 Nov 5, 2023
2c83c27
Wip
Eagle941 Nov 6, 2023
7a2274e
Deletion keccak done
kustosz Nov 6, 2023
05ee70d
Wip
Eagle941 Nov 6, 2023
567e8df
wip
Eagle941 Nov 7, 2023
04afc67
Wip
Eagle941 Nov 7, 2023
cefec3e
Added full insertion circuit proof
Eagle941 Nov 7, 2023
e22db2e
finish both keccaks
kustosz Nov 7, 2023
1a91e6c
WiP
Eagle941 Nov 7, 2023
d027d38
checkpoint
kustosz Nov 7, 2023
db85fd5
Finished
Eagle941 Nov 7, 2023
2d97a0b
Cleaned True
Eagle941 Nov 7, 2023
c040a7a
Cleanup
Eagle941 Nov 7, 2023
cd1913a
Wip
Eagle941 Nov 7, 2023
24da1eb
Wip
Eagle941 Nov 7, 2023
03a7a0d
Wip
Eagle941 Nov 8, 2023
5c4c47f
Replaced variable
Eagle941 Nov 8, 2023
2a15bfe
Removed variable for Prime argument
Eagle941 Nov 9, 2023
d92229b
Update provenzk
Eagle941 Nov 9, 2023
3bd9640
Added nat and fin merkle tree conversions
Eagle941 Nov 9, 2023
f9e528d
Completed before_insertion_all_zeroes_batch'
Eagle941 Nov 9, 2023
f7ac210
Updated before_insertion_all_zeroes_batch
Eagle941 Nov 9, 2023
e1a52db
Theorems for deletion property
Eagle941 Nov 11, 2023
0513a2d
Wip
Eagle941 Nov 12, 2023
1f7c49d
fix
kustosz Nov 12, 2023
45efe72
Wip
Eagle941 Nov 13, 2023
fe5f7fb
Updated deletion proof
Eagle941 Nov 15, 2023
2ac2c12
Removed commented code
Eagle941 Nov 15, 2023
01ffdd6
Refactoring
Eagle941 Nov 15, 2023
10cccf8
Rebased solution
Eagle941 Nov 16, 2023
e9af663
Updated provenzk version
Eagle941 Nov 28, 2023
0d16dee
Updated provenzk
Eagle941 Nov 29, 2023
828ac04
x
kustosz Jan 5, 2024
82ffeed
finish insertion functionally
kustosz Jan 11, 2024
f0421b1
clean up insertion
kustosz Jan 11, 2024
bbac388
progress
kustosz Jan 16, 2024
861d30f
progress
kustosz Jan 17, 2024
6de3cce
progress
kustosz Jan 18, 2024
95750f4
.
kustosz Jan 26, 2024
685e9a3
.
kustosz Jan 26, 2024
b81727e
.
kustosz Jan 26, 2024
4541063
progress
kustosz Jan 28, 2024
e46580c
.
kustosz Jan 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions formal-verification/FormalVerification/BinaryDecompositions.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import FormalVerification
import FormalVerification.Common
import FormalVerification.ReducednessCheck
import ProvenZk

open SemaphoreMTB (F Order)

lemma ReducedToBinary_256_iff_Fin_toBitsLE {f : F} {v : Vector F 256}:
Gates.to_binary f 256 v ∧ SemaphoreMTB.ReducedModRCheck_256 v ↔
v = (Fin.toBitsLE ⟨f.val, Nat.lt_trans (Fin.is_lt f) (by decide)⟩).map Bool.toZMod := by
rw [Gates.to_binary_iff_eq_Fin_ofBitsLE]
apply Iff.intro
. intro ⟨bin, red⟩
rcases bin with ⟨v, a, b⟩
subst_vars
rw [ReducedModRCheck_256_semantics] at red
have {h} : Fin.mk (ZMod.val ((Fin.ofBitsLE v).val : F)) h = Fin.ofBitsLE v := by
simp [ZMod.val_cast_of_lt, red]
simp [this]
. rintro ⟨_⟩
simp [ReducedModRCheck_256_semantics, ZMod.val_lt]

def rev_ix_256 (i : Fin 256): Fin 256 := 248 - (i / 8) * 8 + i % 8
def rev_ix_32 (i : Fin 32): Fin 32 := 24 - (i / 8) * 8 + i % 8

theorem rev_ix_256_surj : Function.Surjective rev_ix_256 := by
intro i
exists rev_ix_256 i
revert i
decide

theorem rev_ix_32_surj : Function.Surjective rev_ix_32 := by
intro i
exists rev_ix_32 i
revert i
decide

theorem ToReducedBigEndian_256_uncps {f k}:
SemaphoreMTB.ToReducedBigEndian_256 f k ↔ k (Vector.permute rev_ix_256 ((Fin.toBitsLE ⟨f.val, Nat.lt_trans (Fin.is_lt f) (by decide)⟩).map Bool.toZMod)) := by
unfold SemaphoreMTB.ToReducedBigEndian_256
conv =>
pattern _ ::ᵥ _
change Vector.permute rev_ix_256 gate_0
apply Iff.intro
. intro ⟨g, a, b, c⟩
rw [ReducedToBinary_256_iff_Fin_toBitsLE.mp ⟨a, b⟩] at c
assumption
. intro _
simp_rw [←and_assoc, ReducedToBinary_256_iff_Fin_toBitsLE]
simp [*]

theorem ToReducedBigEndian_32_uncps {f k}:
SemaphoreMTB.ToReducedBigEndian_32 f k ↔ ∃(h : f.val < 2^32), k (Vector.permute rev_ix_32 ((Fin.toBitsLE ⟨f.val, h⟩).map Bool.toZMod)) := by
unfold SemaphoreMTB.ToReducedBigEndian_32
unfold SemaphoreMTB.ReducedModRCheck_32
conv =>
pattern _ ::ᵥ _
change Vector.permute rev_ix_32 gate_0
simp_rw [Gates.to_binary_iff_eq_fin_to_bits_le_of_pow_length_lt]
apply Iff.intro
. rintro ⟨_, ⟨_, ⟨_⟩⟩, _, cont⟩
simp [*]
. rintro ⟨_, _⟩
simp [*]

theorem FromBinaryBigEndian_256_uncps {f k}:
SemaphoreMTB.FromBinaryBigEndian_256 (Vector.map Bool.toZMod f) k ↔ k (Fin.ofBitsLE (Vector.permute rev_ix_256 f)).val := by
unfold SemaphoreMTB.FromBinaryBigEndian_256
conv =>
pattern _ ::ᵥ _
change Vector.permute rev_ix_256 (f.map Bool.toZMod)
simp [←Vector.map_permute, Gates.from_binary_iff_eq_ofBitsLE_mod_order]
12 changes: 12 additions & 0 deletions formal-verification/FormalVerification/Common.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import FormalVerification
import ProvenZk.Binary
import ProvenZk.Hash
import ProvenZk.Merkle
import ProvenZk.Ext.Vector

def Bn256_Fr : Nat := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
axiom bn256_Fr_prime : Nat.Prime Bn256_Fr
instance : Fact (Nat.Prime SemaphoreMTB.Order) := Fact.mk (by apply bn256_Fr_prime)

abbrev D := 30
abbrev B := 4
206 changes: 206 additions & 0 deletions formal-verification/FormalVerification/Deletion.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
import ProvenZk

import FormalVerification
import FormalVerification.Common
import FormalVerification.Poseidon

import FormalVerification.MerkleProofs

open SemaphoreMTB (F Order)

open SemaphoreMTB renaming DeletionRound_30_30 → gDeletionRound
open SemaphoreMTB renaming DeletionProof_4_4_30_4_4_30 → gDeletionProof
open SemaphoreMTB renaming VerifyProof_31_30 → gVerifyProof

namespace Deletion

def deletionRoundSemantics (Index Item : F) (Tree : MerkleTree F poseidon₂ D) (Proof : Vector F D) (k : MerkleTree F poseidon₂ D → Prop): Prop :=
if Index.val < 2 ^ (D + 1)
then if h : Index.val < 2 ^ D
then Tree.itemAtFin ⟨Index.val, h⟩ = Item ∧
Tree.proofAtFin ⟨Index.val, h⟩ = Proof.reverse ∧
k (Tree.setAtFin ⟨Index.val, h⟩ 0)
else k Tree
else False

theorem deletionRoundCircuit_eq_deletionRoundSemantics [Fact (CollisionResistant poseidon₂)]:
gDeletionRound tree.root index item proof k ↔ deletionRoundSemantics index item tree proof (fun t => k t.root) := by
unfold gDeletionRound
unfold deletionRoundSemantics
rw [Vector.exists_succ_iff_exists_snoc]
simp only [Vector.getElem_snoc_before_length, Vector.getElem_snoc_at_length]
conv =>
pattern (occs := *) _ ::ᵥ _
. change item ::ᵥ Vector.ofFn proof.get
. change Vector.ofFn vs.get
. change 0 ::ᵥ Vector.ofFn proof.get
simp_rw [Vector.ofFn_get, Gates.to_binary_iff_eq_fin_to_bits_le_of_pow_length_lt]
unfold Fin.toBitsLE
unfold Fin.toBitsBE
cases Decidable.em (index.val < 2^(D+1)) with
| inl hlt =>
cases Nat.lt_or_ge index.val (2^D) with
| inl hlt =>
simp [*, VerifyProof_uncps', sub_eq_zero, MerkleTree.root_setAtFin_eq_recoverAtFin]
apply Iff.intro <;> {
intros; casesm* _ ∧ _; simp [*] at *; assumption
}
| inr hge =>
have : ¬index.val < 2 ^ D := by linarith
simp [*, VerifyProof_uncps, sub_eq_zero]
| inr hge => simp [*]

def deletionRoundsSemantics {b : Nat}
(indices : Vector F b)
(items : Vector F b)
(proofs : Vector (Vector F D) b)
(tree : MerkleTree F poseidon₂ D)
(k : F → Prop): Prop := match b with
| Nat.zero => k tree.root
| Nat.succ _ =>
deletionRoundSemantics (indices.head) (items.head) tree (proofs.head) (fun t => deletionRoundsSemantics indices.tail items.tail proofs.tail t k)

theorem deletionProofCircuit_eq_deletionRoundsSemantics [Fact (CollisionResistant poseidon₂)]:
gDeletionProof indices tree.root idComms proofs k ↔ deletionRoundsSemantics indices idComms proofs tree k := by
unfold gDeletionProof
repeat unfold deletionRoundsSemantics
repeat (
cases indices using Vector.casesOn; rename_i _ indices
cases idComms using Vector.casesOn; rename_i _ idComms
cases proofs using Vector.casesOn; rename_i _ proofs
)
simp_rw [deletionRoundCircuit_eq_deletionRoundSemantics]
rfl

def treeTransformationSemantics {B : ℕ}
(tree : MerkleTree F poseidon₂ D)
(indices : Vector F B): Option (MerkleTree F poseidon₂ D) := match B with
| 0 => some tree
| _ + 1 => if h : indices.head.val < 2 ^ D
then treeTransformationSemantics (tree.setAtFin ⟨indices.head.val, h⟩ 0) indices.tail
else if indices.head.val < 2 ^ (D + 1)
then treeTransformationSemantics tree indices.tail
else none

theorem deletionRounds_rootTransformation {B : ℕ} {indices idComms : Vector F B} {proofs : Vector (Vector F D) B} {tree : MerkleTree F poseidon₂ D} {k : F → Prop}:
deletionRoundsSemantics indices idComms proofs tree k →
∃postTree, treeTransformationSemantics tree indices = some postTree ∧ k postTree.root := by
intro hp
induction B generalizing tree with
| zero => exists tree
| succ B ih =>
unfold deletionRoundsSemantics at hp
unfold deletionRoundSemantics at hp
split at hp
. split at hp
. rcases hp with ⟨-, -, hp⟩
replace hp := ih hp
unfold treeTransformationSemantics
simp [*]
. unfold treeTransformationSemantics
replace hp := ih hp
simp [*]
. contradiction

theorem treeTransform_get_absent {B : ℕ} {i : F} {indices : Vector F B} {tree tree' : MerkleTree F poseidon₂ D}:
treeTransformationSemantics tree indices = some tree' → i ∉ indices → tree'[i.val]? = tree[i.val]? := by
intro hp hn
induction B generalizing tree tree' with
| zero => unfold treeTransformationSemantics at hp; injection hp; simp [*]
| succ B ih =>
unfold treeTransformationSemantics at hp
have i_tail : i ∉ indices.tail := by
intro h
apply hn
apply Vector.mem_of_mem_tail
assumption
split at hp
. replace hp := ih hp i_tail
rw [hp]; clear hp
cases Nat.lt_or_ge i.val (2^D) with
| inl _ =>
repeat rw [getElem?_eq_some_getElem_of_valid_index] <;> try assumption
apply congrArg
apply MerkleTree.itemAtFin_setAtFin_invariant_of_neq
intro hp
apply hn
injection hp with hp
cases (Fin.eq_of_veq hp)
apply Vector.head_mem
| inr _ =>
repeat rw [getElem?_none_of_invalid_index]
all_goals (apply not_lt_of_ge; assumption)
. split at hp
. exact ih hp i_tail
. contradiction

theorem treeTranform_get_present {B : ℕ} {i : F} {indices : Vector F B} {tree tree' : MerkleTree F poseidon₂ D}:
treeTransformationSemantics tree indices = some tree' → i ∈ indices → tree'[i.val]! = 0 := by
intro hp hi
induction B generalizing tree tree' with
| zero => cases indices using Vector.casesOn; cases hi
| succ B ih =>
unfold treeTransformationSemantics at hp
cases indices using Vector.casesOn; rename_i hix tix
split at hp
. rename_i range
cases Decidable.em (i ∈ tix.toList) with
| inl h => exact ih hp h
| inr h =>
rw [getElem!_eq_getElem?_get!]
rw [treeTransform_get_absent hp h]
cases eq_or_ne i hix with
| inl heq =>
cases heq
rw [getElem?_eq_some_getElem_of_valid_index] <;> try exact range
simp [getElem]
| inr hne => cases hi <;> contradiction
. rename_i invalid
cases List.eq_or_ne_mem_of_mem hi with
| inl heq =>
rw [getElem!_eq_getElem?_get!, getElem?_none_of_invalid_index]
. rfl
. rw [heq]; exact invalid
| inr h =>
rcases h with ⟨-, range⟩
split at hp
. exact ih hp range
. contradiction

theorem exists_assignment {B : ℕ} {indices : Vector F B} {tree : MerkleTree F poseidon₂ D} (ixesOk : ∀i ∈ indices, i.val < 2 ^ (D+1)):
∃items proofs postRoot, deletionRoundsSemantics indices items proofs tree (fun t => t = postRoot):= by
induction B generalizing tree with
| zero => simp [deletionRoundsSemantics]
| succ B ih =>
cases indices using Vector.casesOn with | cons i indices =>
simp [deletionRoundsSemantics, deletionRoundSemantics, ixesOk]
split
. have := ih (indices := indices) (tree := tree.setAtFin ⟨i.val, by assumption⟩ 0) (by
intro i hi
apply ixesOk
apply Vector.mem_of_mem_tail
simp
exact hi
)
rcases this with ⟨items, proofs, postRoot, h⟩
rw [Vector.exists_succ_iff_exists_cons]
apply Exists.intro
exists items
rw [Vector.exists_succ_iff_exists_cons]
apply Exists.intro
exists proofs
exists postRoot
simp [←Vector.reverse_eq]
exact ⟨by rfl, by rfl, h⟩
. have := ih (indices := indices) (tree := tree) (by
intro i hi
apply ixesOk
apply Vector.mem_of_mem_tail
simp
exact hi
)
rcases this with ⟨items, proofs, h⟩
exists (0 ::ᵥ items)
exists (Vector.replicate D 0 ::ᵥ proofs)

end Deletion
Loading