Declarations¶
Declarations allow to introduce the various kinds of objects that are used to model protocols and security properties in Squirrel. Declared objects may be purely abstract, carry assumptions, or have a concrete, explicit meaning.
Terms¶
Names¶
Names are used to model random samplings.
name_id::=
ident
- Declaration name name_id : type ->? type¶
A name declaration
name name_id : typei ->? types
introduces a new name symbolname_id
optionally indexed bytypei
and sampling values of typetypes
.Whenever a name
n
is defined, a corresponding namelength axiom is declared as:- axiom [any] namelength_n : [len (n) = namelength_message]
It states that all names have the same length, given by a constant.
It is required that the indexing type
typei
is a finite type, but there are no restrictions over the sampling typetypes
.The sampling distribution used over the sampling type
types
is usually arbitrary — though it can be restricted using type tags.
Two distinct applied name symbols, or the same name symbol applied to
two different index values, denote independent random samplings
(using the same distribution).
This is reflected by the fresh
tactic.
Abstract functions¶
Abstract functions model arbitrary functions over which no assumptions are made, apart from the fact that they are deterministic and polynomial-time computable. In other words, their implementation cannot depend on the random tapes, but it may still depend on the security parameter \(\eta\). If needed, their behaviour can be restricted further through axioms.
fun_id::=
ident | (infix_op)
- Declaration abstract fun_id [tvar_params]? : type¶
Declares a deterministic and polynomial-time computable abstract function of type
type
and namedfun_id
.The function can be polymorphic through the optional
tvar_params
type variable parameters.
An abstract function must be used in prefix notation if its name is an
ident
, and in infix notation if its name is an
infix_op
(note the parentheses around (infix_op)
in the
declaration).
Example
Equality is defined in Squirrel as an axiomatized polymorphic abstract function:
- abstract (=) [’a] : ‘a -> ‘a -> bool
Operators¶
Operators are function symbols with a concrete user-defined semantics. An operator’s semantics must be deterministic.
operator_id::=
ident | (infix_op)
- Declaration op operator_id [tvar_params]? binders : type? = term¶
Declares an operator named
op_id
, with argumentsbinders
and returningterm
.The return type
type
can be provided, or left to be automatically inferred by Squirrel.Operator declarations can be polymorphic through the optional
tvar_params
type variable parameters.An operator declaration fails if Squirrel cannot syntactically check that its body represents a deterministic value.
An operator must be used in prefix notation if its name is an
ident
, and in infix notation if its name is an
infix_op
(note the parentheses around (infix_op)
in the
declaration).
Built-ins¶
Squirrel features several built-in function symbols with built-in axiomatizations.
if term then term else term
, used in terms, may theoretically be viewed as a built-in.happens(term)
,pred(term)
andinit
are three function symbols dealing with the timestamp type. Each model instantiates the set of timestamps by specifying which ones actually happen on the given trace, and for all the ones that happen, their total ordering,init
refering to a fixed first timestamp andpred
being the predecessor function.The boolean connectors of local formulas are built-ins:
true
,false
,&&
,||
,=>
,<=>
andnot
.Comparison functions
=
,<>
,<=
,<
,>=
and>
.A witness function
witness
.A dedicated
xor
symbol along with itszero
.A conversion function from
bool
tomessage
,of_bool
.Utility constants for failure,
fail
, and an empty message,empty
.The successor function over natural numbers succ.
The pairing function
pair
(also noted<x,y>
) with its projection functionsfst
andsnd
.A length function for the number of bits in a message,
len
, as well as a function producing a bitstring of zeroes of the same length as its input,zeroes
.
Cryptographic functions¶
Squirrel allows to declare functions modelling standard cryptographic functions with associated cryptographic assumptions.
crypto_ty_arg::=
ident : type
Types over which the cryptographic functions operate can be specified
using crypto_ty_arg
, where ident:type
states that the argument
named ident
is of type type
. See the declarations below for
a description of which argument names can be provided for each tactic.
If no argument is provided for ident
, type
default to message
.
- Declaration hash fun_id where crypto_ty_arg+?¶
- hash h where m:tym h:tyh k:tyk
declares a keyed hash function with types
tyk
for keys,tym
for messages andtyh
for hash digests. It is assumed to satisfy the PRF and known-key collision resistance assumptions.
- Declaration signature fun_id, fun_id, fun_id where crypto_ty_arg+?¶
- signature sig, ver, pk where m:tym sig:tysig sk:tysk pk:typk
declares a signature scheme with types
tym
for messages to be signed,tysig
for signatures,tysk
for secret signing keys andtypk
for public verification keys. It is assumed unforgeable against chosen message attacks (EUF-CMA) and satisfying the equationver(sig(m,sk),m,pk(sk)) = true
.Enables the use of
euf
.
- Declaration aenc fun_id, fun_id, fun_id where crypto_ty_arg+?¶
- aenc enc, dec, pk where ptxt:typtxt ctxt:tyctxt rnd:tyrnd sk:tysk pk:typk
declares an asymmetric encryption scheme with types
typtxt
for plain-texts,tyctxt
for cipher-texts,tyrnd
for encryption randomness,tysk
for secret decryption keys andtypk
for public encryption keys. It is assumed IND-CCA1 and ENC-KP, and satisfying the equationdec(enc(m,pk(sk)),sk) = m
.
- Declaration senc fun_id, fun_id, fun_id where crypto_ty_arg+?¶
- senc enc, dec where ptxt:typtxt ctxt:tyctxt rnd:tyrnd k:tyk
declares a symmetric encryption scheme with types
typtxt
for plain-texts,tyctxt
for cipher-texts,tyrnd
for encryption randomness andtyk
for keys. It is assumed IND-CPA and INT-CTXT, and satisfying the equationdec(enc(m,sk),sk) = m
.
- Declaration ddhcdhgdh fun_id, fun_id ,fun_id? where crypto_ty_arg+?
The group declaration:
- ddh g, (^), ( ** ) where group:tyg exponents:tye
declares a group with generator
g
, exponentation(^)
and exponent multiplication( ** )
. The group is assumed to satisfy the DDH assumption when declared withddh
, the CDH assumption withcdh
, and the Gap-DH assumption with g:gdh.
Processes¶
Protocols are modelled as systems, which provide a meaning to macros
(e.g., output
, cond
) used in our logic. Systems are themselves
defined through processes written in a dialect of the applied pi-calculus.
Note
The first presentations of Squirrel’s logic relied explicitly on notions of systems, first without state [BDJ+21] and then with state [BDKM22]. The latest presentation [BKL23] does not feature a notion of system, but allows to encode systems through a more expressive logic. So far, the translation from processes to systems has not been formally defined in the literature.
Channels¶
Communications over the network are performed over public channels, identified by a name.
channel_id::=
ident
- Declaration channel channel_id¶
Declares a channel named
channel_id
.
Memory cells¶
Processes in Squirrel can use mutable states.
state_id::=
ident
- Declaration mutable state_id binders : type? = term¶
Declares a memory cell named
state_id
indexed by argumentsbinders
and initialized toterm
. Due to technical limitations, Squirrel currently only supportsbinders
of finite type.The return type
type
can be provided, or left to be automatically inferred by Squirrel.
Example: State counter
A set of mutable counters indexed by i,j,k
, all initialized
to zero
, may be declared as follows:
- mutable counter (i,j,k:index) : message = zero
With this declaration, the following formula is valid:
- forall i j k, counter i j k @ init = zero
Processes¶
We first introduce process prefixes, which correspond to basic operations performed by processes:
process_prefix::=
new name_id
|
state_id term*? := term
|
out(channel, term)
|
in(channel, term)
The last three prefixes correspond to the update of a memory cell, and input and asynchronous output over a channel. Their semantics is straightforward.
From a process semantics viewpoint, new name
samples a new
random value. From a logical viewpoint, this is reflected by
declaring a new name, indexed by the current replication indices. This
is syntactic sugar that can be avoided by manually declaring the
needed name symbols with the appropriate arities before the process
declaration.
Processes are then built from prefixes using parallel composition, (indexed) replication and conditionals, as well as other common constructs:
process_id::=
ident
alias::=
ident
process::=
null
|
process_prefix
|
process_prefix; process
|
process | process
|
if term then process else process?
|
try find binders such that term in process else process?
|
let ident = term in process
|
!_ident process
|
process_id (term*,)?
|
alias : process
The construct A : proc
does not have any semantic impact: it is
only used to give an alias to this location in the process.
- Declaration process process_id binders = proc¶
Declares a new process named
process_id
with argumentsbinders
and bodyprocess
.
Systems and actions¶
Squirrel’s logic only deals with systems, which are obtained by translating protocols. Systems are (partially ordered) sets of actions, which correspond to atomic execution steps of a protocol comprising:
the reception of a message input from the (malicious) network;
the verification of an executability condition;
and, if the action is executable, the output of a message to the network.
A system can currently only be defined from a process. For the same reasons that make multi-terms useful, it is useful to define multiple systems at once (i.e., a multi-system) using a process featuring multi-terms.
system_id::=
ident
- Declaration system [system_id]? process¶
Declare a bi-system whose actions are obtained by translating
process
, which may use bi-terms. The obtained single systems can be referred to assystem_id/left
andsystem_id/right
. The left (resp. right) single system corresponds to the process obtained by taking the left (resp. right) projections of all bi-terms appearing inprocess
.The system name
system_id
defaults todefault
when no identifier is specified.
Actions are referred to through identifiers:
action_id::=
ident
When translating processes into sets of actions, fresh action
identifiers are automatically generated to name created
actions. Alternatively, the user can give a naming hint using the
alias
process construct. Note however that Squirrel may not
respect such naming hints.
Internally, an action is defined by:
an action identifier or constructor
action_id
;a list of
index
variables corresponding to surrounding replications andtry find
constructs;a
term
of typebool
representing the action executability condition;a term of type
message
representing the action output.
Example: Actions corresponding to a process definition
Consider the following system declaration:
- abstract one : message.
- name n : index -> message.
- channel c.
- system
- (!_i (in(c,x);
- if x=zero then
- A: out(c,n(i))
- else
- B: out(c,x)
- ) | in(c,x); out(c,empty)).
The provided process yields a system with three actions:
action
A(i)
, which on inputx
checks whetherx=zero
and outputsn(i)
;action
B(i)
, which on inputx
checks whetherx<>zero
and outputsx
;and action
A1
(automatically named) which checks whethertrue
and outputsempty
.
System-defined macros¶
Declaring a system provides a meaning to several macros for the
system’s actions. Given an action A(indices)
with output value o(x)
and condition c(x)
over the input x
,
the following holds:
output@A(indices) = o(input@A(indices))
;cond@A(indices) = c(input@A(indices))
;input@A(indices) = att(frame@pred(A(indices)))
.
Other macros have a meaning that does not depend on the specific action:
frame@tau = <frame@(pred tau), exec@tau, if exec@tau then output@tau>
provided thattau
happens and is not the initial timestampinit
(otherwise,frame@tau
isempty
);exec@tau = exec@(pred tau) && cond@tau>
provided thattau
happens and is not the initial timestampinit
(otherwise,exec@init
istrue
).
System expressions¶
System expressions describe one or several systems. We first introduce single system expressions:
single_system_expr::=
system_id/left | system_id/right
Here, system_id/proj
is an unlabelled single system
representing the left (if proj = left
) or right (if proj = right
)
component of the bi-system named system_id
.
::=
any | system_id | single_system_expr*,
A system expression may be generic (any
, corresponding to any system,
already declared or not) or specify a fixed list of systems, each
of them coming with a label identifying it.
When system_id
is a multi-system,
the system expression system_id
corresponds to the list of
its single systems, with the labels that they carry in this multi-system.
A system expression can also be explicitly formed as
single_system_expr1,...,single_system_exprn
.
In this case, the labels are:
ε if
n = 1
;
left
andright
ifn = 2
;the
n
first positive integers otherwise.
System contexts¶
system_context::=
set: system_expr; equiv: system_expr
|
system_id
A concrete system context set:S; equiv:P
comprises:
a multi-system specified by
S
used to interpret reachability atoms;a pair of systems (i.e. a multi-system with two elements)
P
used to interpret equivalence atoms.
A system_id
S
can also be used as a system context:
it stands for set:S; equiv:S/left,S/right
.
Axioms and Lemmas¶
Squirrel supports two kinds of lemmas, one for each kind of formulas: local lemmas for local formulas and global lemmas for global formulas. Similarly, there are local and global axioms. The only difference between a lemma and an axiom declaration is that the former creates a proof-obligation that must be discharged by the user through a proof.
statement_id::=
ident
local_statement::=
[system_expr]? statement_id_ [tvar_params]? binders : formula
global_statement::=
[system_context]? statement_id_ [tvar_params]? binders : global_formula
A local statement as described above expresses that
the local formula forall binders, formula
holds
in the context [system_expr]
(which
defaults to [default]
).
The statement is named statement_id
for future reference.
Similarly,
a global statement expresses that
Forall binders, global_formula
holds in the context
[system_context]
(which defaults to [default]
).
Local and global statements can be
polymorphic through the optional
tvar_params
type variable parameters (they hold for all
instances of the given type variables).
Unnamed (local and global) statements can be declared using an
underscore _
instead of a statement identifier
statement_id
.
- Declaration local? lemmaaxiom local_statement¶
Declares a new local
lemma
oraxiom
.
- Declaration global lemmaaxiom global_statement¶
Declares a new global
lemma
oraxiom
.
Example: Local axioms and lemmas
We declare an axiom stating
that in any system, a pair has a negligible probability of
being equal to the constant fail
.
- axiom [any] fail_not_pair (x,y:message): <x,y> <> fail
Next, we state that in system [default]
,
the adversary never sends the same message twice.
- axiom no_repeat t t’ : happens(t,t’) => t <> t’ => input@t <> input@t’
Finally, the following unnammed local lemma states that, for the
single system myProtocol/left
,
action A2
can execute only if the adversary sends the message
ok
at time-point A1:
- lemma [myProtocol/left] _ : cond@A2 => input@A1 = ok
Example: Global lemmas
The next (typical) global lemma states that the two projections
of the bi-system myProtocol
are observationally equivalent:
- global lemma [myProtocol] obs_equiv (t:timestamp[const]) : [happens(t)] -> equiv(frame@t)
As a slight variant,
we now state that real/left
and ideal/right
are observationally equivalent, this time using only real/left
to interpret [_]
atoms (which does not change anything in that
case since happens(_)
does not depend on the details of system
actions):
- global lemma [set: real/left; equiv: real/left,ideal/right] ideal_real_equiv :
- Forall (tau:timestamp[const]), [happens(tau)] -> equiv(frame@tau)