Merkle–Damgård construction
DefinitionChaining value of a reversed block list#✓fully proved
Let \(h : S \times B \to S\) be a compression function and \(iv \in S\) an initial value. The chaining value of a list of blocks given last block first is defined recursively: the empty list has chaining value \(iv\), and a list with first entry \(x\) followed by a list \(xs\) has chaining value \(h(c, x)\), where \(c\) is the chaining value of \(xs\).
def chainRev : List B → S
| [] => iv
| x :: xs => h (chainRev xs, x)
DefinitionMerkle–Damgård chaining value#✓fully proved
Let \(h : S \times B \to S\) be a compression function and \(iv \in S\) an initial value. The chaining value of a list of blocks \(M = (x_1, \dots, x_L)\) is \(z_L\), where \(z_0 = iv\) and \(z_i = h(z_{i-1}, x_i)\) for \(1 \le i \le L\).
DefinitionMerkle–Damgård hash with length strengthening#✓fully proved
Let \(h : S \times B \to S\) be a compression function, \(iv \in S\) an initial value and \(\ell : \mathbb{N} \to B\) a length encoding. The hash of a list of blocks \(M = (x_1, \dots, x_L)\) is \(h(z_L, \ell(L))\), where \(z_0 = iv\) and \(z_i = h(z_{i-1}, x_i)\) for \(1 \le i \le L\).
def hash (M : List B) : S := h (chain h iv M, lenBlock M.length)
def chain (M : List B) : S := chainRev h iv M.reverse
CSLibExt/Crypto/Hash/MerkleDamgard.lean:56
Uses 1 · Used by 3
DefinitionBackward search for a compression collision#✓fully proved
Let \(h : S \times B \to S\) be a compression function with initial value \(iv\), and for a list of blocks written last block first let \(z(xs)\) be its chaining value: \(z([\,]) = iv\) and \(z(x :: xs) = h(z(xs), x)\). Given two such lists, the search compares their leading compression inputs: on \(x :: xs\) and \(y :: ys\), if \((z(xs), x) = (z(ys), y)\) it continues with \(xs\) and \(ys\), and otherwise it returns the pair \(((z(xs), x), (z(ys), y))\). When either list is empty it returns no pair.
def search : List B → List B → Option ((S × B) × (S × B))
| x :: xs, y :: ys =>
if (chainRev h iv xs, x) = (chainRev h iv ys, y) then search xs ys
else some ((chainRev h iv xs, x), (chainRev h iv ys, y))
| _, _ => none
def chainRev : List B → S
| [] => iv
| x :: xs => h (chainRev xs, x)
CSLibExt/Crypto/Hash/MerkleDamgard.lean:51
Uses 1 · Used by 2
DefinitionCollision of a compression function#✓fully proved
Let \(h : S \times B \to S\) be a compression function. A pair \((p_1, p_2)\) of compression inputs in \(S \times B\) is a collision of \(h\) when \(p_1 \ne p_2\) and \(h(p_1) = h(p_2)\).
def IsCollision (p : (S × B) × (S × B)) : Prop := p.1 ≠ p.2 ∧ h p.1 = h p.2
DefinitionExtracting a compression collision from a Merkle–Damgård collision#✓fully proved
Let \(h : S \times B \to S\) be a compression function, \(iv \in S\) an initial value and \(\ell : \mathbb{N} \to B\) a length encoding. Let \(M = (x_1, \dots, x_L)\) and \(M' = (x'_1, \dots, x'_{L'})\) be lists of blocks with chaining values \(z_0 = z'_0 = iv\), \(z_i = h(z_{i-1}, x_i)\) and \(z'_j = h(z'_{j-1}, x'_j)\). The procedure compares the final compression inputs \((z_L, \ell(L))\) and \((z'_{L'}, \ell(L'))\) and returns this pair if they differ. Otherwise, for \(k = 1, 2, \dots, \min(L, L')\) in turn, it compares \((z_{L-k}, x_{L-k+1})\) with \((z'_{L'-k}, x'_{L'-k+1})\) and returns the first such pair that differs; if there is none, it returns no output.
def findCollision (M M' : List B) : Option ((S × B) × (S × B)) :=
if (chain h iv M, lenBlock M.length) = (chain h iv M', lenBlock M'.length) then
search h iv M.reverse M'.reverse
else some ((chain h iv M, lenBlock M.length), (chain h iv M', lenBlock M'.length))
def chain (M : List B) : S := chainRev h iv M.reverse
CSLibExt/Crypto/Hash/MerkleDamgard.lean:56
def search : List B → List B → Option ((S × B) × (S × B))
| x :: xs, y :: ys =>
if (chainRev h iv xs, x) = (chainRev h iv ys, y) then search xs ys
else some ((chainRev h iv xs, x), (chainRev h iv ys, y))
| _, _ => none
CSLibExt/Crypto/Hash/MerkleDamgard.lean:73
TheoremA Merkle–Damgård hash collision yields a compression collision#✓fully proved
Let \(h : S \times B \to S\) be a compression function, \(iv \in S\) an initial value and \(\ell : \mathbb{N} \to B\) a length encoding, and let \(H\) be the Merkle–Damgård hash with length strengthening they define. Write \(|M|\) for the number of blocks of a list of blocks \(M\). If \(M\) and \(M'\) are distinct lists of blocks with \(H(M) = H(M')\), and \(\ell(|M|) = \ell(|M'|)\) implies \(|M| = |M'|\), then the collision-finding procedure applied to \(M\) and \(M'\) returns a pair \((p_1, p_2)\) of compression inputs with \(p_1 \ne p_2\) and \(h(p_1) = h(p_2)\).
This is a block-level form of Katz and Lindell, Theorem 5.4.
theorem findCollision_spec {M M' : List B} (hne : M ≠ M')
(heq : hash h iv lenBlock M = hash h iv lenBlock M')
(hlen : lenBlock M.length = lenBlock M'.length → M.length = M'.length) :
∃ p, findCollision h iv lenBlock M M' = some p ∧ IsCollision h p
def hash (M : List B) : S := h (chain h iv M, lenBlock M.length)
CSLibExt/Crypto/Hash/MerkleDamgard.lean:67
def findCollision (M M' : List B) : Option ((S × B) × (S × B)) :=
if (chain h iv M, lenBlock M.length) = (chain h iv M', lenBlock M'.length) then
search h iv M.reverse M'.reverse
else some ((chain h iv M, lenBlock M.length), (chain h iv M', lenBlock M'.length))
CSLibExt/Crypto/Hash/MerkleDamgard.lean:99
def IsCollision (p : (S × B) × (S × B)) : Prop := p.1 ≠ p.2 ∧ h p.1 = h p.2
CSLibExt/Crypto/Hash/MerkleDamgard.lean:80
Uses 6 · Used by 1
DefinitionHash collision game for Merkle–Damgård#✓fully proved
Let \(H\) be the Merkle–Damgård hash with length strengthening defined by a compression function \(h : S \times B \to S\), an initial value \(iv \in S\) and a length encoding \(\ell : \mathbb{N} \to B\), and let \(N\) be a natural number. An adversary \(A\) maps random coins \(r\) from a finite nonempty type \(R\) to a pair of lists of blocks. The game is the distribution of the Boolean outcome when \(r\) is drawn uniformly from \(R\): the adversary wins (outcome true) exactly when \(A(r) = (M, M')\) with \(M \ne M'\), both \(M\) and \(M'\) have fewer than \(N\) blocks, and \(H(M) = H(M')\).
noncomputable def hashCollisionGame (A : R → List B × List B) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype R).map fun r =>
decide ((A r).1 ≠ (A r).2 ∧ (A r).1.length < maxLen ∧ (A r).2.length < maxLen ∧
hash h iv lenBlock (A r).1 = hash h iv lenBlock (A r).2)
def hash (M : List B) : S := h (chain h iv M, lenBlock M.length)
CSLibExt/Crypto/Hash/MerkleDamgard.lean:67
Uses 1 · Used by 1
DefinitionCompression-function collision game#✓fully proved
Let \(h : S \times B \to S\) be a compression function and let \(A\) be an adversary that maps random coins \(r\) from a finite nonempty type \(R\) either to a pair \((p_1, p_2)\) of compression inputs in \(S \times B\) or to no output. The game is the distribution of the Boolean outcome when \(r\) is drawn uniformly from \(R\): the adversary wins (outcome true) exactly when \(A(r)\) is a pair \((p_1, p_2)\) with \(p_1 \ne p_2\) and \(h(p_1) = h(p_2)\), and loses when \(A(r)\) is no output.
noncomputable def compressionCollisionGame (A : R → Option ((S × B) × (S × B))) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype R).map fun r =>
match A r with
| some p => decide (IsCollision h p)
| none => false
def IsCollision (p : (S × B) × (S × B)) : Prop := p.1 ≠ p.2 ∧ h p.1 = h p.2
CSLibExt/Crypto/Hash/MerkleDamgard.lean:80
Uses 1 · Used by 1
DefinitionMerkle–Damgård collision reduction#✓fully proved
Let \(h : S \times B \to S\) be a compression function, \(iv \in S\) an initial value, \(\ell : \mathbb{N} \to B\) a length encoding and \(A\) an adversary that maps random coins \(r\) from a finite nonempty type \(R\) to a pair \((M, M')\) of lists of blocks. The reduction is the adversary that, on coins \(r\), outputs the result of the Merkle–Damgård collision-finding procedure applied to the pair \((M, M') = A(r)\): a pair of compression inputs, or no output.
def reduction (A : R → List B × List B) : R → Option ((S × B) × (S × B)) :=
fun r => findCollision h iv lenBlock (A r).1 (A r).2
def findCollision (M M' : List B) : Option ((S × B) × (S × B)) :=
if (chain h iv M, lenBlock M.length) = (chain h iv M', lenBlock M'.length) then
search h iv M.reverse M'.reverse
else some ((chain h iv M, lenBlock M.length), (chain h iv M', lenBlock M'.length))
CSLibExt/Crypto/Hash/MerkleDamgard.lean:99
Uses 1 · Used by 1
TheoremThe Merkle–Damgård transform preserves collision resistance#✓fully proved
Let \(h : S \times B \to S\) be a compression function, \(iv \in S\) an initial value, \(\ell : \mathbb{N} \to B\) a length encoding and \(N\) a natural number such that \(\ell\) is injective on \(\{0, 1, \dots, N - 1\}\). Then for every adversary \(A\) that maps random coins from a finite nonempty type \(R\) to a pair of lists of blocks, the probability that the reduction built from \(A\) wins the compression-function collision game for \(h\) is at least the probability that \(A\) wins the hash collision game for the Merkle–Damgård hash defined by \(h\), \(iv\) and \(\ell\) with messages of fewer than \(N\) blocks.
theorem hashCollisionGame_le (hinj : ∀ L L', L < maxLen → L' < maxLen → lenBlock L = lenBlock L' →
L = L') (A : R → List B × List B) :
hashCollisionGame h iv lenBlock maxLen A true ≤
compressionCollisionGame h (reduction h iv lenBlock A) true
noncomputable def hashCollisionGame (A : R → List B × List B) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype R).map fun r =>
decide ((A r).1 ≠ (A r).2 ∧ (A r).1.length < maxLen ∧ (A r).2.length < maxLen ∧
hash h iv lenBlock (A r).1 = hash h iv lenBlock (A r).2)
CSLibExt/Crypto/Hash/MerkleDamgard.lean:123
noncomputable def compressionCollisionGame (A : R → Option ((S × B) × (S × B))) : PMF Bool :=
(Cslib.Probability.PMF.uniformOfFintype R).map fun r =>
match A r with
| some p => decide (IsCollision h p)
| none => false
CSLibExt/Crypto/Hash/MerkleDamgard.lean:130
def reduction (A : R → List B × List B) : R → Option ((S × B) × (S × B)) :=
fun r => findCollision h iv lenBlock (A r).1 (A r).2
CSLibExt/Crypto/Hash/MerkleDamgard.lean:137
Uses 7
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.