.Xr crypto_lock 3monocypher .
The
.Em server
-generates an X25519 secret key and its corresponding public
-key ahead of time using
-.Xr crypto_key_exchange_public_key 3monocypher
-when the key exchange starts.
+and the
+.Em client
+each generate a long-term X25519 secret key and its corresponding public
+key ahead of time before the key exchange using
+.Xr crypto_key_exchange_public_key 3monocypher .
The
.Em client
-does not need to know the
+must know the
.Em server's
public key before performing the key exchange.
The
These functions differ from the
.Xr crypto_kex_xk1_init_client 3monocypher
functions in that the functions described in this page
-.Em do not
-authenticate the server's identity.
-If you can share a server's public key with client applications ahead of
-time,
-always prefer
+can be used even if a server is offline (i.e. asynchronous
+communication); they have lower security guarantees, see
+.Sx SECURITY CONSIDERATIONS .
+If you can, always prefer
.Xr crypto_kex_xk1_init_client 3monocypher .
.Ss Key exchange as the client
When starting a new connection to the server, the client first reads
-the server's public key from the network;
-then it calls
+the server's public key from the network; then it calls
.Fn crypto_client_x_init_client
to initialize a
.Vt crypto_kex_ctx .
.Xr intro 3monocypher
for advice about generating random bytes (use the operating system's
random number generator).
+This argument is not constant because it is wiped after use.
.It Fa local_sk
A 32-byte secret random number.
-This should be different for every connection you make.
+This is a long-term secret used to identify the respective party.
.It Fa local_pk
The public key corresponding to the
.Fa local_sk ,
The public key of the server.
.El
.Pp
-After creating initializing
+After creating initialising
.Fa ctx ,
the client calls
.Fn crypto_kex_x_1
.Fa msg1
to the server to complete the key exchange.
.Ss Key exchange as the server
-When accepting a new connection from a client, the server first
-generates a new secret key and sends the corresponding public key,
-derived from the secret key using
-.Xr crypto_key_exchange_public_key 3monocypher ,
-to the client.
-It then calls
+When accepting a new connection from a client, the server calls
.Fn crypto_client_xk1_init_server
to initialize a
.Vt crypto_kex_ctx .
.Fn crypto_client_xk1_init_server
are identical to the arguments to
.Fn crypto_client_xk1_init_client ,
-except that the server does not need a
-.Fa random_seed
-and does not need to know a client's public key,
-so no
+except that the server does not need a
+.Fa random_seed ;
+no
.Fa remote_pk
-can be specified.
+can be specified because the server authenticates clients
+only once the handshake completes,
+which is application logic and not part of the key exchange protocol.
.Pp
After initializing
.Fa ctx ,
and
.Fa remote_pk ,
the client's public key.
+The server can use this to authenticate clients by their public key;
+.Em if possible, always authenticate clients .
.Fn crypto_kex_x_2
returns zero on success and -1 if the client's message mismatches the
key exchange until now.
.Em Always check the return value .
-On success, this function also wipes the data in
+This function also wipes the data in
.Fa ctx .
.Sh RETURN VALUES
.Fn crypto_kex_x_init_client ,
Corruption can be caused by transmission errors, programmer error, or an
attacker's interference.
.Sh EXAMPLES
-These examples use UNIX\(rg networking functions to keep the examples
+These examples use *NIX networking functions to keep the examples
concise,
but any kind of networking code will work.
It is assumed that the client and server have already established a
Client:
.Bd -literal -offset indent
crypto_kex_ctx client_ctx; /* key exchange context */
-uint8_t sk[32]; /* 32 random bytes ephemeral secret key */
-uint8_t their_pk[32]; /* the server's ephemeral public key */
+uint8_t sk[32]; /* 32 random bytes long-term secret key */
+uint8_t their_pk[32]; /* the server's public key
+ * (known ahead of time) */
uint8_t seed[32]; /* 32 random bytes */
uint8_t buf[80]; /* buffer for the key exchange messages */
uint8_t session_key[32]; /* the resulting session key */
int fd; /* the socket of the connection */
-if (read(fd, their_pk, 32) != 32)
- return -1;
-/* (generate random bytes in seed and sk here) */
+/* (generate random bytes in seed) */
crypto_kex_x_init_client(&client_ctx, seed, sk, NULL, their_pk);
crypto_kex_x_1(&client_ctx, session_key, buf);
if (write(fd, buf, 80) != 80)
Server:
.Bd -literal -offset indent
crypto_kex_ctx server_ctx; /* key exchange context */
-uint8_t sk[32]; /* 32 random bytes ephemeral secret key */
+uint8_t sk[32]; /* 32 random bytes long-term secret key */
uint8_t my_pk[32]; /* public key to sk */
-uint8_t their_pk[32]; /* the server's public key */
+uint8_t their_pk[32]; /* the client's public key */
uint8_t seed[32]; /* 32 random bytes */
uint8_t buf[80]; /* buffer for the key exchange messages */
uint8_t session_key[32]; /* the resulting session key */
int fd; /* the socket of the connection */
-/* (generate random bytes in sk here) */
-crypto_key_exchange_public_key(my_pk, sk);
-if (write(fd, my_pk, 32) != 32)
- return -1;
crypto_kex_x_init_server(&server_ctx, sk, my_pk);
if (read(fd, buf, 80) != 80)
return -2;
.Sh STANDARDS
These functions are equivalent to an implementation of the X pattern
of the Noise protocol framework.
+.Sh SECURITY CONSIDERATIONS
+Unlike the
+.Xr crypto_kex_xk1_init_client 3monocypher
+family of functions, the functions described on this page suffer from a
+number of security issues:
+.Bl -tag -width Ds
+.It Limited forward secrecy
+If an attacker manages to steal the server's long-term secret key,
+past messages may be recovered.
+.It Replay attacks
+The server does not send a random challenge in this.
+.It Key compromise impersonation
+If an attacker manages to steal the server's long-term secret key,
+the attacker can impersonate
+.Em any
+client to that server; if client identity is tied to authorization,
+this also means that authorization requirements can be bypassed.
+.El
+.Pp
+The reason they are provided is because they work even if the other
+party cannot respond to a key exchange immediately (e.g. if the server
+may not always be available; consider something like crash dumps where
+a program may be used temporarily in an offline environment).
.Xr crypto_lock 3monocypher .
The
.Em server
-must have generated an X25519 secret key and its corresponding public
-key ahead of time using
+and the
+.Em client
+each generate a long-term X25519 secret key and its corresponding public
+key ahead of time before the key exchange using
.Xr crypto_key_exchange_public_key 3monocypher .
-This key is also used by the client to verify the server's identity.
+These keys are also used by the by each party to verify the other
+party's identity.
The
.Em client
must know the
.Pp
These functions differ from the
.Xr crypto_kex_x_init_client 3monocypher
-functions in that the functions described in this page authenticate a
-server's identity.
+functions in that the functions described in this page provide stronger
+security guarantees, but also require the server to be able to respond
+to a connection from a client immediately.
.Ss Key exchange as the client
When starting a new connection to the server, the client first calls
.Fn crypto_client_xk1_init_client
.Xr intro 3monocypher
for advice about generating random bytes (use the operating system's
random number generator).
+This argument is not constant because it is wiped after use.
.It Fa local_sk
A 32-byte secret random number.
-This should be different for every connection the client makes.
+This is a long-term secret used to identify the respective party.
.It Fa local_pk
The public key corresponding to the
.Fa local_sk ,
This is used to authenticate the server's identity.
.El
.Pp
-After creating initializing
+After initialising
.Fa ctx ,
the client calls
.Fn crypto_kex_xk1_1
returns zero on success and -1 if the server's message mismatches the
key exchange until now.
.Em Always check the return value .
-On success, this function also wipes the data in
+This function also wipes the data in
.Fa ctx .
The client sends
.Fa msg3
.Fn crypto_client_xk1_init_server
are identical to the arguments to
.Fn crypto_client_xk1_init_client ,
-except that the server does not know a client's public key yet,
+except that the server does not know the client's public key yet,
so no
.Fa remote_pk
-can be specified;
-the server's
+can be specified because the server authenticates clients
+once the handshake completes; the server's
.Fa local_sk
and
.Fa local_pk
and
.Fa remote_pk ,
the client's public key.
+The server can use this to authenticate clients by their public key;
+.Em if possible, always authenticate clients .
.Fn crypto_kex_xk1_4
returns zero on success and -1 if the client's message mismatches the
key exchange until now.
.Em Always check the return value .
-On success, this function also wipes the data in
+This function also wipes the data in
.Fa ctx .
.Sh RETURN VALUES
.Fn crypto_kex_xk1_init_client ,
Corruption can be caused by transmission errors, programmer error, or an
attacker's interference.
.Sh EXAMPLES
-These examples use UNIX\(rg networking functions to keep the examples
+These examples use *NIX networking functions to keep the examples
readable,
but any kind of networking code will work.
It is assumed that the client and server have already established a
Client:
.Bd -literal -offset indent
crypto_kex_ctx client_ctx; /* key exchange context */
-uint8_t sk[32]; /* 32 random bytes ephemeral secret key */
+uint8_t sk[32]; /* 32 random bytes long-term secret key */
uint8_t their_pk[32]; /* the server's public key
* (known ahead of time) */
uint8_t seed[32]; /* 32 random bytes */
uint8_t session_key[32]; /* the resulting session key */
int fd; /* the socket of the connection */
-/* (generate random bytes in seed and sk here) */
+/* (generate random bytes in seed here) */
crypto_kex_xk1_init_client(&client_ctx, seed, sk, NULL, their_pk);
crypto_kex_xk1_1(&client_ctx, buf);
if (write(fd, buf, 32) != 32)
-.Dd December 28, 2017
+.Dd March 6, 2019
.Dt INTRO 3MONOCYPHER
.Os
.Sh NAME
Argon2 won the password hashing competition in 2015.
Unlike Scrypt, Argon2i is immune to timing attacks.
.Ss Key exchange
-.Xr crypto_key_exchange 3monocypher
-implements X25519, an elliptic curve Diffie Hellman key exchange
+The
+.Xr crypto_kex_xk1_init_client 3monocypher
+and
+.Xr crypto_kex_x_init_client 3monocypher
+families of functions,
+provide key exhange protocols with forward secrecy.
+.Pp
+If more control over the key exchange is required,
+there is
+.Xr crypto_key_exchange 3monocypher ,
+which implements X25519, an elliptic curve Diffie Hellman key exchange
algorithm based on Curve25519.
X25519 derives a shared secret from two private/public key pairs.
It is fast, simple, and relatively easy to implement securely.
.Xr crypto_check_final 3monocypher ,
.Xr crypto_check_init 3monocypher ,
.Xr crypto_check_update 3monocypher ,
+.Xr crypto_kex_xk1_init_client 3monocypher ,
+.Xr crypto_kex_x_init_client 3monocypher ,
.Xr crypto_key_exchange 3monocypher ,
.Xr crypto_lock 3monocypher ,
.Xr crypto_lock_aead 3monocypher ,
To mitigate this problem, some protocols guarantee that past messages
are not compromised even if the long term keys are.
This is done by generating temporary keys, then encrypting messages
-with them.
+using them.
+Monocypher provides the
+.Xr crypto_kex_xk1_init_client 3monocypher
+and
+.Xr crypto_kex_x_init_client 3monocypher
+families of functions,
+which provide forward secrecy.
.Pp
In general, secrets that went through a computer should not be
compromised when this computer is stolen or infected at a later point.