we defined a Coq definition \coqe{Crypto_Scalarmult} mimicking the exact behavior of X25519 in TweetNaCl.

By proving that each function \coqe{Low.M}; \coqe{Low.A}; \coqe{Low.Sq}; \coqe{Low.Zub};

\coqe{Unpack25519}; \coqe{clamp}; \coqe{Pack25519}; \coqe{Inv25519}; \coqe{car25519} behave over \coqe{list Z}

as their equivalent over \coqe{Z} with \coqe{:GF} (in \Zfield), we prove that given the same inputs \coqe{Crypto_Scalarmult} performs the same computation as \coqe{RFC}.

% This is formalized as follows in Coq:

\begin{lstlisting}[language=Coq]

Lemma Crypto_Scalarmult_RFC_eq :

forall (n: list Z) (p: list Z),

Zlength n = 32 ->

Zlength p = 32 ->

Forall (fun x => 0 <= x /\ x < 2 ^ 8) n ->

Forall (fun x => 0 <= x /\ x < 2 ^ 8) p ->

Crypto_Scalarmult n p = RFC n p.

\end{lstlisting}

This proves that TweetNaCl's X25519 implementation respect RFC~7748.

we defined a Coq definition \coqe{Crypto_Scalarmult} mimicking the exact behavior of X25519 in TweetNaCl.

By proving that each functions \coqe{Low.M}; \coqe{Low.A}; \coqe{Low.Sq}; \coqe{Low.Zub};

\coqe{Unpack25519}; \coqe{clamp}; \coqe{Pack25519}; \coqe{Inv25519}; \coqe{car25519} behave over \coqe{list Z}

as their equivalent over \coqe{Z} with \coqe{:GF} (in \Zfield), we prove that given the same inputs \coqe{Crypto_Scalarmult} performs the same computation as \coqe{RFC}.

% This is formalized as follows in Coq:

\begin{lstlisting}[language=Coq]

Lemma Crypto_Scalarmult_RFC_eq :

forall (n: list Z) (p: list Z),

Zlength n = 32 ->

Zlength p = 32 ->

Forall (fun x => 0 <= x /\ x < 2 ^ 8) n ->

Forall (fun x => 0 <= x /\ x < 2 ^ 8) p ->

Crypto_Scalarmult n p = RFC n p.

\end{lstlisting}

This proves that TweetNaCl's X25519 implementation respect RFC~7748.