(*Module HMAC_Pad.Declare Module HF:HP.HASH_FUNCTION.*)
Module HM:= HP.HMAC_FUN HF.

(* Specifications: *)
Lemma xor_equiv_byte: forall xpad XPAD k K, bytes_bits_lists xpad (HM.sixtyfour XPAD) -> length K= HF.BlockSize -> bytes_bits_lists k K -> bytes_bits_lists (BLxor k xpad) (HM.mkArg K XPAD).
Lemma hash_block_equiv: forall (bits : Blist) (bytes : list byte) (regs : Blist) REGS, regs = bytesToBits (intlist_to_bytelist REGS) -> bits = bytesToBits bytes -> I.shah regs bits = bytesToBits (intlist_to_bytelist (I.hashblock REGS (bytelist_to_intlist bytes))).
Lemma fold_equiv_blocks b (B:(0<b)%nat) (DB32: (I.d*32)%nat=b): forall (l : Blist) (acc : Blist) (L : list int) (ACC : list int), InBlocks b l -> InBlocks I.d L -> l = convert L -> acc = convert ACC -> hash_blocks_bits b B I.shah acc l = convert (I.hashblocks ACC L).
Lemma equiv_pad shaiv shasplitandpad c p (B: (0< b c p)%nat) (DB32: (I.d*32 =b c p)%nat) ir (IVIR: shaiv = convert ir) gap (GAP: forall bits, NPeano.Nat.divide I.d (length (gap (bitsToBytes bits)))) (sap_gap: forall bits, shasplitandpad bits = bytesToBits (intlist_to_bytelist (gap (bitsToBytes bits)))) HASH (HSH: forall (m:list byte), HASH m = intlist_to_bytelist (I.hashblocks ir (gap m))): forall (bits : Blist) (bytes : list byte), bytes_bits_lists bits bytes -> bytes_bits_lists (hash_words_padded c p B I.shah shaiv shasplitandpad bits) (HASH bytes).
Theorem HMAC_pad_concrete splitandpad c p (B: (0< b c p)%nat) (BS: (HF.BlockSize * 8)%nat = b c p) (DB32: (I.d*32 =b c p)%nat) ir (*ie initial_regs*) gap (*ie generate_and_pad*) (GAP: forall bits, NPeano.Nat.divide I.d (length (gap (bitsToBytes bits)))) (sap_gap: forall bits, splitandpad bits = bytesToBits (intlist_to_bytelist (gap (bitsToBytes bits)))) (HSH: forall (m:list byte), HF.Hash m = intlist_to_bytelist (I.hashblocks ir (gap m))) (K : list byte) (M H : list byte) (OP IP : byte) (k m h : Blist) (op ip : Blist): length K = HF.BlockSize -> bytes_bits_lists k K -> bytes_bits_lists m M -> bytes_bits_lists op (HM.sixtyfour OP) -> bytes_bits_lists ip (HM.sixtyfour IP) -> HMAC c p B I.shah (convert ir) splitandpad op ip k m = h -> HM.HmacCore IP OP M K = H -> bytes_bits_lists h H.
Theorem HMAC_pad_concrete' splitandpad c p (B: (0< b c p)%nat) (BS: (HF.BlockSize * 8)%nat =b c p) (DB32: (I.d*32 =b c p)%nat) ir (*ie initial_regs*) gap (*ie generate_and_pad*) (GAP: forall bits, NPeano.Nat.divide I.d (length (gap (bitsToBytes bits)))) (sap_gap: splitandpad = fun bits => bytesToBits (intlist_to_bytelist (gap (bitsToBytes bits)))) (HSH: forall (m:list byte), HF.Hash m = intlist_to_bytelist (I.hashblocks ir (gap m))) (K : list byte) (M : list byte) (OP IP : byte) (k m : Blist) (op ip : Blist): length K = HF.BlockSize -> bytes_bits_lists k K -> bytes_bits_lists m M -> bytes_bits_lists op (HM.sixtyfour OP) -> bytes_bits_lists ip (HM.sixtyfour IP) -> bytes_bits_lists (HMAC c p B I.shah (convert ir) splitandpad op ip k m) (HM.HmacCore IP OP M K).