Local Open Scope nat.
Definition LBLOCK : nat := Z.to_nat LBLOCKz.
Definition CBLOCK : nat := Z.to_nat CBLOCKz.
Opaque LBLOCK CBLOCK.

Lemma generate_and_pad_lemma1:
forall hashed (dd: list byte) hashed' (dd': list byte) pad bitlen
(PAD : pad = 0 \/ dd' = [])
(H0 : Zlength dd' + 8 <= CBLOCKz)
(H1 : 0 <= pad < 8)
(H4: (LBLOCKz | Zlength hashed))
(H7 : ((Zlength hashed * 4 + Zlength dd) * 8)%Z = bitlen)
(H3: Zlength dd < CBLOCKz)
(H2 : (LBLOCKz | Zlength hashed'))
(H5 : intlist_to_bytelist hashed' ++ dd' =
intlist_to_bytelist hashed ++ dd ++ [Byte.repr 128] ++ list_repeat (Z.to_nat pad) Byte.zero),
let lastblock :=
(dd' ++
list_repeat (Z.to_nat (CBLOCKz - 8 - Zlength dd')) Byte.zero ++
intlist_to_bytelist [hi_part bitlen; lo_part bitlen])
in let lastblock' :=
bytelist_to_intlist lastblock
in forall (H99: Zlength lastblock = CBLOCKz),
generate_and_pad (intlist_to_bytelist hashed ++ dd) = hashed' ++ lastblock'.