Proofs¶
The proof of a lemma is given after the lemma declaration,
between the Proof
and Qed
markers.
It consists in a list of tactics. The invocation of each
tactic modifies the proof state, which contains a list of goals to prove.
Each goal is displayed as a judgement.
Initially, the proof state consists of a single goal, as declared by the
user. Each tactic then reduces the first goal of the proof state to
an arbitrary number of new sub-goals. When no goal is left, the proof
is completed and Qed
can be used.
The complete list of tactics can be found in the corresponding tactic index.
Judgements¶
Squirrel features two kinds of judgements: local judgements and global judgements.
Logical variables¶
Logical variables are free variables in a current goal. Such variables are implicitly quantified universally based on their type and tags.
Hypotheses¶
Hypotheses are referred to by a hypothesis identifier hypothesis_id
.
::=
ident
Local judgement¶
The general layout for a local judgement is as follows:
- System: currentSystem
- Type variables: tvars
- Variables: vars
- H_1: hypothesis_1
- …
- H_k: hypothesis_k
- ——————————————
- conclusion
The judgement asserts that the conclusion below the line holds in the context given above the line. We now describe the various components of the judgement:
the system
currentSystem
is asystem_expr
in which the judgement’s formulas should be understood;tvars
are the judgement’s type variables;vars
are the judgement’s term variables with their types and tags;each hypothesis is identified by its hypothesis identifier (e.g.
H_1, H_2
) and is either a global hypothesis, whose body is a global formula, or a local hypothesis, whose body is a local formula;conclusion
is a local formula.
Global judgement¶
The general layout for a global judgement is similar to the local one except that now:
currentSystem
is asystem_context
;all hypotheses, as well as the conclusion, are global formulas.
When the conclusion is a single equiv(term,...,term)
predicate,
all the bi-terms that need to be proved equivalent are displayed as a
numbered list.
Example: Initial judgement for observational equivalence
Consider a lemma for observational equivalence, where the frame is enriched with some public key, as follows:
- global lemma [myProtocol] obs_equiv t : [happens(t)] -> equiv(frame@t, pk(sk))
When starting its proof, after doing intro H
, the goal that the user must prove is displayed as:
- [goal> Focused goal (1/1):
- Systems: left:myProtocol/left, right:myProtocol/right (same for equivalences)
- Variables: t:timestamp[glob]
- H: [happens(t)]
- —————————————-
- 0: frame@t
- 1: pk (sk)
Generalities¶
Tactic arguments¶
Tactics that apply to judgements whose conclusion is an equivalence
may take a natural number as argument to identify one item in the equivalence.
This is represented using the position
token.
::=
natural
Many tactics expecting a term support term patterns,
which are underspecified terms that can include term holes
_
. Most tactics will match the pattern against
sub-terms of the current goal until it manages to infer values for the term
holes.
Term patterns are produced by appending to the production of
term
and sterm
the hole construct:
::=
…
|
_
sterm_pat::=
…
|
_
Intro patterns¶
Introduction patterns are the principal tool used to do proof-context book-keeping. They are used in Squirrel with an SSReflect-inspired syntax. For a more comprehensive and detailed guide to introduction patterns, see here. Note however that Squirrel supports only a sub-set of SSReflect intro patterns, and that their behaviour in Squirrel may vary in small ways.
Introduction patterns take a different meaning depending
on the tactic in which they are used
(intro
, have
, destruct
, …). Nonetheless,
a introduction pattern always applies to a set of
focused formulas (sometimes taken in a judgement, with a full
proof-context) which they modify. A introduction pattern may create or
remove focused formulas. Most introduction patterns act only on the top-most
variables or assumptions of the focused formulas (e.g. if the formula
is forall x. G
or H => G
then the pattern will start by acting on
x
or H
).
::=
_?ident
and_or_ip::=
[][ simpl_ip+ ][ simpl_ip+| ]
simpl_ip::=
naming_ipand_or_iprewrite_ip
s_item::=
///=//=
rewrite_ip::=
-><-
expand_ip::=
@/macro_idoperator_id
clear_switch::=
{ hypothesis_id+ }
intro_pat::=
simpl_ip | s_item | expand_ip | clear_switch | * | >
A naming introduction pattern naming_ip
pops
the top-most assumption or universally quantified variable of the
focused formula and introduces it in the proof context,
with a name chosen according to the pattern:
ident
: using the nameident
provided, which fails ifident
is already in use;?
: using a name chosen automatically by Squirrel;_
: using an automatically chosen name for variables, and the name_
for assumptions, which is a special name that can never be referred to by the user. Note that, contrary to otherhypothesis_id
, several hypotheses may be named_
.
A and/or introduction pattern and_or_ip
will,
for each focused formula, destruct the top-most assumption of the formula:
[ simpl_ip ... simpl_ip ]
: the top-most assumption of the formula must be a conjunction with as many conjuncts as simple patterns are provided. Destruct the conjunction, handling each conjunct according to the correspondingsimpl_ip
.[ simpl_ip | ... | simpl_ip ]
: the top-most assumption of the formula must be a disjunction with as many disjuncts as simple patterns are provided. Destruct the disjunction, creating a formula for each disjunct and handling each of them according to the correspondingsimpl_ip
.
Note
Existentials are viewed as conjunctions in intro patterns.
Hence, when the conclusion is of the form (exists x, phi) => psi
,
the tactic intro [x H] will introduce a variable x and hypothesis
H : phi. Here, the conjunctive intro pattern has been used to
destruct the existentially quantified hypothesis during its introduction.
A simplification item s_item
simplifies the focused formulas:
//
removes all formulas on whichauto
concludes;/=
simplifies all formulas usingsimpl
;//=
is short-hand for// /=
;
A rewrite intro pattern item rewrite_ip
uses the top-most assumption to rewrite the focused formulas. The top
assumption is cleared after rewriting.
->
reads the top-most assumption as a left-to-right rewrite rule.<-
reads the top-most assumption as a right-to-left rewrite rule.
An expansion item expand_ip
expands definitions in the focused formulas:
@/macro_id
expands the applications of the macro symbol;macro_id
whenever it is applied to a time-point that can be shown to happen;@/operator_id
expands the operatoroperator_id
, \(\beta\)-reducing the operator if it is applied.
A clear switch clear_switch
clears the
specified hypotheses from the proof context.
Proof terms¶
Proof terms are used by several tactics (see e.g. have
or
apply
) as a convenient way to combine and (partially) apply
hypotheses, axioms or proved lemmas, in order to derive new facts.
::=
ident pt_arg*
pt_arg::=
sterm_pat | ident | (% proof_term) | _
In a proof_term
or a pt_arg
, an identifier ident
must
refer to a hypothesis in the current proof context, an axiom or a
previously proved lemma.
Note that the grammar for proof term arguments pt_arg
is
ambiguous (because of the ident
and sterm
productions). When this happens, Squirrel tries to desambiguate using
the context.
Note
The (% proof_term)
syntax is experimental, and is subject to
change in the future.
Proof-term resolution¶
A proof-term ident pt_arg1 ... pt_argn
is
resolved into a local or global formula as follows:
First, the proof-term head
ident
is resolved as alocal_formula
orglobal_formula
F
.Then, this local or global formula
F
is successively modified by applying to it the argumentspt_arg1 ... pt_argn
, in order, as follows:sterm_pat
: the top-most element ofF
must be a universally quantified variable, which is then substituted withsterm_pat
, e.g.forall x, F0
is replaced with(F0{x -> sterm})
. Moreover, a new term unification variable is created for each hole_
insterm_pat
.ident
: the top-most element ofF
must be an assumption, which is popped and unified with the formula corresponding to the hypothesis, axiom or lemma identified byident
.(% proof_term)
: the proof-term argumentproof_term
is recursively resolved into a formula, which is then unified with the top-most element ofF
._
: ifF
’s top-most element is a universally quantified variable then a new unification variable is created and applied toF
. IfF
’s top-most element is an assumptionH
, a new sub-goal requiring to proveH
is created and must be discharged by the user.
Finally, depending on which tactic uses the proof-term, Squirrel checks that the term unification variables can all be inferred, generalizes the term unification variables that remain, or leaves the term unification environment unclosed.
In practice, the application of a proof-term argument is more complex than described above, for several reasons:
checks must be perfomed to ensure the compatibility of the systems corresponding to the applied formulas, e.g. applying an axiom over system
[any]
to a formula over system[default]
is valid, but the converse is not;some formula manipulations occur when trying to mix global and local formulas, e.g. when applying a global formula to a local formula.
Reduction¶
Several tactics (e.g., simpl
and auto
) rely on a
reduction engine. This engine repeatedly applies several
transformations, corresponding to the following flags.
::=
~flags:[ rwbetaprojdeltaconstr*, ]
Leaving the flags unspecified results in the rw
, beta
and
proj
transformations being used. Specifying an empty list of
flags results in no transformations being applied. Otherwise, only the
specified transformations are applied, as described next:
rw
: perform user-defined rewriting;
beta
: perform beta-reductions;
proj
: compute tuple projections;
delta
: replace macros and operators with their definitions;
constr
: automatically simplify trace formulas using constraint reasoning.
The constr
transformation replaces trace (sub-)formulas that
are provably equal to true
or false
with that value.
When doing so, the constraint solver takes into account
the current hypotheses but also the conditionals that surround
the trace formula.
The user-defined rewriting transformation eagerly applies the rewrite
rules added to the rewriting database using the hint rewrite
command.
Automatic simplification tactics¶
There are three automated tactics. The autosimpl
tactic is
called automatically after each tactic, unless the tactical
nosimpl
is used.
- Tactic auto simpl_flags?¶
Attempt to automatically prove a goal using the hypotheses.
The tactic uses the reduction engine with the provided flags (defaults to
rw,beta,proj
).Moreover, for local goals, the tactic relies on basic propositional reasoning, rewriting simplications, and both
constraints
andcongruence
.- Error cannot close goal¶
The current goal could not be closed.
- Tactic autosimpl¶
Simplify a goal, without closing it.
The tactic uses the reduction engine with the flags
rw,beta,proj
.When the conclusion of the goal is a conjunction, it splits the goal into several sub-goals, automatically closing only the trivial goals proved by
true
andassumption
.When the conclusion of the goal is a global formula which only contains a local formula, the goal is then turned into a local formula. Otherwise the tactic does nothing.
- Tactic simpl simpl_flags?¶
Simplify a goal and its hypotheses. This tactic always succeeds, replacing the initial goal with a single simplified goal.
The tactic uses the reduction engine with the provided flags (defaults to
rw,beta,proj
).When the goal is a conjunction, the tactic will attempt to automatically prove some conjuncts (using
auto
) and will then return a simplified sub-goal without these conjuncts. In the degenerate case where no conjunct remains, the goal will betrue
.When the conclusion of the goal is an equivalence, the tactic will automatically perform
fa
when at most one of the remaining sub-terms is non-deducible. It may thus remove a deducible item from the equivalence, or replace an item<u,v>
withu
if it determines thatv
is deducible.
Tactics¶
The full syntax of tactic combinations is as follows:
tactic::=
tactic; tac_selector? tactic
|
tactic; [ tac_selector tactic*| ]
|
tactic + tactic
|
by tactic
|
nosimpl tactic
|
try tactic
|
repeat tactic
|
tactic => intro_pat+
tac_selector::=
natural*, :
Tactic combinators behaves as follows:
the semi-column
;
is used for judgemential composition. The second tactic is applied to all sub-goals created by the first one, unless the indices of some sub-goals are specified using atac_selector
.A different tactic can be applied to different sub-goals, for example
tactic; [1: tactic1 | 3,4: tactic2]
appliestactic1
to the first created sub-goal, andtactic2
to the third and fourth sub-goals.The
+
combinator performs an or-else, i.e. tries applying the first tactic, and if that fails, applies the second one.
The remainder behaves as follows:
- Tactic nosimpl tactic¶
Call the given tactic without the implicit use of simplifications. This can be useful to understand what’s going on step by step. This is also necessary in rare occasions where simplifications are actually undesirable to complete the proof.
- Tactic try tactic¶
Try to apply the given tactic. If it fails, succeed with the sub-goal left unchanged.
- Tactic repeat tactic¶
Apply the given tactic, and recursively apply it again on the generated sub-goals, until it fails.
- Tactic tactic => intro_pat_list
- intro_pat_list
::=
intro_pat*tactic => intro_pat_list
is equivalent totactic; intro intro_pat_list
Common errors¶
- Error Out of range position.¶
Argument does not correspond to a valid equivalence item.
- Error Assumption not over valid system¶
Trying to use a proof term that does not apply to the current system.
Tactics¶
Tactics are organized in three categories:
generic tactics, that rely on generic logical reasoning;
structural tactics, that rely on properties of protocols and equality;
cryptographic tactics, that rely on cryptographic assumptions.
In addition, they are also split between tactics applicable to local goals only, global goals only, or tactics common to both types of goals. Remark that applying a tactic to a local goal may produce a global sub-goal, and conversely.
Additionally, there are a few utility tactics listed at the end.
Generic tactics¶
Common tactics¶
- Tactic admit position?¶
Admit the current goal, or admit the element at position
position
when the goal is an equivalence.
- Tactic assumption hypothesis_id?¶
Conclude if the conclusion of the current goal (or
false
) appears in the hypotheses. The hypothesis to be checked against may be directly specified usinghypothesis_id
.
- Tactic case hypothesis_idterm_pat¶
Perform a case analysis over the given argument:
hypothesis_id
: create one sub-goal for each disjunct ofhypothesis_id
;term_pat
a term of typetimestamp
: create one sub-goal for each possible action constructor of the current goal’s system (all systems appearing in a judgement have the same set of actions, as they must be be compatible).
- Tactic induction term_pat?¶
Apply the induction scheme to the conclusion. There are several behaviours depending on the type of the current goal and whether an argument is given.
For a reachability goal, if no argument is specified, the conclusion must start with a universal quantification over a well-founded type and the induction is performed over the first quantified variable. If a term is manually specified, the goal is first generalized (see
generalize
) w.r.t. those variables and only then is the induction applied.For an equivalence goal, an argument must always be specified, and,
if a timestamp variable is given then, a weak induction is performed over this variable as well as a case disjunction over all possible actions;
for any other term argument, the tactic behaves as in the reachability case.
The weak induction variant is in fact the most widely used tactic in current Squirrel examples to prove the observational equivalence of a protocol.
Example: Induction for observational equivalence.
Over a goal of the form
- [goal> Focused goal (1/1):
- Systems: left:myProtocol/left, right:myProtocol/right (same for equivalences)
- Variables: t:timestamp[glob]
- H: [happens(t)]
- —————————————-
- 0: frame@t
Calling
induction t
will apply the weak induction and case disjunction, yielding as many goals as there are actions in the protocol, plus one additional goal for the initialization. Assuming an actionA
is in the protocol, that has a total of 3 actions, a sub-goal created for the case ofA
looks like- [goal> Focused goal (1/4):
- Systems: left:myProtocol/left, right:myProtocol/right (same for equivalences)
- H: [happens(A)]
- IH: equiv(frame@pred (A))
- —————————————-
- 0: frame@A
- Tactic dependent induction variable?¶
Apply the induction scheme to the conclusion. If no argument is specified, the conclusion must be a universal quantification over a well-founded type. Alternatively, a term of a well-founded type can be given as argument, in which case the goal is first generalized in the dependent variant (see
generalize dependent
) before proceeding with the induction.This tactic always uses a strong induction principle (as opposed to the
induction
tactic, which performs a weak induction when the conclusion is an equivalences).
- Tactic destruct hypothesis_id as simpl_ip?¶
Destruct a hypothesis based on its top-most connective (existential quantification, disjunction or conjunction), applying the simple introduction pattern
simpl_ip
to it.simpl_ip
defaults to?
if no pattern is provided by the user.Example: Destruct
If we have the hypothesis
H: A \/ (B /\ C)
, the tactic- destruct H as [H1 | [H2 H3]]
removes the
H
hypothesis and creates two sub-goals, one with the hypothesisH1:A
, the other with the hypothesesH2:B, H3:C
.
- Tactic exists term*¶
exists term1 ... termn
uses the termsterm1 ... termn
as witnesses to prove an existentially quantified conclusion.For example,
exists t
transforms the conclusion of a goal(exists x, phi)
into(phi{x -> t})
.
- Tactic generalize term_pat+ as variable+?¶
generalize term_pat
looks for an instanceterm
ofterm_pat
in the goal. Then, it replaces all occurrences ofterm
by a fresh universally quantified variable (automatically named, orvariable
if provided).
- Tactic generalize dependent term_pat+ as variable+?¶
Same as
generalize
, but also generalize in the proof context. All hypotheses in which generalization occurred are pushed back into the conclusion before the newly added quantified variables.
- Tactic have have_ip : termglobal_formula¶
- have_ip
::=
s_item* simpl_ip s_item*have have_ip : F
introduces the new hypothesisF
, which can be aterm
or aglobal_formula
. The new hypothesis is processed byhave_ip
(see below). A new sub-goal requiring to proveF
is created.If
have_ip
is the introduction patterns_itempre simpl_ip s_itempost
then:the simplification item
s_itempre
is applied to the conclusion before adding the hypothesis;the simple intro-pattern
simpl_ip
is applied to introduce the new hypothesisF
;the simplification item
s_itempost
is applied to the conclusions after adding the hypothesis.
It there are mutliple pre or post simplification items, they are applied in order.
- Tactic assert term as simpl_ip?¶
This is an alternative syntax for
have simpl_ip : term
, wheresimpl_ip
defaults to?
.
- Tactic have have_ip := proof_term¶
have have_ip := proof_term
resolvesproof_term
— requiring that the term unification enviroment is closed — and processes the resulting formula using introduction patternhave_ip
.
- Tactic apply proof_term¶
Backward reasoning tactic. First,
proof_term
is resolved as a formulaFpt
— without closing the term unification environment. Then, it is unified with the conclusion, and finally the term unification environment is closed.If the unification of
Fpt
with the conclusion fails, the tactic introduces the top-most element ofFpt
as described below, and then tries again to unify with the conclusion:if it is a variable (i.e.
Fpt = forall x, F
), it introduces a new term unification variablex
and continues fromF
;if it is an assumption (i.e.
Fpt = G => F
), the assumptionG
is discharged as a new sub-goal, and the tactic continues fromF
.
- Tactic apply proof_term in hypothesis_id¶
Forward reasoning variant of
apply
, which unifies the premisses ofproof_term
against the conclusion ofhypothesis_id
, replacinghypothesis_id
content withproof_term
’s conclusion.For instance, if
H1:A=>B
andH2:A
, thenapply H1 in H2
replacesH2:A
withH2:B
.
- Tactic rewrite rw_arg* in rw_target?¶
- rw_arg
::=
s_itemrw_itemrw_item
::=
natural? !?? <-? (proof_term)/ident/( infix_op)/*rw_target
::=
hypothesis_id*Apply a sequence of rewriting and simplification items to the rewrite target, which is:
the hypothesis
hypothesis_id
ifrw_target = hypothesis_id
;all hypotheses if
rw_target = hypothesis_id
;the conclusion if no specific rewrite target is given.
Rewrite items are applied as follows:
proof term rewrite item
proof_term
:It is first resolved — without closing the term unification environment — as a local formula
F
or global formula[F]
whereF = forall x1...xn, H1=>...=>Hn=> l = r
. At that point,l
andr
are swapped if the rewrite item is prefixed by<-
.Then, Squirrel tries to unify
l
with a sub-term of the rewrite target, wherex1...xn
are handled as term unification variables. If it succeeds, all occurrences of the matched instance ofl
are replaced with the corresponding instantiation ofr
.The term unification environment is closed, and new sub-goals are created for the instantiated assumptions
H1,...,Hn
.
expansion items
/ident
and/( infix_op)
tries to expand the corresponding symbol (see expansion item), while/*
tries to expand all possible symbols;!
applies the rewrite item as many times as possible, but at least once, while(natural !)
applies the rewrite item exactlynatural
times.?
behaves as!
, except that the rewrite item may be applied zero times. Otherwise, the rewrite item must be applied exactly once.
- Error rule bad systems¶
Rewrite item applies to a system which is not compatible with the rewrite target.
- Error nothing to rewrite¶
No instance of the rewrite rule were found.
- Error max nested rewriting reached¶
There were too many nested rewriting. This is to avoid infinite rewriting loops.
- Tactic id¶
The identity tactic, which does nothing. Sometimes useful when using tactic combinators.
- Tactic intro intro_pat+¶
Introduce the top-most assumptions and universally quantified variables of the conclusion as specified by the given introduction patterns.
- Tactic clear hypothesis_id*¶
Drop the specified hypotheses.
- Tactic reduce simpl_flags?¶
Reduce all terms in a goal, working on both hypotheses and conclusion.
This tactic always succeeds, replacing the initial goal with a unique sub-goal (which may be identical to the initial one).
The tactic uses the reduction engine with the provided flags (defaults to
rw,beta,proj
).
- Tactic remember term_pat¶
remember
behaves asgeneralize
, except that it adds as a hypothesis the equality between the generalized term and the new variable.
- Tactic revert hypothesis_id*¶
Remove the hypotheses from the proof context, and add them back into the conclusion of the goal.
For example, running
revert H
on the judgementH : F, Γ ⊢ conc
yieldsΓ ⊢ F => conc
.
- Tactic left¶
Reduce a goal with a disjunction conclusion into the goal where the conclusion has been replaced with the first disjunct. That is,
left
turnsΓ ⊢ F || G
intoΓ ⊢ F
.
- Tactic right¶
Reduce a goal with a disjunction conclusion into the goal where the conclusion has been replaced with the second disjunct. That is,
right
turnsΓ ⊢ F || G
intoΓ ⊢ G
.
- Tactic split¶
Split a conjunction goal, creating one sub-goal per conjunct. For example,
split
replaces the goal⊢ F && G && H
with the three goals⊢ F
,⊢ G
and⊢ H
.
- Tactic use hypothesis_id with term+? as simpl_ip?¶
Instantiate a lemma or hypothesis using the provided arguments (if any). An introduction pattern can also be specified to handle the new hypothesis.
Warning
This tactic is a deprecated (and less powerful) variant of the
have
tactic (with thehave have_ip := proof_term
form).
Local tactics¶
- TraceTactic true¶
Close a goal when the conclusion is (syntactically)
true
.
Global tactics¶
- EquivTactic byequiv¶
Transform a global judgement
⊢ [F]
into a local judgement⊢ F
.
- EquivTactic constseq position: (fun binders => term) term+¶
Simplify a sequence at the given
position
when it only contains a finite number of possible valuesv_1
,…,v_i
depending on the value of the sequence variable.Given a sequence over a variable of a given type, the arguments passed must be of the form
(fun_1 v_1) ... (fun_i v_i)
, where all thefun
functions must be binders over the sequence type and must return a boolean. This tactic creates two sub-goals asking to prove the two required properties of the arguments and sequence:All the functions must be such that for any given input element, exactly one of the functions returns true.
The sequence is then expected to be equal to the value of v_i for all input elements such that fun_i is true.
Example: Constseq one or zero
Consider the following conclusion for a global goal
0: seq(t':timestamp=>(if (t' < t) then one))
(assuming thatt'
is a freetimestamp
variable).It is clear that this sequence only returns
one
orzero
(zero is in the implicit else branch). It can then be simplified by calling the tactic:- constseq 0:
- (fun (t’:timestamp) => t’ < t) one)
- (fun (t’:timestamp) => not (t’ < t)) zero).
This replaces in the current goal the constant by zero and one, and creats two sub-goal, asking to prove the two following formulas:
- forall (t’:timestamp),
- (fun (t’:timestamp) => t’ < t) t’
- || (fun (t’:timestamp) => not (t’ < t)) t’
- (forall (t’:timestamp),
- (fun (t’:timestamp) => t’ < t) t’ => if (t’ < t) then one = one) &&
- forall (t’:timestamp),
- (fun (t’:timestamp) => not (t’ < t)) t’ => if (t’ < t) then one = zero
- EquivTactic enrich term+,¶
Enrich the conclusion of an equivalence goal with the given terms. Note that this changes the positions of items in the equivalence, and if added before other tactics may break later references.
- Tactic localize hypothesis as simpl_ip¶
Change a global hypothesis containing a reachability formula
[term]
to a local hypothesisterm
, and applies the given simple introduction patternsimpl_ip
to the new hypothesis.For example, the tactic turns
[F],G ⊢ H
intoF,G ⊢ H
.
- EquivTactic memseq¶
Prove that a bi-frame element appears in a sequence of the bi-frame.
- EquivTactic refl¶
Close a goal by reflexivity. Cannot apply if the goal contains variable or macros, as those may have different left and right behaviours.
- EquivTactic sym¶
Swap the left and right system of the equivalence goal.
- EquivTactic trans¶
Prove an equivalence by transitivity.
- EquivTactic splitseq position: (fun binders => term)¶
Split a sequence according to some boolean test, replacing the sequence with two subsequences.
The function passed as argument must be take as argument a variable of the same type as the sequence, and must return a boolean.
Example: Splitting a sequence
Called in a goal with a conclusion of the form
0: seq(x:message => value)
, the tactic:- splitseq 0: (fun y:message => some_test)
replaces the conclusion with:
- 0: seq(x:message=>
- (if (fun y:message => some_test) x then
- value))
- 1: seq(x:message=>
- (if not ((fun y:message => some_test) x) then
- value))
Structural tactics¶
Common tactics¶
- Tactic constraints¶
Attempt to conclude by automated reasoning on trace literals. Literals are collected from hypotheses, both local and global, after the destruction of conjunctions (but no case analysis is performed to handle conjunctive hypotheses). If the conclusion is a trace literal then it is taken into account as well.
- Tactic depends timestamp, timestamp¶
If the second action depends on the first action, and if the second action happens, then add the corresponding timestamp inequality.
- Error Not dependent¶
The two actions are not dependent, i.e. were not derived from two outputs in sequence in the source process.
- Tactic expand macro_id | macro_application+,¶
Expand all occurences of the given macros in both the conclusion and proof-context, either fully specified with an action or simply a type of macro.
- Tactic expandall¶
Expand all possible macros in the current proof-context and conclusion.
- Tactic fa positionfa_arg+,¶
- fa_arg
::=
!?? term_patApply the function application rule, simplifying the goal by removing the head function symbol, as follows:
in a local goal with conclusion
f u = f v
, the conclusion is replaced withu=v
. This produces as many sub-goals as there are arguments of the head function symbol. For a local goal, the tactic takes no arguments.in a global goal,
f(u1,...,un)
is replaced withu1,...,un
.
In the global goal setting, the target can be selected with its
position
, or using afa_arg
, which behave as follow:fa
term_pat
selects the first position in the equivalence that matchesterm_pat
.fa !t
repeats the function application as many times as possible, but at least once.fa ?t
repeats the function application as many times as possible, including 0.fa arg1, arg2, ...
is syntactic sugar forfa arg1; fa arg2; ...
.
Local tactics¶
- TraceTactic congruence¶
Attempt to conclude by automated reasoning on message (dis)-equalities. Equalities and disequalities are collected from hypotheses, both local and global, after the destruction of conjunctions (but no case analysis is performed to handle conjunctive hypotheses). If the conclusion is a message (dis)-equality then it is taken into account as well.
- TraceTactic const variable¶
Add the const tag to a variable.
The variable must be of a finite and fixed (η-independent) type, and must not appear in any global hypothesis (some global hypotheses may be localised (see
localize
) if necessary.
- TraceTactic eqnames¶
Add index constraints resulting from names equalities, modulo the known equalities.
If
n(i) = n(j)
theni = j
. This is checked on all name equality entailed by the current context.
- TraceTactic eqtrace¶
Add term constraints resulting from timestamp and index equalities.
Whenever
i=j
orts=ts'
, we can substitute one by another in the other terms.
- TraceTactic executable term¶
Assert that
exec@_
impliesexec@_
for all previous timestamps.Given as input a timestamp
ts
, this tactic produces two new sub-goals, requiring to prove thathappens(ts)
holds and thatexec@ts
also holds. The fact that(forall (t:timestamp), t <= ts => exec@t)
is added as a hypothesis to the current goal.
- TraceTactic project¶
Turn a local goal on a multi-system into one goal for each single system in the multi-system.
- TraceTactic rewrite equiv -?proof_term¶
Use an equivalence to rewrite a reachability goal.
First, try to resolve
proof_term
as an equivalenceequiv (diff(u,v))
. Then, try to find a contextC
that does not contain anynames
, diff-terms or macro terms such that the current local goalphi
is convertible withC[u]
. If such a context is found, the current goal is is changed toC[v]
.If a
-
sign is added in front ofproof_term
, the rewriting occurs in the other direction, replacingv
withu
.Example: Hash rewrite
Consider the following goal.
- [goal> Focused goal (1/1):
- System: default/left (equivalences: left:default/left, right:default/right)
- H: equiv(diff(h (a, k), n), diff(h (b, k), m))
- U: [a <> b]
- —————————————-
- h (a, k) <> h (b, k)
Assuming we have been able to prove that two hashes are indistinguishable from names, we have hypothesis
H
. We then useH
to replace the hashes with names in the conclusion of the goal, where we want to prove that the two hashes are not equal.Calling
rewrite equiv H
produces the new goal:- [goal> Focused goal (1/1):
- System: default/right (equivalences: left:default/left, right:default/right)
- H: equiv(diff(h (a, k), n), diff(h (b, k), m))
- U: [a <> b]
- —————————————-
- n <> m
- TraceTactic smt ~prover? ~slow? pure?~ ~style?¶
Try to discharge the current goal using an SMT solver.
The provers called can be chosen using the flag ~prover, any combination of CVC4 (CVC4) Z3 (Z3) and Alt-Ergo (AltErgo) can be used. The alternative counterexamples can be used by adding (_counterexamples) after the name of the prover. The same goes with alternatives (_BV) for Alt-Ergo and (_noBV) for Z3. The time before the timeout can be increased by setting the flag ~slow to true. We can restrict the tactic to pure trace formulas by setting the flag ~pure to true. The theory used to translate timestamps is chosen using the flag ~style. We can chose to translate timestamps to integers (nat) or to an abstract type with the usual equality (abstract_eq) or not (abstract).
- TraceTactic subst term, term¶
If
x = t
wherex
is a variable, thensubst x, t
substitutes all occurrences ofx
witht
and removesx
from the logical variables.- Error Unequal arguments¶
Terms given as argument are not equal.
Global tactics¶
- EquivTactic cs pattern in position?¶
Performs case study on conditionals inside an equivalence.
Without a specific target,
cs phi
will project all conditionals on phi in the equivalence. With a specific target,cs phi in i
will only project conditionals in the i-th item of the equivalence.Example
When proving an equivalence
- equiv(if phi then t1 else t2, if phi then u1 else u2)
invoking
cs phi
results in two sub-goals:- equiv(phi, t1, u1)
- equiv(phi, t2, u2)
- Error Argument of cs should match a boolean.¶
- Error Did not find any conditional to analyze.¶
- EquivTactic deduce position?¶
deduce i
removes thei
’th element from the bi-frame when it can be computed from the rest of the bi-frame. Without any argument, it will remove the first element that can be dropped, if it exists.Here, the fact that the bi-frame element
u
can be computed from the other bi-frame elementsx,y,...
means that there exists a contextC
made of function applications such thatu
is equal toC[x,y,..]
.This relies on some heuristical automated reasoning. Some properties on macros are automatically exploited, e.g. that for any timestamp
t
,frame@pred(t)
allows to deduceinput@t
, allframe@t'
fort' < pred(t)
, as well as theoutput@t'
for wheneverexec@t'
is true.
- EquivTactic diffeq¶
Close a reflexive goal up to equality. That is, if all diff-term whitin the global goal’s conclusion always evaluate to the same value in all systems, the equivalence holds. For each diff-term, a dedicated sub-goal is created.
Warning
This tactic is still at an experimental development stage. We do not recommend its usage.
Cryptographic tactics¶
Cryptographic tactics enable reasoning over cryptographic and probabilistic properties of random samplings and primitives.
Occurrence formula¶
Several reasoning techniques require tracking how a given name is
used. For instance, if the name n
does not occur at all in term
t
, then n=t
is false with overwhelming probability. To apply
a cryptographic assumption relying on a secret key, one needs to check
that all occurrences of the secret key are valid (i.e. correspond
to the key argument of the corresponding primitive).
Over macro-free terms, collecting occurrences is simply equivalent to
looking at the subterms. However, if some macros occur in t
,
typically input@ts
or output@ts
, we need to look through all
the actions that may have happened before ts
to look for
occurrences.
We define here how to build an occurrence formula that will be
reused in several tactics description. For any name n
, any term
t
and a set of allowed patterns pats
(patterns built over
the name n
and function applications), we define the formula
occurs(n,t,pats)
as the conjunction of conditions under which it
is possible that n
occurs in t
without following one of the
allowed pattern of pats:
whenever
t
contains as a subterm an occurrencen
that does not match any of the allowed patternspats
, the formula istrue
.whenever
t
contains a system-defined macro,macro@ts
, if ts is a concrete action, we simply unfold the definition of the macro, and whenever is it not concrete, we collect all actions of the formA1
such thatn
occurs in the definition of the action not as an allowed pattern, and the formulaA1<=ts
is added to the conjunction ofoccurs(n,t,pats)
.
occurs
is of course generally defined for indexed names that may
occur in indexed actions.
Example: Basic name occurrence
Consider the following process:
- name n : index->message
- channel c
- system (!_i !_j A : out(c,n(i)) | B :in(c,x);out(c,x)).
The formula occurs(n(i),input@B,none)
is equal to exists j. A(i,j) < B
.
Example: Key corruption
Consider the following process:
- name k : message
- name r : message
- senc enc,dec.
- channel c.
- system (Corr: out(c,k) | B : in(c,x);out(c,enc(x,r,k))).
To reason about the encrypted message, the key k
needs to be
secret, and thus the dynamic corruption should not have
happened. This intuition is captured by the formula
occurs(k,input@B,enc(_,r,k))
, which is equal to Corr < B
.
This formula may be imprecise, for example due to states.
Example: Imprecise state occurrence
- name n : message
- mutable s = n.
- channel c
- system (A: out(c,s) | B :in(c,x);out(c,x)).
Here, n
occurs only inside the init
action, where the
mutable state is initialized with value n
. The formula
occurs(n,input@B,none)
is then equal to init < B
.
However, the occurrence can happen only if A
did occur between
init
and B
to reveal the value of the state.
We define a precise variant precise_occurs(n,t,pats)
, that tracks
more precisely the usages of the states, and also adds the condition
that the correct value of the state is revealed if a state can contain
an occurrence of n
.
We also generalize occur to allow for collecting multiple name
occurrences at once, which is useful when we want to allow patterns depending on
two names at once (see e.g. gdh
or ddh
).
Common tactics¶
- Tactic fresh ~precise_ts? positionhypothesis_id¶
Fresh is an information-theoretically sound tactic exploiting the fact that names represent independent random samplings. This can be exploited in two ways: i) to remove a fresh name from an equivalence; or ii) to obtain that a term has a negligible probability of being equal to a fresh name.
In a local goal with conclusion
phi
, the tactic may be called on a hypothesis of the formt=n
for some namen
sampled over a type with taglarge
. For such a sampling, if termt
is computed without knowingn
, this equality can only hold with negligible probability. We may thus assume thatn
occurs int
. Accordingly, the tactic turns the conclusion into the formulaoccur(n,t,none) => phi
(see the definition of the occurrence formula).If one can then prove that
n
cannot occur int
, that is thatoccur(n,t,none)
is false, that new conclusion trivially holds. Ifoccur(n,t,none)
is trivially false, e.g. ift
is a macro-free term withoutn
as a subterm, the goal will be directly closed.Example: Name leak
Consider a small process
in(c,x); A : out(c,x);in(c,x); B: out(c,n)
, where we wish to prove thatinput@A <> n
. Intuitively, this holds asn
is only revealed afterA
has occurred.The goal corresponding to this proof will look like this:
- [goal> Focused goal (1/1):
- System: left:default/left, right:default/right
- Eq: input@A = n
- H: happens(A)
- —————————————-
- false
Calling
fresh Eq
turns the goal into:- [goal> Focused goal (1/1):
- System: left:default/left, right:default/right
- Eq: input@A = n
- H: happens(A)
- —————————————-
- B < A => false
Here, Squirrel automatically deduced that
n
can only occur insideinput@A
if the output ofB
happened beforeA
. One would conclude by using the fact, according to the process definition, this is impossible.In an equivalence goal, on the other hand, the tactic must be applied to a bi-frame element
i
of the formdiff(nL,nR)
, wherenL
,nR
are names sampled over the same type. Since samplings are independent, the two names are indistinguishable, unless some information on them is revealed by the rest of the bi-frame. Note that, contrary to the local case, that property holds even if the type is notlarge
.If we let
bf
denote the bi-frame, the :g:ì`th bi-frame element is replaced by the tactic with- if not(diff(occur(nL,bf,i : diff(nL,nR)),occur(nR,bf,i : diff(nL,nR)))) then
- zero
- else
- diff(nL,nR)
We specify through the occurrence formula that the only possible occurrence of
nL
is in fact the one we are currently looking at.In all cases, the
precise_ts
makes the tactic use precise_occur instead of occur.Latest formal Squirrel description: [BKL23] (Appendix F).
Local tactics¶
- TraceTactic cdh hypothesis_id, term¶
This tactic applies the Computational Diffie-Hellman assumption (see e.g. [OP01]), stating for a generator \(g\) and randomly sampled exponents \(a\) and \(b\), it is computationally hard to compute \(g^{ab}\) when only \(g^a\) and \(g^b\) are known.
A
cdh
,ddh
orgdh
group declaration must have been specified (the DDH or GDH assumptions indeed both imply the CDH assumption). For a group with generatorg
and exponentiation^
, the tacticcdh M, g
may be called in a local goal on a message equality hypothesisM
of the form t=g^{a b}. Following the CDH assumption,M
can only hold ift
accessesa
orb
in some way other thang^a
andg^b
.Therefore, the tactic will replace in the current goal the conclusion
phi
withoccur(a,t,g^a) || occur(b,t,g^b) => phi
(see the definition of the occurrence formula). If both occurrence formulas are trivially false, then the goal is closed automatically.A formal description of this tactic has not yet been given in any published work.
- TraceTactic gdh hypothesis_id, term¶
This tactic applies the Gap Diffie-Hellman assumption (see e.g. [OP01]), which is similar to CDH over \(g^a\) and \(g^b\), except that the attacker is additionally allowed to access an oracle testing equality to \(g^{ab}\). It also includes the Square-GDH variant (see [FS11]), which is equivalent to the GDH assumption for prime order groups, where the attacker can also test equality to \(g^{aa}\) and \(g^{bb}\).
A
gdh
group declaration must have been specified.The behaviour of this tactic is similar to
cdh
, expect that the current goal’s conclusionphi
is replaced with a more permissive formulaoccur((a,b),t,(g^a,g^b,_=g^(ab), _=g^(bb), _=g^(aa)) => phi
(see the definition of the occurrence formula).A formal description of this tactic has not yet been given in any published work.
- TraceTactic collision¶
Requires a hash function declaration.
This tactic applies the known-key collision resistance assumption (see e.g. the cr2-kk assumption from [GB96]).
It collects all equalities between hashes occurring at top-level in message hypotheses, that is all hypotheses of the form
h(u,k)=h(v,k)
, and for each such hypothesis adds as new hypothesisu=v
.As this implements the known-key variant of the collision resistance assumption, no side condition is checked on the hash key.
Latest formal Squirrel description: [BKL23] (only as an example).
- TraceTactic euf hypothesis_id¶
Requires either a hash function or a signature scheme declaration.
This tactic applies the EUF-CMA axiom in a local goal, either for keyed-hashes or signatures. (see e.g. [GB96])
For a hash function
h(x,k)
, one may calleuf M
over a message equalityM
of the formt = h(m,k)
orh(m,k)=t
. EUF-CMA then states that, provided the keyk
is always used in correct position,M
can only hold if computingt
requires already knowing the hash ofm
. Accordingly, the tactic creates a first new sub-goal asking to prove that the key is only used in correct position, i.e. a sub-goal with conclusionnot(occur(k,goal,h(_,k))
(see the definition of the occurrence formula). The tactic then collects all possible occurrence of a honest hashh(u,k)
insidet
, and for each of them, creates a sub-goal with the original conclusion and a new hypothesis stating thatm=u
. Moreover, if the occurrence is under a macro, additional new hypotheses will state that these macros must be taken at an earlier timestamp thant
.Example: Basic hashing
Consider the following system:
- hash h
- name k:message
- channel c
- name n : message
- name m : message
- system (!_i out(c,h(n,k)) | in(c,x);out(c,x)).
Calling
euf
over a hypothesis of the forminput@tau <> h(m,k)
would add the fact thath(m,k)
needs to be equal to one of the honestly computed hashes appearing ininput@tau
, which are all of the formh(n,k)
. The new hypothesis would then be:- (exists (i:index), A(i) < tau && m = n)
For a signature function
sign(x,r,k)
, public keypk(k)
and verification functioncheck(s,m,pub)
,euf
must be called on a hypothesis of the formcheck(s,m,pk(k))
. The behaviour is then similar to the hash case: honest signatures that may occur ins
will be collected, andm
must be equal to one of the honestly signed messages. A sub-goal for each possible honest signing case is created, as well as a sub-goal specifying that the key is correctly used, i.e. with conclusionnot(occur(k,goal,sign(_,k), pk(k))
.Latest formal Squirrel description: [BKL23].
- TraceTactic intctxt hypothesis_id¶
This tactic applies the INT-CTXT assumption (see e.g. [BN00]) in a local goal.
It requires the declaration of a symmetric encryption scheme.
It can be applied to a hypothesis either of the form
dec(c,k)<>fail
ordec(c,k) = t
(in the latter case, it will generate as an additional proof obligation that t <> fail).The INT-CTXT assumption then states that, provided the key
k
is correctly used, such a decryption may only succeed ifc
was produced by an honest encryption.In both cases, Squirrel will thus collect all honest encryptions made with key
k
, and produce a subogal corresponding to each case wherec
is equal to one of those honest encryptions.The key
k
must only be used in key position, so a sub-goal asking to prove thatnot(occur(k,c,(enc(_,_,k),dec(_,k)))
is created when it is not trivially true (see the definition of the occurrence formula).In addition, a goal asking to prove that all randomness used for encryption are disjoint and fresh (when it is not trivially true).
Latest formal Squirrel description: [BDJ+21].
Global tactics¶
- EquivTactic cca1 position¶
This tactic applies the IND-CCA assumption (see e.g. [BN00]) in a global goal.
It requires the declaration of a symmetric encryption or asymmetric encryption scheme.
The tactic may be called over a bi-frame element containing a term of the form
C[enc(n, r, m)]
, wherer
must be a fresh name;there is no decryption in
C
;no universal message variable occurs;
m
is a key or a public key that only appears in key position, i.e. underpk
,dec
orenc
.
The tactic will then replace the encryption occurrence by an encryption of a bitstring of zeroes of the correct length, yielding
C[enc(zeroes(len(n)), r, pk(k))]
.In addition, the tactic creates a sub-goal asking to prove that all occurrences of the key and encryptions are correct. Notably, one must prove that
occur(k,bi-frame,(enc(_,_,k), dec(_,k))
(see the definition of the occurrence formula) is false (oroccur(k,bi-frame,(pk(k), dec(_,k))
) for the asymmetric case).In addition, in the asymmetric case, a sub-goal is created to prove the freshness of the random used in the encryption, with the conclusion
occur(r,bi-frame,enc(n,r,m))
.In the symmetric case, an additional sub-goal is created ensuring that all encryptions are made with distinct fresh randoms (and not just the the encryption we are looking at).
Latest formal Squirrel description:[BKL23].
- EquivTactic ddh term, term, term, term¶
This tactic applies the Decisional Diffie-Helman assumption (see e.g. [OP01]), stating that for a generator \(g\), and randomly sampled exponents \(a\), \(b\), \(c\), it is computationally hard to distinguish \(g^{ab}\) from \(g^c\), when only \(g^a\) and \(g^b\) are known.
A
ddh
group declaration must have been specified.When calling,
ddh g,a,b,k
, the goal must contain only diff terms of the formdiff(g^(ab),g^(c)))
. The tactic will close the goal if the formulaoccur((a,b,c),goal,(g^a,g^b,diff(g^(ab),c)))
instantly reduces to false (see the definition of the occurrence formula).Latest formal Squirrel description: [BDJ+21].
- EquivTactic enckp position term_pat? term?¶
ENC-KP assumes that a symmetric or an asymmetric encryption scheme does not leak any information about the public (or secret) key used to encrypt the plaintext. It is based on the IK-CPA notion of [BBDP01].
The tactic can be called on a bi-frame element containing a term of the form
C[enc(n, r, m)]
, wherer
must be a fresh name;there is no decryption in
C
;no universal message variable occurs;
m
is either a key or the diff of two keys, that only appear in key position, i.e. underpk
,dec
orenc
;if
m
is a key, and a second key has been given as argument to the tactic, that key must also occur only in key position.
When
m
is the diff of two keys, the diff is simplified by keeping only the key on the left. Whenm
is just one key, a new key with which it is replaced can be specified as arugment.Example: Basic ENC-KP application
On a bi-frame element of the form
- i : enc(n,r,diff(pk(k1),pk(k2)))
calling the tactic
enckp i
will simplify the bi-frame element by only keeping the key on the left, yielding- i: enc(n,r,pk(k1))
The tactic expects as arguments:
the position identifying the bi-frame element;
optional: the encryption term on which to apply the tactic;
optional: the new key with which to replace the key.
Example: Switching key with ENC-KP
On a bi-frame element of the form
- i: enc(n,r,m)
the tactic
enckp i, k
will simplify the bi-frame element by using the specified key, yielding- i: enc(n,r,pk(k))
Example: Targeted ENC-KP application
On a bi-frame element of the form
- i: ⟨ enc(n,r,m),m’⟩
the tactic
enckp i,enc(n,r,m), k
will simplify the bi-frame element by using the specified key, yielding- i: ⟨ enc(n,r,pk(k)),m ‘⟩
To apply the enckp tactic, the key
k
must be such thatoccur(k,bi-frame,(enc(_,_,k), dec(_,k))
(see the definition of the occurrence formula) is trivially false. (oroccur(k,bi-frame,(pk(k), dec(_,k))
) for the asymmetric case).When it is not trivially true, a sub-goal is created, asking to prove the freshness of the random used in the encryption, with the conclusion
occur(r,bi-frame,enc(n,r,m))
.In the symmetric case, an additional check is performed ensuring that all encryptions are made with distinct fresh randoms (and not just the encryption we are looking at).
Latest formal Squirrel description:[BDJ+21].
- EquivTactic prf position , term_pat?¶
This tactic applies the PRF assumption (see e.g. [GB96]).
It requires a hash function declaration.
This tactic applied to a bi-frame element containg a hash application
h(m,k)
tries to replace the hash value with a fresh name, under the condition thatm
has never been hashed before, and that the keyk
is correctly used.Formally, when called over a bi-frame element
i : C[h(m,k)]
, the tactic replaces in the current goal the element withi : C[nPRF]
wherenPRF
is a newly generated unique name. It in addition produces sub-goals requiring to prove the side conditions described above. It notably produces a goal asking to prove that the key is only used in key position, i.e. thatoccur(k,bi-frame,h(_,k))
is false (see the definition of the occurrence formula). In addition, it creates for each occurrence ofh(t,k)
within the bi-frame (that may occur under macros) a sub-goal asking to prove thatt <> m
, that is, thatm
was never hashed before. Such sub-goals may need to be created separately for both projections of the bi-frame.Example: Basic PRF application
Consider the following system:
- channel c
- hash h
- name k : message
- name n :message
- name m :message
- name p :message
- system (A: out(c,h(n,k)) | B: out(c,h(m,k))).
When trying to prove that
[happens(A)] -> equiv(frame@pred(A),diff(output@A,p))
, one may call the tactic prf on the bi-frame element corresponding to thediff(output@A,p)
, which after expanding output isdiff(h(n,k),p)
.This replaces in the current goal the hash occurrence with
diff(n_PRf,p)
, and creates a sub-goal asking to prove that the hash messagen
is different from any possible previously hashed message. Here, the only other possible hash would occur inframe@pred(A)
, in the output ofB
if it occurred beforeA
. The created sub-goal then asks to prove that[B < A => n <> m]
.If multiple occurrences of hashes occur in the bi-frame element, the first one is targeted by default. Calling the tactic with an optional
term_pat
allows to target a specific hash occurrence.Latest formal Squirrel description: [BKL23].
- EquivTactic xor position , term_pat? , term_pat?¶
This tactic applies the unconditionally sound one time pad property of the xor operation.
The tactic applied to a bi-frame element of the form
i : C[n XOR t]
will replace the XOR term by- if occur(n,bi-frame, i : C[n XOR t] ) && len(n) = len(t) then n_FRESH else (n XOR t)
This new term then allows us to drop the old term only if
n
andt
do have the same length (as the one time pad does not work otherwise), and if this is the only occurrence ofn
in the bi-frame.When multiple XOR occur in the bi-frame, one can specify one or two optional term patterns, to specify in any order the name
n
or the full XOR-ed termn XOR t
to target.Latest formal Squirrel description: [BDJ+21].
Utility tactics¶
- Tactic help tacnconcise?¶
When used without arguments, display all available commands. The tactic can also display the details for a given tactic name, or display or more concise list. It is a tactic and not a command, and as such can only be used inside proofs.