Module M := HMAC_Equiv HF EQ.
(* Assume h is a tau-PRF against adversary (PRF_h_A h_star_pad A_GHMAC) *)
Definition h_PRF (A : OracleComp (HMAC_Abstract.Message PARS.P) (Bvector EQ.c) bool) tau :=
isPRF ({ 0 , 1 }^EQ.c) ({ 0 , 1 }^EQ.c) M.h_v (Bvector_EqDec (b EQ.c EQ.p)) (Bvector_EqDec EQ.c) tau
(PRF_h_A (h_star_pad M.h_v EQ.fpad_v)
(HMAC_PRF.A_GHMAC EQ.p Message_eqdec (HMAC_Abstract.wrappedSAP _ _ EQ.splitAndPad_v) A)).
(* We could make similar predicates for the other definitions, or just assume the inequalities Definition h_star_WCR (A : OracleComp (HMAC_Abstract.Message PARS.P) (Bvector EQ.c) bool) epsilon := cAU.Adv_WCR (list_EqDec (Bvector_EqDec (b EQ.c EQ.p))) (Bvector_EqDec (b EQ.c EQ.p)) (h_star_pad M.h_v EQ.fpad_v) ({ 0 , 1 }^EQ.c) (au_F_A (A_GHMAC EQ.p Message_eqdec (HMAC_Abstract.wrappedSAP _ _ EQ.splitAndPad_v) A)) <= epsilon.*)
Definition h_star_WCR (A : OracleComp (HMAC_Abstract.Message PARS.P) (Bvector EQ.c) bool) epsilon := cAU.Adv_WCR (list_EqDec (Bvector_EqDec (HMAC_spec.b EQ.c EQ.p))) (Bvector_EqDec EQ.c) (h_star EQ.p M.h_v)
({ 0 , 1 }^ EQ.c) (Y EQ.fpad_v (au_F_A (A_GHMAC EQ.p Message_eqdec (HMAC_Abstract.wrappedSAP EQ.c EQ.p EQ.splitAndPad_v) A))) <=
epsilon.
Definition dual_h_RKA (A : OracleComp (HMAC_Abstract.Message PARS.P) (Bvector EQ.c) bool) sigma:=
RKA_Advantage _ _ _ ({ 0 , 1 }^b EQ.c EQ.p) ({ 0 , 1 }^EQ.c) (dual_f M.h_v) (BVxor (b EQ.c EQ.p))
(HMAC_RKA_A M.h_v EQ.iv_v EQ.fpad_v M.opad_v M.ipad_v (A_GHMAC EQ.p Message_eqdec (HMAC_Abstract.wrappedSAP _ _ EQ.splitAndPad_v) A)) <= sigma.

Theorem HMAC_isPRF A (A_wf : well_formed_oc A) tau epsilon sigma
(HH1: h_PRF A tau) (HH2: h_star_WCR A epsilon) (HH3: dual_h_RKA A sigma):
isPRF (Rnd (b EQ.c EQ.p)) (Rnd EQ.c)
(HMAC M.h_v EQ.iv_v (HMAC_Abstract.wrappedSAP _ _ EQ.splitAndPad_v)
EQ.fpad_v M.opad_v M.ipad_v)
Message_eqdec _ (tau + epsilon + sigma) A.