Section HMAC_AbstractEQ.
Variable c:nat.
Variable p:nat.
Definition b := (c+p)%nat.
Variable h_v : Bvector c -> Bvector b -> Bvector c.
Variable iv_v : Bvector c.
Variable P : Blist -> Prop. (*example: P m := NPeano.divide 8 (length m)*)
Definition Message : Set := {m: Blist | P m}.
Definition Message2Blist(msg:Message):Blist := let (m,_) := msg in m.
Variable splitAndPad_v : Blist -> list (Bvector b).
Definition wrappedSAP (msg:Message): list (Bvector b) :=
splitAndPad_v (Message2Blist msg).
Variable splitAndPad_inj: forall b1 b2, splitAndPad_v b1 = splitAndPad_v b2 ->
P b1 -> P b2 -> b1=b2.
Definition wrappedSAP_1_1: forall msg1 msg2, wrappedSAP msg1=wrappedSAP msg2 -> msg1=msg2.
Variable fpad_v : Bvector c -> Bvector p.
Variable opad_v ipad_v : Bvector b.
(*End HMAC_AbstractEQ.  Section HMAC_Abstract_List. Variable c:nat. Variable p:nat. Variable h_v : Bvector c -> Bvector (b c p) -> Bvector c. Variable iv_v : Bvector c. Variable P : Blist -> Prop. (*example: P m := NPeano.divide 8 (length m)*)
Variable splitAndPad_v : Blist -> list (Bvector (b c p)).
Variable splitAndPad_inj: forall b1 b2, splitAndPad_v b1 = splitAndPad_v b2 ->
P b1 -> P b2 -> b1=b2.
Variable fpad_v : Bvector c -> Bvector p.
Variable opad_v ipad_v : Bvector (b c p).
*)
(* h *)
Variable h: Blist -> Blist -> Blist.
Hypothesis h_eq : forall block_v block_l
(HVL: block_l = Vector.to_list block_v)
ivA ivB (IV: ivA = Vector.to_list ivB),
h ivA block_l = Vector.to_list (h_v ivB block_v).
Variable iv: Blist.
Hypothesis iv_eq: iv=Vector.to_list iv_v.

(* h_star *)
Lemma hash_words_eq: forall l v
(HVL: Forall2 (fun bv bl => bl = Vector.to_list bv) v l)
ivA ivB (IV: ivA = Vector.to_list ivB),
HMAC_List.hash_words h ivA l
= Vector.to_list (hash_words p h_v ivB v).