(* Lemma 1: M = Prefix(Pad(M)) *)
(* TODO: replace InWords with InBlocks 4? *)
Inductive InWords : list byte -> Prop :=
| words_nil : InWords []
| words_word : forall (a b c d : byte) (msg : list byte),
InWords msg -> InWords (a :: b :: c :: d :: msg).
(* *** New definition for this lemma. *)
Definition pad (msg : list byte) : list byte :=
let n := Zlength msg in
msg ++ [Byte.repr 128%Z]
++ list_repeat (Z.to_nat (-(n + 9) mod 64)) Byte.zero
++ intlist_to_bytelist (([Int.repr (n * 8 / Int.modulus); Int.repr (n * 8)])%list).
Definition generate_and_pad' (msg : list byte) : list int :=
bytelist_to_intlist (pad msg).
(* ----------------- ^ Definitions *)
Definition fulllen (len : Z) :=
len + 1%Z + (- (len + 9) mod 64).
(* a ++ (b ++ (c ++ d)) = (a ++ (b ++ c)) ++ d *)
(* ------------------------------------------------ *)
(* Lemma 2: |M1| = |M2| -> |Pad(M1)| = |Pad(M2)| *)

Theorem length_equal_pad_length : forall (msg1 : list byte) (msg2 : list byte),
Zlength msg1  = Zlength msg2 ->
Zlength (generate_and_pad msg1) = Zlength (generate_and_pad msg2).