.In monocypher.h
.Ft void
.Fo crypto_kex_x_init_client
-.Fa "crypto_kex_ctx *ctx"
+.Fa "crypto_kex_client_ctx *client_ctx"
.Fa "uint8_t random_seed[32]"
-.Fa "const uint8_t local_sk[32]"
-.Fa "const uint8_t local_pk[32]"
-.Fa "const uint8_t remote_pk[32]"
+.Fa "const uint8_t client_sk[32]"
+.Fa "const uint8_t client_pk[32]"
+.Fa "const uint8_t server_pk[32]"
.Fc
.Ft void
.Fo crypto_kex_x_init_server
-.Fa "crypto_kex_ctx *ctx"
-.Fa "const uint8_t local_sk[32]"
-.Fa "const uint8_t local_pk[32]"
+.Fa "crypto_kex_server_ctx *server_ctx"
+.Fa "const uint8_t server_sk[32]"
+.Fa "const uint8_t server_pk[32]"
.Fc
.Ft void
.Fo crypto_kex_x_1
-.Fa "crypto_kex_ctx *ctx"
+.Fa "crypto_kex_client_ctx *client_ctx"
.Fa "uint8_t session_key[32]"
.Fa "uint8_t msg1[80]"
.Fc
.Ft void
.Fo crypto_kex_x_2
-.Fa "crypto_kex_ctx *ctx"
+.Fa "crypto_kex_server_ctx *server_ctx"
.Fa "uint8_t session_key[32]"
-.Fa "uint8_t remote_pk[32]"
+.Fa "uint8_t client_pk[32]"
.Fa "conts uint8_t msg1[80]"
.Fc
.Sh DESCRIPTION
.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
-.Fn crypto_client_x_init_client
-to initialise a
-.Vt crypto_kex_ctx .
-The arguments to
-.Fn crypto_client_x_init_client
-are:
+.Pp
+The arguments are:
.Bl -tag -width Ds
-.It Fa ctx
+.It Fa client_ctx
A pointer to a
-.Vt crypto_kex_ctx .
+.Vt crypto_kex_client_ctx ,
+i.e. the context for the client.
+.It Fa server_ctx
+A pointer to a
+.Vt crypto_kex_server_ctx ,
+i.e. the context for the server.
.It Fa random_seed
32 randomly generated bytes.
See
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
+.It Fa client_sk
A 32-byte secret random number.
-This is a long-term secret used to identify the respective party.
-.It Fa local_pk
+This is a long-term secret used to identify the client.
+.It Fa client_pk
The public key corresponding to the
-.Fa local_sk ,
+.Fa client_sk ,
generated using
.Xr crypto_key_exchange_public_key 3monocypher .
If
.Dv NULL ,
the public key will be generated for you.
-.It Fa remote_pk
-The public key of the server.
+.It Fa server_sk
+A 32-byte secret random number.
+This is a long-term secret used to identify the server.
+.It Fa server_pk
+The public key of the server, which must be known to the client before
+making a connection.
+This is used to authenticate the server's identity.
+It must thus be known to the client before making a connection.
+.It Fa msg1
+A 32-byte message, which is generated and sent by the client.
+It is the only message in the key exchange.
.El
.Pp
-After creating initialising
-.Fa ctx ,
+.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
+.Fn crypto_client_x_init_client
+to initialise a
+.Vt crypto_kex_client_ctx .
+.Pp
+After initialising
+.Fa client_ctx ,
the client calls
.Fn crypto_kex_x_1
to generate
.Fa msg1
and the
-.Fa session_key .
-It proceeds to send
+.Fa session_key ;
+this function also wipes the data in
+.Fa client_ctx .
+The client proceeds to send
.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 calls
.Fn crypto_client_xk1_init_server
to initialise a
-.Vt crypto_kex_ctx .
+.Vt crypto_kex_server_ctx .
The arguments to
.Fn crypto_client_xk1_init_server
are identical to the arguments to
except that the server does not need a
.Fa random_seed ;
no
-.Fa remote_pk
+.Fa client_pk
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 initialising
-.Fa ctx ,
+.Fa server_ctx ,
the server waits for the client to send
.Fa msg1
and reads it from the network.
which yields
.Fa session_key
and
-.Fa remote_pk ,
+.Fa client_pk ,
the client's public key.
The server can use this to authenticate clients by their public key;
.Em if possible, always authenticate clients .
key exchange until now.
.Em Always check the return value .
This function also wipes the data in
-.Fa ctx .
+.Fa server_ctx .
.Sh RETURN VALUES
.Fn crypto_kex_x_init_client ,
.Fn crypto_kex_x_init_server
.Pp
Client:
.Bd -literal -offset indent
-crypto_kex_ctx client_ctx; /* key exchange context */
-uint8_t sk[32]; /* 32 random bytes long-term secret key */
-uint8_t their_pk[32]; /* the server's public key
+crypto_kex_client_ctx client_ctx; /* key exchange context */
+uint8_t client_sk[32]; /* 32 random bytes long-term secret key */
+uint8_t server_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 */
int fd; /* the socket of the connection */
/* (generate random bytes in seed) */
-crypto_kex_x_init_client(&client_ctx, seed, sk, NULL, their_pk);
+crypto_kex_x_init_client(&client_ctx, seed, client_sk, NULL,
+ server_pk);
crypto_kex_x_1(&client_ctx, session_key, buf);
if (write(fd, buf, 80) != 80)
return -2;
Server:
.Bd -literal -offset indent
crypto_kex_ctx server_ctx; /* key exchange context */
-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 client's public key */
+uint8_t server_sk[32]; /* 32 random bytes long-term secret key */
+uint8_t server_pk[32]; /* public key to server_sk */
+uint8_t client_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 */
-crypto_kex_x_init_server(&server_ctx, sk, my_pk);
+crypto_kex_x_init_server(&server_ctx, server_sk, server_pk);
if (read(fd, buf, 80) != 80)
return -2;
-crypto_kex_1_2(&server_ctx, session_key, their_pk, buf);
+crypto_kex_1_2(&server_ctx, session_key, client_pk, buf);
+
+/* authenticate client using client_pk now if possible */
+
/* key exchange complete;
* send/receive messages encrypted with crypto_lock() now */
.Ed
.In monocypher.h
.Ft void
.Fo crypto_kex_xk1_init_client
-.Fa "crypto_kex_ctx *ctx"
+.Fa "crypto_kex_client_ctx *client_ctx"
.Fa "uint8_t random_seed[32]"
-.Fa "const uint8_t local_sk[32]"
-.Fa "const uint8_t local_pk[32]"
-.Fa "const uint8_t remote_pk[32]"
+.Fa "const uint8_t client_sk[32]"
+.Fa "const uint8_t client_pk[32]"
+.Fa "const uint8_t server_pk[32]"
.Fc
.Ft void
.Fo crypto_kex_xk1_init_server
-.Fa "crypto_kex_ctx *ctx"
+.Fa "crypto_kex_server_ctx *server_ctx"
.Fa "uint8_t random_seed[32]"
-.Fa "const uint8_t local_sk[32]"
-.Fa "const uint8_t local_pk[32]"
+.Fa "const uint8_t server_sk[32]"
+.Fa "const uint8_t server_pk[32]"
.Fc
.Ft void
.Fo crypto_kex_xk1_1
-.Fa "crypto_kex_ctx *ctx"
+.Fa "crypto_kex_client_ctx *client_ctx"
.Fa "uint8_t msg1[32]"
.Fc
.Ft void
.Fo crypto_kex_xk1_2
-.Fa "crypto_kex_ctx *ctx"
+.Fa "crypto_kex_server_ctx *server_ctx"
.Fa "uint8_t msg2[48]"
.Fa "const uint8_t msg1[32]"
.Fc
.Ft int
.Fo crypto_kex_xk1_3
-.Fa "crypto_kex_ctx *ctx"
+.Fa "crypto_kex_client_ctx *client_ctx"
.Fa "uint8_t session_key[32]"
.Fa "uint8_t msg3[48]"
.Fa "const uint8_t msg2[48]"
.Fc
.Ft int
.Fo crypto_kex_xk1_4
-.Fa "crypto_kex_ctx *ctx"
+.Fa "crypto_kex_server_ctx *server_ctx"
.Fa "uint8_t session_key[32]"
-.Fa "uint8_t remote_pk[32]"
+.Fa "uint8_t client_pk[32]"
.Fa "const uint8_t msg3[48]"
.Fc
.Sh DESCRIPTION
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
-to initialise a
-.Vt crypto_kex_ctx .
-The arguments to
-.Fn crypto_client_xk1_init_client
-are:
+.Pp
+The arguments are:
.Bl -tag -width Ds
-.It Fa ctx
+.It Fa client_ctx
+A pointer to a
+.Vt crypto_kex_client_ctx ,
+i.e. the context for the client.
+.It Fa server_ctx
A pointer to a
-.Vt crypto_kex_ctx .
+.Vt crypto_kex_server_ctx ,
+i.e. the context for the server.
.It Fa random_seed
32 randomly generated bytes.
+The server and the client must
+.Em each
+generate a
+.Fa random_seed .
See
.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
+.It Fa client_sk
A 32-byte secret random number.
-This is a long-term secret used to identify the respective party.
-.It Fa local_pk
+This is a long-term secret used to identify the client.
+.It Fa client_pk
The public key corresponding to the
-.Fa local_sk ,
+.Fa client_sk ,
generated using
.Xr crypto_key_exchange_public_key 3monocypher .
If
.Dv NULL ,
the public key will be generated for you.
-.It Fa remote_pk
+.It Fa server_sk
+A 32-byte secret random number.
+This is a long-term secret used to identify the server.
+.It Fa server_pk
The public key of the server, which must be known to the client before
making a connection.
This is used to authenticate the server's identity.
+It must thus be known to the client before making a connection.
+.It Fa msg1
+A 32-byte message, which is generated and sent by the client.
+It starts the actual key exchange.
+.It Fa msg2
+A 48-byte message, which is generated and sent by the server.
+.It Fa msg3
+A 48-byte message, which is generated and sent by the client.
+This is the final message in the key exchange.
.El
-.Pp
+.Ss Key exchange as the client
+When starting a new connection to the server, the client first calls
+.Fn crypto_client_xk1_init_client
+to initialise a
+.Vt crypto_kex_client_ctx .
After initialising
-.Fa ctx ,
+.Fa client_ctx ,
the client calls
.Fn crypto_kex_xk1_1
to generate
key exchange until now.
.Em Always check the return value .
This function also wipes the data in
-.Fa ctx .
+.Fa client_ctx .
The client sends
.Fa msg3
to the server to complete the key exchange.
When accepting a new connection from a client, the server first calls
.Fn crypto_client_xk1_init_server
to initialise a
-.Vt crypto_kex_ctx .
+.Vt crypto_kex_server_ctx .
The arguments to
.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 the client's public key yet,
so no
-.Fa remote_pk
+.Fa client_pk
can be specified because the server authenticates clients
once the handshake completes; the server's
-.Fa local_sk
+.Fa server_sk
and
-.Fa local_pk
+.Fa server_pk
are generated ahead of time and known to the clients.
.Pp
After initialising
-.Fa ctx ,
+.Fa server_ctx ,
the server waits for the client to send
.Fa msg1
and reads it from the network.
which yields
.Fa session_key
and
-.Fa remote_pk ,
+.Fa client_pk ,
the client's public key.
The server can use this to authenticate clients by their public key;
.Em if possible, always authenticate clients .
key exchange until now.
.Em Always check the return value .
This function also wipes the data in
-.Fa ctx .
+.Fa server_ctx .
.Sh RETURN VALUES
.Fn crypto_kex_xk1_init_client ,
.Fn crypto_kex_xk1_init_server ,
.Pp
Client:
.Bd -literal -offset indent
-crypto_kex_ctx client_ctx; /* key exchange context */
-uint8_t sk[32]; /* 32 random bytes long-term secret key */
-uint8_t their_pk[32]; /* the server's public key
+crypto_kex_client_ctx client_ctx; /* key exchange context */
+uint8_t client_sk[32]; /* 32 random bytes long-term secret key */
+uint8_t server_pk[32]; /* the server's public key
* (known ahead of time) */
uint8_t seed[32]; /* 32 random bytes */
uint8_t buf[48]; /* buffer for the key exchange messages */
int fd; /* the socket of the connection */
/* (generate random bytes in seed here) */
-crypto_kex_xk1_init_client(&client_ctx, seed, sk, NULL, their_pk);
+crypto_kex_xk1_init_client(&client_ctx, seed, client_sk, NULL,
+ server_pk);
crypto_kex_xk1_1(&client_ctx, buf);
if (write(fd, buf, 32) != 32)
return -1;
.Pp
Server:
.Bd -literal -offset indent
-crypto_kex_ctx server_ctx; /* key exchange context */
-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 client's public key */
+crypto_kex_server_ctx server_ctx; /* key exchange context */
+uint8_t server_sk[32]; /* 32 random bytes long-term secret key */
+uint8_t server_pk[32]; /* public key to server_sk */
+uint8_t client_pk[32]; /* the client's public key */
uint8_t seed[32]; /* 32 random bytes */
uint8_t buf[48]; /* 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 seed here) */
-crypto_kex_xk1_init_server(&server_ctx, seed, sk, my_pk);
+crypto_kex_xk1_init_server(&server_ctx, seed, server_sk, server_pk);
if (read(fd, buf, 32) != 32)
return -1;
crypto_kex_xk1_2(&server_ctx, buf, buf);
return -2;
if (read(fd, buf, 48) != 48)
return -3;
-if (crypto_kex_xk1_4(&server_ctx, session_key, their_pk, buf) != 0)
+if (crypto_kex_xk1_4(&server_ctx, session_key, client_pk, buf) != 0)
return -4;
+
+/* authenticate client using client_pk now if possible */
+
/* key exchange complete;
* send/receive messages encrypted with crypto_lock() now */
.Ed