clutch.approxis.examples.prg
From clutch.prob_lang Require Import typing.tychk.
From clutch.approxis Require Import approxis map list security_aux option.
From clutch.approxis Require Export bounded_oracle.
Set Default Proof Using "Type*".
(* Right-associative tuples. Alas, this breaks Coq's built-in tuple notation. *)
(* Notation "( e1 ; e2 )" := (Pair e1 e2) : expr_scope.
Notation "( e1 ; e2 ; .. ; en' ; en )" := (Pair e1 (Pair e2 .. (Pair en' en) ..)) : expr_scope.
Notation "( e1 ; e2 )" := (PairV e1 e2) : val_scope.
Notation "( e1 ; e2 ; .. ; en' ; en )" := (PairV e1 (PairV e2 .. (PairV en' en) ..)) : val_scope. *)
Class PRG_params :=
{ card_input : nat
; card_extension : nat
; prg_params : val := (#card_input, #card_extension) }.
Definition TInput := TNat.
Definition TExtension := TNat.
Definition TOutput := (TNat * TNat)%ty.
Definition T_PRG_params := (TInput * TExtension)%ty.
Definition get_param_card_input : val := λ:"prg_params", Fst "prg_params".
Definition get_param_card_extension : val := λ:"prg_params", Snd "prg_params".
Class PRG `{PRG_params} :=
{ prg : val
(* ; rand_output : val *)
; prg_scheme : val := (prg_params, prg)%V
}.
Definition TPRG : type := () → TOutput.
Definition T_PRG_scheme := (T_PRG_params * TPRG)%ty.
Definition T_PRG_Adv := ((() → (TOption TOutput)) → TBool)%ty.
Definition get_params : val := λ:"prg_scheme", Fst "prg_scheme".
Definition get_card_input : val := λ:"prg_scheme", Fst (Fst "prg_scheme").
Definition get_card_extension : val := λ:"prg_scheme", Snd (Fst "prg_scheme").
Definition get_prg : val := λ:"prg_scheme", Snd "prg_scheme".
(* An idealised random generator. *)
Definition random_generator : val :=
λ: "card_input" "card_extension",
λ: "x",
(rand (#1 ≪ "card_input" - #1),
rand (#1 ≪ "card_extension" - #1)).
From clutch.approxis Require Import approxis map list security_aux option.
From clutch.approxis Require Export bounded_oracle.
Set Default Proof Using "Type*".
(* Right-associative tuples. Alas, this breaks Coq's built-in tuple notation. *)
(* Notation "( e1 ; e2 )" := (Pair e1 e2) : expr_scope.
Notation "( e1 ; e2 ; .. ; en' ; en )" := (Pair e1 (Pair e2 .. (Pair en' en) ..)) : expr_scope.
Notation "( e1 ; e2 )" := (PairV e1 e2) : val_scope.
Notation "( e1 ; e2 ; .. ; en' ; en )" := (PairV e1 (PairV e2 .. (PairV en' en) ..)) : val_scope. *)
Class PRG_params :=
{ card_input : nat
; card_extension : nat
; prg_params : val := (#card_input, #card_extension) }.
Definition TInput := TNat.
Definition TExtension := TNat.
Definition TOutput := (TNat * TNat)%ty.
Definition T_PRG_params := (TInput * TExtension)%ty.
Definition get_param_card_input : val := λ:"prg_params", Fst "prg_params".
Definition get_param_card_extension : val := λ:"prg_params", Snd "prg_params".
Class PRG `{PRG_params} :=
{ prg : val
(* ; rand_output : val *)
; prg_scheme : val := (prg_params, prg)%V
}.
Definition TPRG : type := () → TOutput.
Definition T_PRG_scheme := (T_PRG_params * TPRG)%ty.
Definition T_PRG_Adv := ((() → (TOption TOutput)) → TBool)%ty.
Definition get_params : val := λ:"prg_scheme", Fst "prg_scheme".
Definition get_card_input : val := λ:"prg_scheme", Fst (Fst "prg_scheme").
Definition get_card_extension : val := λ:"prg_scheme", Snd (Fst "prg_scheme").
Definition get_prg : val := λ:"prg_scheme", Snd "prg_scheme".
(* An idealised random generator. *)
Definition random_generator : val :=
λ: "card_input" "card_extension",
λ: "x",
(rand (#1 ≪ "card_input" - #1),
rand (#1 ≪ "card_extension" - #1)).
PRG security definitions using the variant of q_calls with explicit bounds
checks in the code.
Module bounds_check.
Section bounds_check.
(* Context `{PRG_scheme : PRG}. *)
(* Variable Input Extension : nat.
Let prg PRG_scheme : expr := Fst (Snd PRF_scheme).
Let rand_output PRF_scheme : expr := Snd (Snd PRF_scheme). *)
(* Let q_calls := q_calls (card_input PRG_scheme). *)
Definition PRG_real_rand : val :=
λ:"b" "adv" "PRG_scheme" "Q",
let: "input" := get_card_input "PRG_scheme" in
let: "prg_key_b" :=
if: "b" then
λ: <>, (get_prg "PRG_scheme") (rand "input")
else
random_generator (get_card_input "PRG_scheme") (get_card_extension "PRG_scheme") in
let: "oracle" := q_calls (get_card_input "PRG_scheme") "Q" "prg_key_b" in
let: "b'" := "adv" "oracle" in
"b'".
End bounds_check.
End bounds_check.
Section prg_lrel.
Context `{PRG_params : PRG}.
Definition lrel_input {Σ} : lrel Σ := lrel_int_bounded 0 card_input.
Definition lrel_output {Σ} : lrel Σ := lrel_int_bounded 0 (card_input + card_extension).
Definition lrel_prg `{!approxisRGS Σ} : lrel Σ := lrel_input → lrel_output.
Definition lrel_PRG_Adv `{!approxisRGS Σ} := ((lrel_input → (lrel_option lrel_output)) → lrel_bool)%lrel.
End prg_lrel.
Section bounds_check.
(* Context `{PRG_scheme : PRG}. *)
(* Variable Input Extension : nat.
Let prg PRG_scheme : expr := Fst (Snd PRF_scheme).
Let rand_output PRF_scheme : expr := Snd (Snd PRF_scheme). *)
(* Let q_calls := q_calls (card_input PRG_scheme). *)
Definition PRG_real_rand : val :=
λ:"b" "adv" "PRG_scheme" "Q",
let: "input" := get_card_input "PRG_scheme" in
let: "prg_key_b" :=
if: "b" then
λ: <>, (get_prg "PRG_scheme") (rand "input")
else
random_generator (get_card_input "PRG_scheme") (get_card_extension "PRG_scheme") in
let: "oracle" := q_calls (get_card_input "PRG_scheme") "Q" "prg_key_b" in
let: "b'" := "adv" "oracle" in
"b'".
End bounds_check.
End bounds_check.
Section prg_lrel.
Context `{PRG_params : PRG}.
Definition lrel_input {Σ} : lrel Σ := lrel_int_bounded 0 card_input.
Definition lrel_output {Σ} : lrel Σ := lrel_int_bounded 0 (card_input + card_extension).
Definition lrel_prg `{!approxisRGS Σ} : lrel Σ := lrel_input → lrel_output.
Definition lrel_PRG_Adv `{!approxisRGS Σ} := ((lrel_input → (lrel_option lrel_output)) → lrel_bool)%lrel.
End prg_lrel.