Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Benoit Viguier
coq-verif-tweetnacl
Commits
82f2b86e
Commit
82f2b86e
authored
May 28, 2019
by
Benoit Viguier
Browse files
9.75 pages
parent
f920cbbe
Changes
2
Hide whitespace changes
Inline
Side-by-side
readings/2_Implementation.tex
View file @
82f2b86e
...
...
@@ -296,7 +296,7 @@ in Coq (for the sake of simplicity we do not display the conversion in the theor
For all
$
n
\in
\N
, n <
2
^{
255
}$
and where the bits 1, 2, 5 248, 249, 250
are cleared and bit 6 is set, for all
$
P
\in
E
(
\F
{
p
^
2
}
)
$
,
for all
$
p
\in
\F
{
p
}$
such that
$
P.x
=
p
$
,
there exists
$
Q
\in
E
(
\F
{
p
^
2
}
)
$
such that
$
Q
=
nP
$
,
$
Q.x
=
q
$
and
$
q
$
=
\VSTe
{
CSM
}
$
n
$
$
p
$
.
there exists
$
Q
\in
E
(
\F
{
p
^
2
}
)
$
such that
$
Q
=
nP
$
where
$
Q.x
=
q
$
and
$
q
$
=
\VSTe
{
CSM
}
$
n
$
$
p
$
.
\end{theorem}
A more complete description in Coq of Theorem
\ref
{
CSM-correct
}
with the associated conversions
is as follow:
...
...
readings/4_NumberAndImplementation.tex
View file @
82f2b86e
\section
{
Linking C and
Coq
}
\section
{
Linking C and
Reflections
}
In this section we describe techniques used to prove the equivalence between the
Clight description of TweetNaCl and Coq functions producing similar behaviors.
...
...
@@ -8,27 +8,38 @@ Clight description of TweetNaCl and Coq functions producing similar behaviors.
As described in Section
\ref
{
sec:impl
}
, numbers in
\TNaCle
{
gf
}
are represented
in base
$
2
^{
16
}$
and we can use a direct mapping to represent that array as a list
integers in Coq. However in order to show the correctness of the basic operations,
we need to convert this number as a full integer. For this reason we define
\Coqe
{
ZofList : Z -> list Z -> Z
}
:
\begin{Coq}
we need to convert this number as a full integer.
\begin{definition}
Let
\Coqe
{
ZofList
}
:
$
\Z
\rightarrow
\texttt
{
list
}
\Z
\rightarrow
\Z
$
, a parametrized map by
$
n
$
betwen a list
$
l
$
and its
it's little endian representation with a base
$
2
^
n
$
.
\end{definition}
We define it in Coq as:
\begin{lstlisting}
[language=Coq]
Fixpoint ZofList
{
n:Z
}
(a:list Z) : Z :=
match a with
| [] => 0
| h :: q => h + (pow 2 n) * ZofList q
end.
\end{lstlisting}
We define a notation where
$
n
$
is
$
16
$
.
\begin{lstlisting}
[language=Coq]
Notation "Z16.lst A" := (ZofList 16 A).
\end{Coq}
It converts any list of integer from a base
$
2
^
n
$
to an single integer. In our
case we define a notation where
$
n
$
is
$
16
$
.
The following Coq notation is defined to convert any integer to its representant
in
\Zfield
.
\begin{Coq}
\end{lstlisting}
We also define a notation to do the modulo, projecting any numbers in
$
\Zfield
$
.
\begin{lstlisting}
[language=Coq]
Notation "A :GF" := (A mod (2
^
255-19)).
\end{Coq}
\end{lstlisting}
Remark that this representation is different from
\Coqe
{
Zmodp
}
.
However the equivalence between operations over
$
\Zfield
$
and
$
\F
{
p
}$
is easily proven.
Using these two definitions, we proved lemmas such as the correctness of the
multiplication
\Coqe
{
M
}
:
Using these two definitions, we proved intermediates lemmas such as the correctness of the
multiplication
\Coqe
{
M
}
where
\Coqe
{
M
}
replicate the computations and steps done in C.
\begin{lemma}
For all list of integers
\texttt
{
a
}
and
\texttt
{
b
}
of length 16 representing
$
A
$
and
$
B
$
in
$
\Zfield
$
, the number represented in
$
\Zfield
$
by the list
\Coqe
{
(M a b)
}
is equal to
$
A
\times
B
\bmod
\p
$
.
\end{lemma}
And seen in Coq as follows:
\begin{Coq}
Lemma mult
_
GF
_
Zlength :
forall (a:list Z) (b:list Z),
...
...
@@ -38,14 +49,10 @@ Lemma mult_GF_Zlength :
(Z16.lst a * Z16.lst b) :GF.
\end{Coq}
For all list of integers
\texttt
{
a
}
and
\texttt
{
b
}
of length 16 representing
$
A
$
and
$
B
$
in
\Zfield
, the number represented in
\Zfield
by the list
\Coqe
{
(M a b)
}
is equal to
$
A
\times
B
\bmod
2
^{
255
}
-
19
$
.
\subsection
{
Inversions in
\Zfield
}
In a similar fashion we can define a Coq version of the inversion mimicking
the behavior of
\TNaCle
{
inv25519
}
over
\Coqe
{
list Z
}
.
\Coqe
{
step
_
pow
}
contains
the body of the for loop.
the behavior of
\TNaCle
{
inv25519
}
over
\Coqe
{
list Z
}
.
\begin{lstlisting}
[language=Ctweetnacl]
sv inv25519(gf o,const gf a)
{
...
...
@@ -59,18 +66,15 @@ sv inv25519(gf o,const gf a)
FOR(i,16) o[i]=c[i];
}
\end{lstlisting}
\begin{Coq}
We specify this with 2 functions: a recursive
\Coqe
{
pow
_
fn
_
rev
}
to to simulate the for loop and a simple
\Coqe
{
step
_
pow
}
containing the body. Note the off by one for the loop.
\begin{lstlisting}
[language=Coq]
Definition step
_
pow (a:Z) (c g:list Z) : list Z :=
let c := Sq c in
if a <>? 1
&&
a <>? 3
then M c g
else c.
\end{Coq}
\Coqe
{
pow
_
fn
_
rev
}
is responsible of the iteration of the loop by making
recursive calls.
\begin{Coq}
Function pow
_
fn
_
rev (a:Z) (b:Z) (c g: list Z)
{
measure Z.to
_
nat a
}
: (list Z) :=
if a <=? 0
...
...
@@ -78,23 +82,46 @@ Function pow_fn_rev (a:Z) (b:Z) (c g: list Z)
else
let prev := pow
_
fn
_
rev (a - 1) b c g in
step
_
pow (b - 1 - a) prev g.
\end{Coq}
% This \Coqe{Function} requires a proof of termination. It is done by proving the
% Well-foundness of the decreasing argument: \Coqe{measure Z.to_nat a}.
\end{lstlisting}
Calling
\Coqe
{
pow
_
fn
_
rev
}
254 times allows us to reproduce the same behavior as
the Clight definition.
\begin{Coq}
This
\Coqe
{
Function
}
requires a proof of termination. It is done by proving the
Well-foundness of the decreasing argument:
\Coqe
{
measure Z.to
_
nat a
}
. Calling
\Coqe
{
pow
_
fn
_
rev
}
254 times allows us to reproduce the same behavior as the
\texttt
{
Clight
}
definition.
\begin{lstlisting}
[language=Coq]
Definition Inv25519 (x:list Z) : list Z :=
pow
_
fn
_
rev 254 254 x x.
\end{Coq}
\end{lstlisting}
Similarily we define the same function over
$
\Z
$
.
\begin{lstlisting}
[language=Coq]
Definition step
_
pow
_
Z (a:Z) (c:Z) (g:Z) : Z :=
let c := c * c in
if a <>? 1
&&
a <>? 3
then c * g
else c.
\subsection
{
Inversions and Reflections
}
Function pow
_
fn
_
rev
_
Z (a:Z) (b:Z) (c:Z) (g: Z)
{
measure Z.to
_
nat a
}
: Z :=
if (a <=? 0)
then c
else
let prev := pow
_
fn
_
rev
_
Z (a - 1) b c g in
step
_
pow
_
Z (b - 1 - a) prev g.
In TweetNaCl,
\TNaCle
{
inv25519
}
computes an inverse in
\Zfield
. It uses the
Fermat's little theorem by the exponentiation to
$
2
^{
255
}
-
21
$
. To prove the
correctness of the result we can use multiple strategy such as:
Definition Inv25519
_
Z (x:Z) : Z :=
pow
_
fn
_
rev
_
Z 254 254 x x.
\end{lstlisting}
And prove their equivalence in
$
\Zfield
$
.
\begin{lstlisting}
[language=Coq]
Lemma Inv25519
_
Z
_
GF : forall (g:list Z),
length g = 16 ->
(Z16.lst (Inv25519 g)) :GF =
(Inv25519
_
Z (Z16.lst g)) :GF.
\end{lstlisting}
In TweetNaCl,
\TNaCle
{
inv25519
}
computes an inverse in
$
\Zfield
$
. It uses the
Fermat's little theorem by doing an exponentiation to
$
2
^{
255
}
-
21
$
.
This is done by applying a square-and-multiply algorithm. The binary representation
of
$
p
-
2
$
implies to always do a multiplications aside for bit 2 and 4, thus the if case.
To prove the correctness of the result we can use multiple strategies such as:
\begin{itemize}
\item
Proving it is special case of square-and-multiply algorithm applied to
a specific number and then show that this number is indeed
$
2
^{
255
}
-
21
$
.
...
...
@@ -102,94 +129,44 @@ correctness of the result we can use multiple strategy such as:
$
x
^
a
\times
x
^
b
=
x
^{
(
a
+
b
)
}$
and
$
(
x
^
a
)
^
2
=
x
^{
(
2
\times
a
)
}$
. We can prove that
the resulting exponent is
$
2
^{
255
}
-
21
$
.
\end{itemize}
We choose the second method. The only drawback is that it requires to apply the
unrolling and exponentiation lemmas 255 times. This can be automated in Coq with
tacticals such as
\Coqe
{
repeat
}
, but it generates a big proof object which
We use the second method for the benefits of simplicity. However it requires to
apply the unrolling and exponentiation formulas 255 times. This can be automated
in Coq with tacticals such as
\Coqe
{
repeat
}
, but it generates a proof object which
will take a long time to verify.
\subs
ubs
ection
{
Speeding up with Reflections
}
\subsection
{
Speeding up with Reflections
}
In order to speed up the verification, we use a technique called reflection.
It provides us with flexibility such as we don't need to know the
number of
times the lemmas needs to be applied.
It provides us with flexibility such as we don't need to know the number of
times
nor the order in which
the lemmas needs to be applied
(chapter 15 in
\cite
{
CpdtJFR
}
)
.
The idea is to
\textit
{
reflect
}
the goal into a decidable environment.
In our case, we show that for a property
$
P
$
, we can define a decidable
boolean property
$
P
_{
bool
}$
such that if
$
P
_{
bool
}$
is
\Coqe
{
true
}
then
$
P
$
holds.
$$
P
_{
bool
}
=
true
\implies
P
$$
With VST we proved that
\TNaCle
{
inv25519
}
in
\texttt
{
Clight
}
is equivalent to its Coq
functional definition
\Coqe
{
Inv25519
}
. We also proved that
\Coqe
{
Inv25519
}
over
\Coqe
{
list Z
}
is equivalent to applying
\Coqe
{
Inv25519
_
Z
}
over
\Coqe
{
Z
}
% With VST we proved that \TNaCle{inv25519} in \texttt{Clight} is equivalent to its Coq
% functional definition \Coqe{Inv25519}. We also proved that \Coqe{pow_fn_rev}
% over \Coqe{list Z} is equivalent to applying
% \Coqe{pow_fn_rev_Z} over \Coqe{Z}
\begin{Coq}
Lemma Inv25519
_
Z
_
GF :
forall (g:list Z),
length g = 16 ->
(Z16.lst (Inv25519 g)) :GF =
(Inv25519
_
Z (Z16.lst g)) :GF.
\end{Coq}
% \begin{Coq}
% Lemma pow_fn_rev_Z_GF :
% forall (a:Z) (b:Z) (c:list Z) (g:list Z),
% Zlength c = 16 ->
% Zlength g = 16 ->
% (Z16.lst (pow_fn_rev a b c g)) :GF =
% (pow_fn_rev_Z a b (Z16.lst c) (Z16.lst g)) :GF .
% \end{Coq}
where
\Coqe
{
Inv25519
_
Z
}
reproduces the same pattern as
\Coqe
{
Inv25519
}
.
\begin{Coq}
Definition Inv25519
_
Z (x:Z) : Z :=
pow
_
fn
_
rev
_
Z 254 254 x x.
\end{Coq}
\Coqe
{
pow
_
fn
_
rev
_
Z
}
mimicks
\Coqe
{
pow
_
fn
_
rev
}
over
\Coqe
{
Z
}
instead of
\Coqe
{
list Z
}
. The structure is the same:
the application
\Coqe
{
step
_
pow
_
Z
}
and the loop itself
\Coqe
{
pow
_
fn
_
rev
_
Z
}
\begin{Coq}
Definition step
_
pow
_
Z (a:Z) (c:Z) (g:Z) : Z :=
let c := c * c in
if a <>? 1
&&
a <>? 3
then c * g
else c.
Function pow
_
fn
_
rev
_
Z (a:Z) (b:Z) (c:Z) (g: Z)
{
measure Z.to
_
nat a
}
: Z :=
if (a <=? 0)
then c
else
let prev := pow
_
fn
_
rev
_
Z (a - 1) b c g in
step
_
pow
_
Z (b - 1 - a) prev g.
\end{Coq}
%
% In line with the definition of \Coqe{Inv25519}, we define the inversion modulo
% $2^{255}-19$ as an instance of \Coqe{pow_fn_rev_Z} where \Coqe{a} and \Coqe{b} are 254.
\subsubsection
{
A Simple Domain Specific Language
}
We show that for a property
$
P
$
, we can define a decidable boolean property
$
P
_{
bool
}$
such that if
$
P
_{
bool
}$
is
\Coqe
{
true
}
then
$
P
$
holds.
$$
reify
\_
P : P
_{
bool
}
=
true
\implies
P
$$
By applying
$
reify
\_
P
$
on
$
P
$
our goal become
$
P
_{
bool
}
=
true
$
.
We can then compute the result of
$
P
_{
bool
}$
. If the decision goes well we are
left with the tautology
$
true
=
true
$
.
To prove that the
\Coqe
{
Inv25519
_
Z
}
is computing
$
x
^{
2
^{
255
}
-
21
}$
,
we define a Domain Specific Language:
\begin{Coq}
we define a Domain Specific Language.
\begin{definition}
Let
\Coqe
{
expr
_
inv
}
denote an expression which can be either a term;
a multiplication of expressions; a squaring of an expression or a power of an expression.
And Let
\Coqe
{
formula
_
inv
}
denote an equality between two expressions.
\end{definition}
\begin{lstlisting}
[language=Coq]
Inductive expr
_
inv :=
| R
_
inv : expr
_
inv
| M
_
inv : expr
_
inv -> expr
_
inv -> expr
_
inv
| S
_
inv : expr
_
inv -> expr
_
inv
| P
_
inv : expr
_
inv -> positive -> expr
_
inv.
\end{Coq}
An expression can be either a term, a multiplication, a squaring or a power.
This is denoted as follow:
\begin{Coq}
Inductive formula
_
inv :=
| Eq
_
inv : expr
_
inv -> expr
_
inv -> formula
_
inv.
\end{lstlisting}
The denote functions are defined as follows:
\begin{lstlisting}
[language=Coq]
Fixpoint e
_
inv
_
denote (m:expr
_
inv) : Z :=
match m with
| R
_
inv =>
...
...
@@ -201,37 +178,13 @@ Fixpoint e_inv_denote (m:expr_inv) : Z :=
| P
_
inv x p =>
pow (e
_
inv
_
denote x) (Z.pos p)
end.
\end{Coq}
We defined
\Coqe
{
step
_
inv
}
and
\Coqe
{
pow
_
inv
}
to mirror the behavior of
\Coqe
{
step
_
pow
_
Z
}
and respectively
\Coqe
{
pow
_
fn
_
rev
_
Z
}
over our new domain.
\begin{Coq}
Lemma step
_
inv
_
step
_
pow
_
eq :
forall (a:Z) (c:expr
_
inv) (g:expr
_
inv),
e
_
inv
_
denote (step
_
inv a c g) =
step
_
pow
_
Z a (e
_
inv
_
denote c) (e
_
inv
_
denote g).
\end{Coq}
\begin{Coq}
Lemma pow
_
inv
_
pow
_
fn
_
rev
_
eq :
forall (a:Z) (b:Z) (c:expr
_
inv) (g:expr
_
inv),
e
_
inv
_
denote (pow
_
inv a b c g) =
pow
_
fn
_
rev
_
Z a b (e
_
inv
_
denote c) (e
_
inv
_
denote g).
\end{Coq}
We also define what is a formula in our language: a simple equality.
\begin{Coq}
Inductive formula
_
inv :=
| Eq
_
inv : expr
_
inv -> expr
_
inv -> formula
_
inv.
\end{Coq}
This is denoted as follow:
\begin{Coq}
Definition f
_
inv
_
denote (t : formula
_
inv) : Prop :=
match t with
| Eq
_
inv x y => e
_
inv
_
denote x = e
_
inv
_
denote y
end.
\end{
Coq
}
With such Domain Specific Language we have the equ
ivalence
between:
\end{
lstlisting
}
With such Domain Specific Language we have the equ
ality
between:
\begin{lstlisting}
[backgroundcolor=
\color
{
white
}
]
f
_
inv
_
denote
(Eq
_
inv (M
_
inv R
_
inv (S
_
inv R
_
inv))
...
...
@@ -239,22 +192,48 @@ f_inv_denote
= (x * x
^
2 = x
^
3)
\end{lstlisting}
\subsubsection
{
Deciding formulas
}
We define
\Coqe
{
step
_
inv
}
and
\Coqe
{
pow
_
inv
}
to mirror the behavior of
\Coqe
{
step
_
pow
_
Z
}
and respectively
\Coqe
{
pow
_
fn
_
rev
_
Z
}
over our DSL and
we prove their equality.
\begin{lstlisting}
[language=Coq]
Lemma step
_
inv
_
step
_
pow
_
eq :
forall (a:Z) (c:expr
_
inv) (g:expr
_
inv),
e
_
inv
_
denote (step
_
inv a c g) =
step
_
pow
_
Z a (e
_
inv
_
denote c) (e
_
inv
_
denote g).
Lemma pow
_
inv
_
pow
_
fn
_
rev
_
eq :
forall (a:Z) (b:Z) (c:expr
_
inv) (g:expr
_
inv),
e
_
inv
_
denote (pow
_
inv a b c g) =
pow
_
fn
_
rev
_
Z a b (e
_
inv
_
denote c) (e
_
inv
_
denote g).
\end{lstlisting}
We can then derive the following lemma.
\begin{lemma}
\label
{
reify
}
With an appropriate choice of variables,
\Coqe
{
pow
_
inv
}
denotes
\Coqe
{
Inv25519
_
Z
}
.
\end{lemma}
In order to prove formulas in
\Coqe
{
formula
_
inv
}
,
we
def
in
e
a decidable procedure.
We
first compute the power of each side of the formula and then check their
equality.
we
have the follow
in
g
a decidable procedure.
We
define
\Coqe
{
pow
_
expr
_
inv
}
, a function which returns the power of an expression.
We can then compare the two values and decide over their
equality.
\begin{Coq}
Fixpoint pow
_
expr
_
inv (t:expr
_
inv) : Z :=
match t with
| R
_
inv => 1
(* power of a term is 1. *)
| M
_
inv x y =>
(pow
_
expr
_
inv x) + (pow
_
expr
_
inv y)
(* power of a multiplication is
the sum of the exponents. *)
| S
_
inv x =>
2 * (pow
_
expr
_
inv x)
(* power of a squaring is the double
of the exponent. *)
| P
_
inv x p =>
(Z.pos p) * (pow
_
expr
_
inv x)
(* power of a power is the multiplication
of the exponents. *)
end.
Definition decide
_
e
_
inv (l1 l2:expr
_
inv) : bool :=
...
...
@@ -265,20 +244,24 @@ Definition decide_f_inv (f:formula_inv) : bool :=
| Eq
_
inv x y => decide
_
e
_
inv x y
end.
\end{Coq}
We proved that our procedure is correct: for all formulas in
\Coqe
{
formula
_
inv
}
, if
\Coqe
{
decide
_
f
_
inv
}
returns
\Coqe
{
true
}
, then the denoted equality is correct.
We prove our decision procedure correct.
\begin{lemma}
\label
{
decide
}
For all formulas
$
f
$
, if the decision over
$
f
$
returns
\Coqe
{
true
}
,
then the denoted equality by
$
f
$
is true.
\end{lemma}
Which can be formalized as:
\begin{Coq}
Lemma decide
_
formula
_
inv
_
impl :
forall (f:formula
_
inv),
decide
_
f
_
inv f = true ->
f
_
inv
_
denote f.
\end{Coq}
By reification to our Domain Specific Language and then by applying
\texttt
{
decide
\_
formula
\_
inv
\_
impl
}
and computing
\texttt
{
decide
\_
f
\_
inv
}
,
we proved that
\Coqe
{
Inv25519
}
is indeed computing an inverse in
modulo
$
2
^{
255
}
-
19
$
.
By reification to over DSL (lemma
\ref
{
reify
}
) and by applying our decision (lemma
\ref
{
decide
}
).
we proved the following theorem.
\begin{theorem}
\Coqe
{
Inv25519
_
Z
}
computes an inverse in
\Zfield
.
\end{theorem}
\begin{Coq}
Theorem Inv25519
_
Z
_
correct :
forall (x:Z),
...
...
@@ -287,7 +270,9 @@ Theorem Inv25519_Z_correct :
From
\Coqe
{
Inv25519
_
Z
_
correct
}
and
\Coqe
{
Inv25519
_
Z
_
GF
}
, we conclude the
functionnal correctness of the inversion over
\Zfield
.
\begin{corollary}
\Coqe
{
Inv25519
}
computes an inverse in
\Zfield
.
\end{corollary}
\begin{Coq}
Corollary Inv25519
_
Zpow
_
GF :
forall (g:list Z),
...
...
@@ -296,18 +281,19 @@ Corollary Inv25519_Zpow_GF :
(pow (Z16.lst g) (2
^
255-21)) :GF.
\end{Coq}
\subs
ubs
ection
{
Packing and other applications
}
\subsection
{
Packing and other applications
of reflection
}
Reflection can also be used where proofs requires computing and a small and
We prove the functional correctness of
\Coqe
{
Inv25519
}
with reflections.
This technique can also be used where proofs requires some computing or a small and
finite domain of variable to test e.g. for all
$
i
$
such that
$
0
\le
i <
16
$
.
Using reflection
s
we prove
d
that we can split the for loop in
\TNaCle
{
pack25519
}
into two parts.
Using reflection we prove that we can split the for loop in
\TNaCle
{
pack25519
}
into two parts.
\begin{lstlisting}
[language=Ctweetnacl]
for(i=1;i<15;i++)
{
m[i]=t[i]-0xffff-((m[i-1]>>16)
&
1);
m[i-1]
&
=0xffff;
}
\end{lstlisting}
The first is computing the substraction while the second is applying the carrying.
The first
loop
is computing the substraction while the second is applying the carrying.
\begin{lstlisting}
[language=Ctweetnacl]
for(i=1;i<15;i++)
{
m[i]=t[i]-0xffff
...
...
@@ -318,8 +304,8 @@ for(i=1;i<15;i++) {
}
\end{lstlisting}
This loop separation allows simpler proofs. The first loop is seen as the substraction of a number in
\Zfield
.
We then prove
d
tha
n
with the iteration of the second loop, the number represented in
\Zfield
stays the same.
This lead to the proof that
\TNaCle
{
pack25519
}
is effectively reducing mod
$
2
^{
255
}
-
19
$
and returning a number in base
$
2
^
8
$
.
We then prove tha
t
with the iteration of the second loop, the number represented in
\Zfield
stays the same.
This lead
s
to the proof that
\TNaCle
{
pack25519
}
is effectively reducing mod
$
\p
$
and returning a number in base
$
2
^
8
$
.
\begin{Coq}
Lemma Pack25519
_
mod
_
25519 :
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment