  Relational properties describe multiple runs of one or more programs. They
characterize many useful notions of security, program refinement, and
equivalence for programs with diverse computational effects, and they have
received much attention in the recent literature. Rather than developing
separate tools for special classes of effects and relational properties, we
advocate using a general purpose proof assistant as a unifying framework for
the relational verification of effectful programs. The essence of our approach
is to model effectful computations using monads and to prove relational
properties on their monadic representations, making the most of existing
support for reasoning about pure programs.
  We apply this method in F* and evaluate it by encoding a variety of
relational program analyses, including information flow control, program
equivalence and refinement at higher order, correctness of program
optimizations and game-based cryptographic security. By relying on SMT-based
automation, unary weakest preconditions, user-defined effects, and monadic
reification, we show that, compared to unary properties, verifying relational
properties requires little additional effort from the F* programmer.
