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.