Definition shah : Blist -> Blist ->  Blist := sha_h.
Definition hashblock : list int -> list int -> list int := SHA256.hash_block.
Definition HHB : shah =
(fun rgs bl : Blist =>
intsToBits (hashblock (bitsToInts rgs) (bitsToInts bl))).
reflexivity. Qed.
Definition hashblocks: list int -> list int -> list int := SHA256.hash_blocks.
Definition d:nat := 16%nat.
Definition HBS_eq : forall r msg : list int,
hash_blocks r msg =
match msg with
| List.nil => r
| _ :: _ => hash_blocks (hash_block r (firstn d msg)) (skipn d msg)
end := hash_blocks_equation.
End I256.
Module PAD := HMAC_Pad SHA256 I256.

(* Specifications: *)
(* Relates the HMAC padded spec to the HMAC functional program *)
Theorem HMAC_pad_concrete (K : list byte) (M H : list byte) (OP IP : byte)
(k m h : Blist) (op ip : Blist):
((length K) * 8)%nat = (c + p)%nat ->
bytes_bits_lists k K ->
bytes_bits_lists m M ->
bytes_bits_lists op (HMAC_SHA256.sixtyfour OP) ->
bytes_bits_lists ip (HMAC_SHA256.sixtyfour IP) ->
sha.HMAC_spec_pad.HMAC c p B sha_h sha_iv sha_splitandpad op ip k m = h ->
HMAC_SHA256.HmacCore IP OP M K = H ->
bytes_bits_lists h H.
Theorem HMAC_pad_concrete' (K : list byte) (M : list byte) (OP IP : byte)
(k m : Blist) (op ip : Blist):
((length K) * 8)%nat = (c + p)%nat ->
Zlength K = Z.of_nat SHA256.BlockSize ->
bytes_bits_lists k K ->
bytes_bits_lists m M ->
bytes_bits_lists op (HMAC_SHA256.sixtyfour OP) ->
bytes_bits_lists ip (HMAC_SHA256.sixtyfour IP) ->
sha.HMAC_spec_pad.HMAC c p B sha_h sha_iv sha_splitandpad op ip k m =
bytesToBits (HMAC_SHA256.HmacCore IP OP M K).