Set Implicit Arguments.
Local Open Scope program_scope.
Section HMAC.
Variable c:nat.
Variable p:nat.
Definition b := (c+p)%nat.
Variable B: (0<b)%nat.
(* The compression function *)
Variable h : Blist -> Blist -> Blist.
(* The initialization vector is part of the spec of the hash function. *)
Variable iv : Blist.
(* The iteration of the compression function gives a keyed hash function on lists of words. *)
Definition h_star k (m : Blist) :=
hash_blocks_bits b B h k m.
(* The composition of the keyed hash function with the IV. *)
Definition hash_words := h_star iv.
Variable splitAndPad : Blist -> Blist.
Definition hash_words_padded : Blist -> Blist :=
hash_words ∘ splitAndPad.
(* constant-length padding. *)
Variable fpad : Blist.
Definition app_fpad (x : Blist) : Blist :=
x ++ fpad.
Definition h_star_pad k x :=
app_fpad (h_star k x).
(* The "two-key" version of GHMAC and HMAC. *)
(* Concatenate (K xor opad) and (K xor ipad) *)
Definition GHMAC_2K (k : Blist) m :=
let (k_Out, k_In) := splitList b k in (* concat earlier, then split *)
let h_in := (hash_words_padded (k_In ++ m)) in
hash_words_padded (k_Out ++ h_in).
Definition HMAC_2K (k : Blist) (m : Blist) :=
(* GHMAC_2K k (splitAndPad m). *)
GHMAC_2K k m.
(* opad and ipad are constants defined in the HMAC spec. *)
Variable opad ipad : Blist.
Definition HMAC (k : Blist) :=
HMAC_2K (BLxor k opad ++ BLxor k ipad).
(*The following hypotheses and constructions from the abstract spec do not need to be enforced/repeated here  Hypothesis splitAndPad_1_1 : forall b1 b2, splitAndPad b1 = splitAndPad b2 -> b1 = b2.  Definition GNMAC k m := let (k_Out, k_In) := splitList c k in h k_Out (h_star_pad k_In m).  Definition GHMAC (k : Blist) := GHMAC_2K (BLxor k opad ++ BLxor k ipad). *)
End HMAC.
Definition convert (l : list int) : list bool :=
bytesToBits (intlist_to_bytelist l).
(* Front/back equivalence theorems *)

(* Specifications: *)
Lemma front_equiv b d (DB32: (d*32)%nat = b):
forall (back : Blist) (BACK : list int) (front : Blist) (FRONT : list int),
(length front)%nat = b ->
(length FRONT)%nat = d ->
front ++ back = convert (FRONT ++ BACK) ->
front = convert FRONT.
Lemma back_equiv b d (DB32: (d*32)%nat = b):
forall (back : Blist) (BACK : list int) (front : Blist) (FRONT : list int),
(length front)%nat = b ->
(length FRONT)%nat = d ->
front ++ back = convert (FRONT ++ BACK) ->
back = convert BACK.