Definition sixtyfour {A} (i:A): list A:= list_repeat HF.BlockSize i.(*Reading rfc4231 reveals that padding happens on the right*)
Definition zeroPad (k: list byte) : list byte :=
  k ++ list_repeat (HF.BlockSize-length k) Byte.zero.Definition mkKey (l:list byte) : list byte :=
  if Z.gtb (Zlength l) (Z.of_nat HF.BlockSize)
  then (zeroPad (HF.Hash l))
  else zeroPad l.Definition KeyPreparation (l:list byte) : list byte := mkKey l.Definition mkArg (key:list byte) (pad:byte): list byte :=
       (map (fun p => Byte.xor (fst p) (snd p))
          (combine key (sixtyfour pad))).(*
Definition Ipad := P.Ipad.
Definition Opad := P.Opad.
*)
(*innerArg to be applied to message, (map Byte.repr (mkKey password)))*)

Definition innerArg IP (text: list byte) key : list byte :=
  (mkArg key IP) ++ text.Definition INNER IP k text := HF.Hash (innerArg IP text k).Definition outerArg OP (innerRes: list byte) key: list byte :=
  (mkArg key OP) ++ innerRes.Definition OUTER OP k innerRes := HF.Hash (outerArg OP innerRes k).Definition HmacCore IP OP txt (key: list byte): list byte := OUTER OP key (INNER IP key txt).Definition HASH a txt :=  HF.Hash (a ++ txt).Definition HmacCore' IP OP txt (key: list byte): list byte :=
  HASH (mkArg key OP) (HASH (mkArg key IP) txt).Goal forall IP OP txt key, HmacCore IP OP txt key = HmacCore' IP OP txt key.Definition HMAC IP OP txt password: list byte :=
  let key := KeyPreparation password in
  HmacCore IP OP txt key.

(* Specifications: *)
Lemma length_SF {A} (a:A) :length (sixtyfour a) = HF.BlockSize.