(*Require Import FCF.HMAC_DRBG_definitions_only.*)
(*Variant of FCF.HMAC_DRBG_definitions_only.Gen_loop that - specializes eta to 256 - specializes f to HMAC256 - replaces v'::bits with bits++[v']*)
Fixpoint Gen_loop_Bvec (k : Bvector 256) (v : Bvector 256) (n : nat)
: list (Bvector 256) * Bvector 256 :=
match n with
| O => (nil, v)
| S n' =>
let v' := HMAC_Bvec k (to_list v) in
let (bits, v'') := Gen_loop_Bvec k v' n' in
(List.app bits (List.cons v' List.nil), v'')
end.
(*Variant of Gen_loop_bvec that uses Blist instead of Bvector 256*)
Fixpoint Gen_loop_Blist (k : Blist) (v : Blist) (n : nat)
: list Blist * Blist :=
match n with
| O => (nil, v)
| S n' =>
let v' := HMAC_Blist k v in
let (bits, v'') := Gen_loop_Blist k v' n' in
(List.app bits (List.cons v' List.nil), v'')
end.
(*Variant of Gen_loop_bvec that uses list byte instead of Bvector 256*)
Fixpoint Gen_loop_Zlist (k : list byte) (v : list byte) (n : nat)
: list (list byte) * (list byte) :=
match n with
| O => (nil, v)
| S n' =>
let v' := HMAC256 v k in
let (bits, v'') := Gen_loop_Zlist k v' n' in
(List.app bits (List.cons v' List.nil), v'')
end.
Definition Equiv n:= forall k v blocks u
(G: Gen_loop_Zlist k v n = (blocks, u)) m
(M: 32*(Z.of_nat n-1) < m <=32*(Z.of_nat n)),
HMAC_DRBG_generate_helper_Z HMAC256 k v m = (u,flatten (rev blocks)).
*)
(*Hence, by induction the following equivalence property holds*)

Lemma E_aux k: forall n v blocks u,
Gen_loop_Zlist k (HMAC256 v k) n = (blocks, u) ->
(flatten (rev blocks) ++ HMAC256 u k =
HMAC256 (HMAC256 v k) k ++ flatten (rev (map (fun z : list byte => HMAC256 z k) blocks)))%list.