Section PRF_Encryption_IND_CPA.
Variable State : nat -> Set.
Variable A1 : forall n, OracleComp (Plaintext n) (Ciphertext n) (Plaintext n * Plaintext n * State n).
Variable A2 : forall n, State n -> Ciphertext n -> OracleComp (Plaintext n) (Ciphertext n) bool.
Hypothesis A1_admissible :
admissible_oc cost _ _ _ A1.
Hypothesis A2_admissible :
admissible_oc_func_2 cost _ _ _ _ _ A2.
unfold poly_time_nonuniform_oc_func_2.
exists (fun x o => o + 3*x).
exists (fun x => 2 * x).
intuition.
eapply polynomial_plus; intuition.
eapply polynomial_mult.
eapply polynomial_const.
eapply polynomial_ident.
eapply polynomial_mult.
eapply polynomial_const.
eapply polynomial_ident.
eapply cost_le.
eapply cost_curry.
eapply (PRFE_Encrypt_OC_cost_1 n).
eapply (@PRFE_Encrypt_OC_cost_2 n); eauto.
omega.
eapply PRFE_Encrypt_OC_oc_cost; intuition.
Qed.
intuition.
econstructor.
econstructor.
wftac.
intuition.
econstructor.
econstructor.
intuition.
econstructor.
wftac.
Qed.
intuition.
econstructor.
econstructor.
eapply A1_admissible.
eapply PRFE_Encrypt_wf.
intuition.
econstructor.
econstructor.
wftac.
intuition.
econstructor.
econstructor.
wftac.
intuition.
econstructor.
econstructor.
intuition.
econstructor.
econstructor.
simpl.
eapply A2_admissible.
intuition.
eapply PRFE_Encrypt_wf.
intuition.
econstructor.
wftac.
Qed.
intuition.
unfold PRF_A'.
unfold poly_time_nonuniform_oc.
destruct (PRFE_Encrypt_OC_poly_time).
destruct H0.
unfold admissible_oc in *.
unfold admissible_oc_func_2 in *.
intuition.
destruct H0.
destruct H2.
destruct H2.
intuition.
exists (fun x o : nat =>
x1 x (o + 5 * x) + x2 x (o + 5 * x) + o + 5 * (x3 x) + 6 +
7 * x).
intuition.
eapply polynomial_plus.
eapply polynomial_plus.
eapply polynomial_plus.
eapply polynomial_plus.
eapply polynomial_plus.
eapply H6.
eapply polynomial_plus; intuition.
eapply polynomial_mult.
eapply polynomial_const.
eapply polynomial_ident.
eapply H0.
eapply polynomial_plus; intuition.
eapply polynomial_mult.
eapply polynomial_const.
eapply polynomial_ident.
intuition.
eapply polynomial_mult.
eapply polynomial_const.
intuition.
eapply polynomial_const.
eapply polynomial_mult.
eapply polynomial_const.
eapply polynomial_ident.
eapply oc_cost_le.
eapply PRF_A'_cost;
eauto.
eapply H12.
intuition.
eapply H12.
intuition.
Qed.
intuition.
unfold PRFE_Encrypt_OC.
econstructor.
econstructor.
econstructor.
intuition.
econstructor.
econstructor.
intuition.
econstructor.
omega.
Qed.
unfold admissible_oc, admissible_oc_func_2 in *.
intuition.
destruct H5.
destruct H6.
intuition.
exists (fun n => x n + (1 + x0 n)).
intuition.
eapply polynomial_plus; intuition.
eapply polynomial_plus; intuition.
eapply polynomial_const.
eapply qam_le.
econstructor.
econstructor.
eauto.
intuition.
eapply PRFE_Encrypt_OC_qam.
intuition.
econstructor.
econstructor.
econstructor.
intuition.
econstructor.
econstructor.
intuition.
econstructor.
econstructor.
intuition.
econstructor.
econstructor.
econstructor.
eapply H8.
eapply le_refl.
eapply le_refl.
intuition.
eapply PRFE_Encrypt_OC_qam.
intuition.
econstructor.
omega.
Qed.
unfold admissible_oc.
intuition.
eapply PRF_A'_wf.
eapply PRF_A'_poly_time.
eapply PRF_A'_poly_queries.
Qed.
End PRF_Encryption_IND_CPA.

Theorem PRFE_IND_CPA :
PRF _ _ _ Rnd Rnd f _ _ (admissible_oc cost) ->
IND_CPA_SecretKey (fun n => pair_EqDec (Bvector_EqDec n) (Bvector_EqDec n))
PRFE_KeyGen (fun n => PRFE_Encrypt (@f n))
(admissible_oc cost)
(admissible_oc_func_2 cost).