(* 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).(* 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).(* 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).

(* Specifications: *)
Lemma fstpad_len : forall (msg : list byte), Datatypes.length (msg ++ [Byte.repr 128] ++ list_repeat (Z.to_nat (- (Zlength msg + 9) mod 64)) Byte.zero) = (Datatypes.length msg + (S (Z.to_nat (- (Zlength msg + 9) mod 64))))%nat.
Lemma InWords_len4 : forall (l : list byte), Nat.divide (Z.to_nat WORD) (length l) -> InWords l.
Lemma pad_len_64_mod : forall (msg : list byte), (Zlength (pad msg)) mod 64 = 0.
Lemma pad_len_64 : forall (msg : list byte), exists (n : Z), Zlength (pad msg) = 64 * n /\ n >= 0.
Lemma pad_len_64_nat : forall (msg : list byte), exists (n : nat), (length (pad msg))%nat = (64 * n)%nat.
Lemma total_pad_len_Zlist : forall (msg : list byte), exists (n : nat), length (msg ++ [Byte.repr 128] ++ list_repeat (Z.to_nat (- (Zlength msg + 9) mod 64)) Byte.zero) = (n * Z.to_nat WORD (* 4 *))%nat.
Lemma pad_inwords : forall (msg : list byte), InWords (msg ++ [Byte.repr 128] ++ list_repeat (Z.to_nat (- (Zlength msg + 9) mod 64)) Byte.zero).