https://github.com/EasyCrypt/easycrypt
Raw File
Tip revision: 9f6a2f9c698e6c47fa841a0b040bc45d82a601c5 authored by Benjamin Gregoire on 07 July 2016, 06:32:45 UTC
add make
Tip revision: 9f6a2f9
Plug_and_Pray.ec
require import Pair Int Real Distr.
(*---*) import EuclDiv.

(*
  TODO:
    - Generalize from Dinter to Duni.
    - Provide another version for arbitrary distributions where the
      probability is upper-bounded by maximum probability of element
      in support of distribution.
*)

type tin.
type tres.

const bound : int.

axiom bound_pos : bound > 0.

module type Game = {
  proc main(x:tin): tres
}.

module Guess(G:Game) = {
  proc main(x:tin): int * tres = {
    var i, o;

    o = G.main(x);
    i = $[0..bound - 1];
    return (i,o);
  }
}.

lemma PBound (G <: Game) phi psi x0 &m:
  (1%r/bound%r) * Pr[G.main(x0) @ &m: phi (glob G) res]
  = Pr[Guess(G).main(x0) @ &m:
         phi (glob G) (snd res) /\
         let k = psi (glob G) (snd res)  in
         fst res = if 0 <= k < bound then k else 0].
proof.
  rewrite eq_sym.
  byphoare (_: (glob G) = (glob G){m} /\ x0 = x ==>
               phi (glob G) (snd res) /\
               let k = psi (glob G) (snd res) in
               fst res = if 0 <= k < bound then k else 0) => //.
  pose p:= Pr[G.main(x0) @ &m: phi (glob G) res].
  proc.
  seq  1: (phi (glob G) o)
          (p) (1%r/bound%r)
          _ 0%r => //.
    (* probability equality for 'phi (glob G) o' *)
    call (_:  (glob G) = (glob G){m} && x = x0 ==> phi (glob G) res) => //.
    bypr; progress; rewrite /p.
    byequiv (_: (glob G){1} = (glob G){2} /\ x{1} = x{2} ==>
                (phi (glob G) res){1} = (phi (glob G) res){2}) => //.
      by proc true.
    smt.
    (* probability of sampling such that Guess.i = psi (glob G) o *)
    rnd; skip; progress.
    rewrite /fst /snd /=.
    cut ->: (fun x,
              phi (glob G){hr} o{hr} /\
              x = if 0 <= psi (glob G){hr} o{hr} < bound
                    then psi (glob G){hr} o{hr}
                    else 0)
            = (pred1  (if 0 <= psi (glob G){hr} o{hr} < bound
                       then psi (glob G){hr} o{hr}
                       else 0)).
      by apply fun_ext=> x //=; rewrite H /= (eq_sym x).
    by rewrite -/(mu_x _ _) Distr.Dinter.mu_x_def_in; smt.
    (* probability that sampling changes '!phi (glob G) o' to 'phi (glob G) o' zero *)
    hoare; rnd; skip; progress [-split].
    by move: H; rewrite -neqF /snd /= => ->.
qed.
back to top