(* Definition ltb (n m:nat):bool := if beq_nat n m then false else leb n m. Lemma ltb_char n m: ltb n m = true <-> (n<m)%nat. unfold ltb. remember (beq_nat n m). destruct b; symmetry in Heqb; split; intros. inv H. apply beq_nat_true in Heqb. subst. omega. apply beq_nat_false in Heqb. apply leb_complete in H. omega. apply leb_correct. omega. Qed. *)
Function toBlocks (l : Blist) {measure length l} : list Blist :=
(match l with
| nil => nil
| _ :: _ => if leb (List.length l) 511 then [firstn 512 l]
else firstn 512 l :: toBlocks (skipn 512 l)
end)%list.
Definition sha_splitandpad_blocks (msg : Blist) : list Blist :=
toBlocks (sha_splitandpad_inc msg).
(* Note use of sha_splitandpad_blocks and sha_splitandpad_inc' (= concat the blocks) *)

Theorem HMAC_list_concat_explicit : forall (k m : Blist) (op ip : Blist),
length k = b ->
length op = b ->
length ip = b ->
HMAC_List.HMAC c p sha_h sha_iv sha_splitandpad_blocks fpad op ip k m =
HMAC_Concat.HMAC c p B sha_h sha_iv sha_splitandpad_inc fpad op ip k m.