Definition c := (32 * 8)%nat.
Definition p := (32 * 8)%nat.
Definition b := (c + p)%nat.
Definition BlockSize := 64.
Definition BlockSize_Bits := BlockSize * 8.
Definition sha_iv : Blist :=
intsToBits SHA256.init_registers.
Definition sha_h (regs : Blist) (block : Blist) : Blist :=
intsToBits (SHA256.hash_block (bitsToInts regs) (bitsToInts block)).
Definition sha_splitandpad (msg : Blist) : Blist :=
bytesToBits (sha_padding_lemmas.pad (bitsToBytes msg)).
(* artifact of app_fpad definition *)
Definition fpad_inner (msg : list byte) : list byte :=
(let n := BlockSize + Zlength msg in
[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 fpad (msg : Blist) : Blist :=
bytesToBits (fpad_inner (bitsToBytes msg)).
unfold fpad. rewrite bytesToBits_len. apply fpad_inner_length.
apply M. (*we're exploiting the fact that c=p here*)
Qed.
(* modified version of sha_padding_lemmas.pad *)
Definition pad_inc (msg : list byte) : list byte :=
let n := BlockSize + 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)]).
Definition sha_splitandpad_inc (msg : Blist) : Blist :=
bytesToBits (pad_inc (bitsToBytes msg)).
(*******Injectivity of pad_inc*************************)
(********************************************************************)
(* Module SHAHF <: Hashfunction. (* TODO use neater definition with conversion functions *)
(* TODO split out of HMAC_spec_pad *)
Definition c := (32 * 8)%nat.
Definition p := (32 * 8)%nat.
Definition b := (c + p)%nat.
Definition BlockSize := 64.
Definition sha_iv : Blist :=
intsToBits SHA256.init_registers.
Definition sha_h (regs : Blist) (block : Blist) : Blist :=
intsToBits (SHA256.hash_block (bitsToInts regs) (bitsToInts block)).
Definition sha_splitandpad (msg : Blist) : Blist :=
bytesToBits (sha_padding_lemmas.pad (bitsToBytes msg)).
(* artifact of app_fpad definition *)
Definition fpad_inner (msg : list Z) : list Z :=
(let n := BlockSize + Zlength msg in
[128%Z]
++ list_repeat (Z.to_nat (-(n + 9) mod 64)) 0
++ intlist_to_Zlist ([Int.repr (n * 8 / Int.modulus); Int.repr (n * 8)]))%list.
Definition fpad (msg : Blist) : Blist :=
bytesToBits (fpad_inner (bitsToBytes msg)).
(* modified version of sha_padding_lemmas.pad *)
Definition pad_inc (msg : list Z) : list Z :=
let n := BlockSize + Zlength msg in
msg ++ [128%Z]
++ list_repeat (Z.to_nat (-(n + 9) mod 64)) 0
++ intlist_to_Zlist ([Int.repr (n * 8 / Int.modulus); Int.repr (n * 8)]).
Definition sha_splitandpad_inc (msg : Blist) : Blist :=
bytesToBits (pad_inc (bitsToBytes msg)).
(*******Injectivity of pad_inc*************************)

Lemma pad_injective_Case5 l1 l2
(H0 : (l1 ++ 128 :: nil) ++
list_repeat (Z.to_nat (- (BlockSize + Zlength l1 + 9) mod 64)) 0 =
(l2 ++ 128 :: nil) ++
list_repeat (Z.to_nat (- (BlockSize + Zlength l2 + 9) mod 64)) 0)
(H : (BlockSize + Zlength l1) * 8 =
((BlockSize + Zlength l2) * 8) mod Int.modulus)
(Nonneg1 : 0 <= (BlockSize + Zlength l1) * 8)
(l : (BlockSize + Zlength l1) * 8 < Int.modulus):
length l1 = length l2.