unfold IND_CPA_SecretKey_O_3Proc_Advantage, IND_CPA_SecretKey_O_Advantage.
unfold IND_CPA_SecretKey_O_3Proc_G0, IND_CPA_SecretKey_O_3Proc_G1.
unfold IND_CPA_SecretKey_O_G0, IND_CPA_SecretKey_O_G1.
unfold A_c.
Local Opaque evalDist.
simpl.
eapply ratDistance_eqRat_compat.
comp_at comp_inline rightc 1%nat.
comp_swap_r.
inline_first.
comp_skip.
comp_simp.
comp_skip.
simpl.
inline_first.
comp_skip.
comp_simp.
inline_first.
rewrite <- evalDist_right_ident.
comp_skip.
comp_simp.
reflexivity.
comp_at comp_inline rightc 1%nat.
comp_swap_r.
inline_first.
comp_skip.
comp_simp.
comp_skip.
simpl.
inline_first.
comp_skip.
comp_simp.
inline_first.
rewrite <- evalDist_right_ident.
comp_skip.
comp_simp.
reflexivity.
Qed.
End IND_CPA_SecretKey_O_concrete_3Proc.
Section IND_CPA_SecretKey_OI_concrete.
Variable A B S_A: Set.
Variable defA : A.
Variable A1 : Comp (list A * S_A).
Variable A2 : A -> OracleComp Plaintext Ciphertext B.
Variable A3 : S_A -> list B -> Comp bool.
Hypothesis Ciphertext_EqDec : EqDec Ciphertext.
Hypothesis A_EqDec : EqDec A.
Hypothesis B_EqDec : EqDec B.
Hypothesis S_A_EqDec : EqDec S_A.
Variable ptDefault : Plaintext.
Definition IND_CPA_SecretKey_OI_G0 :=
[lsa, s_A] <-$2 A1;
lsb <-$ compMap _
(fun x =>
key <-$ KeyGen;
[b, _] <-$2 (A2 x) _ _ (EncryptOracle _ key) tt;
ret b
) lsa;
A3 s_A lsb.
Definition IND_CPA_SecretKey_OI_G1 :=
[lsa, s_A] <-$2 A1;
lsb <-$ compMap _
(fun x =>
key <-$ KeyGen;
[b, _] <-$2 (A2 x) _ _ (EncryptNothingOracle _ ptDefault key) tt;
ret b
) lsa;
A3 s_A lsb.
Definition IND_CPA_SecretKey_OI_Advantage :=
| Pr[IND_CPA_SecretKey_OI_G0] - Pr[IND_CPA_SecretKey_OI_G1]  |.
Section IND_CPA_SecretKey_OI_impl_O.
Hypothesis KeyGen_wf :
well_formed_comp KeyGen.
Hypothesis A2_wf :
forall a,
well_formed_oc (A2 a).
Variable maxA : nat.
Hypothesis maxA_correct :
forall ls s_A,
In (ls, s_A) (getSupport A1) ->
length ls <= maxA.
Variable IND_CPA_Adv : Rat.
Hypothesis IND_CPA_Adv_correct :
(forall i,
IND_CPA_SecretKey_O_Advantage (A_c
(B1 defA _ _ A1 i)
A2
(B2
(fun x : A =>
key <-$ KeyGen;
z <-$
(A2 x) unit unit_EqDec (EncryptOracle Ciphertext_EqDec key) tt;
[b, _]<-2 z; ret b)
(fun x : A =>
key <-$ KeyGen;
z <-$
(A2 x) unit unit_EqDec
(EncryptNothingOracle Ciphertext_EqDec ptDefault key) tt;
[b, _]<-2 z; ret b) B_EqDec A3)
)
_
ptDefault
<= IND_CPA_Adv)%rat.

Theorem IND_CPA_SecretKey_OI_G0_Hybrid :
Pr[IND_CPA_SecretKey_OI_G0] == Pr[ListHybrid_G _ A1 A3
(fun x =>
key <-$ KeyGen;
[b, _] <-$2 (A2 x) _ _ (EncryptOracle _ key) tt;
ret b
)].