--- /dev/null
+crypto_kex_x_init_client.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_kex_x_init_client.3monocypher
\ No newline at end of file
--- /dev/null
+.Dd March 6, 2019
+.Dt CRYPTO_KEX_X_INIT_CLIENT 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_kex_x_init_client ,
+.Nm crypto_kex_x_init_server ,
+.Nm crypto_kex_x_1 ,
+.Nm crypto_kex_x_2
+.Nd one way key exchange for establishing secure channels
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_kex_x_init_client
+.Fa "crypto_kex_ctx *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]"
+.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]"
+.Fc
+.Ft void
+.Fo crypto_kex_x_1
+.Fa "crypto_kex_ctx *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 "uint8_t session_key[32]"
+.Fa "uint8_t remote_pk[32]"
+.Fa "conts uint8_t msg1[80]"
+.Fc
+.Sh DESCRIPTION
+These functions perform a key exchange between a
+.Em client
+and a
+.Em server
+to establish a secure channel.
+The result of the key exchange is a
+.Em session key
+that is suitable for use with
+.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.
+The
+.Em client
+does not need to know the
+.Em server's
+public key before performing the key exchange.
+The
+.Em client
+initiates the key exchange.
+.Pp
+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
+.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 initialize a
+.Vt crypto_kex_ctx .
+The arguments to
+.Fn crypto_client_x_init_client
+are:
+.Bl -tag -width Ds
+.It Fa ctx
+A pointer to a
+.Vt crypto_kex_ctx .
+.It Fa random_seed
+32 randomly generated bytes.
+See
+.Xr intro 3monocypher
+for advice about generating random bytes (use the operating system's
+random number generator).
+.It Fa local_sk
+A 32-byte secret random number.
+This should be different for every connection you make.
+.It Fa local_pk
+The public key corresponding to the
+.Fa local_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.
+.El
+.Pp
+After creating initializing
+.Fa ctx ,
+the client calls
+.Fn crypto_kex_x_1
+to generate
+.Fa msg1
+and the
+.Fa session_key .
+It 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 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
+.Fn crypto_client_xk1_init_server
+to initialize a
+.Vt crypto_kex_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 need a
+.Fa random_seed
+and does not need to know a client's public key,
+so no
+.Fa remote_pk
+can be specified.
+.Pp
+After initializing
+.Fa ctx ,
+the server waits for the client to send
+.Fa msg1
+and reads it from the network.
+The server then calls
+.Fn crypto_kex_x_2
+with
+.Fa msg1 ,
+which yields
+.Fa session_key
+and
+.Fa remote_pk ,
+the client's public key.
+.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
+.Fa ctx .
+.Sh RETURN VALUES
+.Fn crypto_kex_x_init_client ,
+.Fn crypto_kex_x_init_server
+and
+.Fn crypto_kex_x_1
+return nothing.
+.PP
+.Fn crypto_kex_x_2
+returns 0 on success or -1 if the messages were corrupt or mismatched the
+server's identity.
+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
+concise,
+but any kind of networking code will work.
+It is assumed that the client and server have already established a
+connection with each other.
+.Pp
+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 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) */
+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)
+ return -2;
+/* key exchange complete;
+ * send/receive messages encrypted with crypto_lock() now */
+.Ed
+.Pp
+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 my_pk[32]; /* public key to sk */
+uint8_t their_pk[32]; /* the server'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;
+crypto_kex_1_2(&server_ctx, session_key, their_pk, buf);
+/* key exchange complete;
+ * send/receive messages encrypted with crypto_lock() now */
+.Ed
+.Sh SEE ALSO
+.Xr crypto_key_exchange 3monocypher ,
+.Xr crypto_kex_xk1_init_client 3monocypher ,
+.Xr crypto_lock 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions are equivalent to an implementation of the X pattern
+of the Noise protocol framework.
--- /dev/null
+crypto_kex_x_init_client.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_kex_xk1_init_client.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_kex_xk1_init_client.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_kex_xk1_init_client.3monocypher
\ No newline at end of file
--- /dev/null
+crypto_kex_xk1_init_client.3monocypher
\ No newline at end of file
--- /dev/null
+.Dd March 6, 2019
+.Dt CRYPTO_KEX_XK1_INIT_CLIENT 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_kex_xk1_init_client ,
+.Nm crypto_kex_xk1_init_server ,
+.Nm crypto_kex_xk1_1 ,
+.Nm crypto_kex_xk1_2 ,
+.Nm crypto_kex_xk1_3 ,
+.Nm crypto_kex_xk1_4
+.Nd interactive key exchange for establishing secure channels
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_kex_xk1_init_client
+.Fa "crypto_kex_ctx *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]"
+.Fc
+.Ft void
+.Fo crypto_kex_xk1_init_server
+.Fa "crypto_kex_ctx *ctx"
+.Fa "uint8_t random_seed[32]"
+.Fa "const uint8_t local_sk[32]"
+.Fa "const uint8_t local_pk[32]"
+.Fc
+.Ft void
+.Fo crypto_kex_xk1_1
+.Fa "crypto_kex_ctx *ctx"
+.Fa "uint8_t msg1[32]"
+.Fc
+.Ft void
+.Fo crypto_kex_xk1_2
+.Fa "crypto_kex_ctx *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 "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 "uint8_t session_key[32]"
+.Fa "uint8_t remote_pk[32]"
+.Fa "const uint8_t msg3[48]"
+.Fc
+.Sh DESCRIPTION
+These functions perform a key exchange between a
+.Em client
+and a
+.Em server
+to establish a secure channel.
+The result of the key exchange is a
+.Em session key
+that is suitable for use with
+.Xr crypto_lock 3monocypher .
+The
+.Em server
+must have generated an X25519 secret key and its corresponding public
+key ahead of time using
+.Xr crypto_key_exchange_public_key 3monocypher .
+This key is also used by the client to verify the server's identity.
+The
+.Em client
+must know the
+.Em server's
+public key before performing the key exchange.
+The
+.Em client
+initiates the key exchange.
+.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.
+.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 initialize a
+.Vt crypto_kex_ctx .
+The arguments to
+.Fn crypto_client_xk1_init_client
+are:
+.Bl -tag -width Ds
+.It Fa ctx
+A pointer to a
+.Vt crypto_kex_ctx .
+.It Fa random_seed
+32 randomly generated bytes.
+See
+.Xr intro 3monocypher
+for advice about generating random bytes (use the operating system's
+random number generator).
+.It Fa local_sk
+A 32-byte secret random number.
+This should be different for every connection the client makes.
+.It Fa local_pk
+The public key corresponding to the
+.Fa local_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, which must be known to the client before
+making a connection.
+This is used to authenticate the server's identity.
+.El
+.Pp
+After creating initializing
+.Fa ctx ,
+the client calls
+.Fn crypto_kex_xk1_1
+to generate
+.Fa msg1 .
+It proceeds to send
+.Fa msg1
+to the server.
+The client then reads
+.Fa msg2
+from the server.
+It calls
+.Fn crypto_kex_xk1_3 ,
+which yields the
+.Fa session_key
+and
+.Fa msg3 .
+.Fn crypto_kex_xk1_3
+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
+.Fa ctx .
+The client sends
+.Fa msg3
+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 calls
+.Fn crypto_client_xk1_init_server
+to initialize a
+.Vt crypto_kex_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 a client's public key yet,
+so no
+.Fa remote_pk
+can be specified;
+the server's
+.Fa local_sk
+and
+.Fa local_pk
+are generated ahead of time and known to the clients.
+.Pp
+After initializing
+.Fa ctx ,
+the server waits for the client to send
+.Fa msg1
+and reads it from the network.
+The server then calls
+.Fn crypto_kex_xk1_2
+with
+.Fa msg1 ,
+which yields
+.Fa msg2 .
+.Fa msg2
+is sent to the client.
+The server reads the client's response
+.Fa ( msg3 )
+from the network and calls
+.Fn crypto_kex_xk1_4
+with
+.Fa msg3 ,
+which yields
+.Fa session_key
+and
+.Fa remote_pk ,
+the client's public key.
+.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
+.Fa ctx .
+.Sh RETURN VALUES
+.Fn crypto_kex_xk1_init_client ,
+.Fn crypto_kex_xk1_init_server ,
+.Fn crypto_kex_xk1_1
+and
+.Fn crypto_kex_xk1_2
+return nothing.
+.Pp
+.Fn crypto_kex_xk1_3
+and
+.Fn crypto_kex_xk1_4
+return 0 on success or -1 if the messages were corrupt or mismatched the
+server's identity.
+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
+readable,
+but any kind of networking code will work.
+It is assumed that the client and server have already established a
+connection with each other.
+.Pp
+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 public key
+ * (known ahead of time) */
+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 and sk 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)
+ return -1;
+if (read(fd, buf, 48) != 48)
+ return -2;
+if (crypto_kex_xk1_3(&client_ctx, session_key, buf, buf) != 0)
+ return -3;
+if (write(fd, buf, 48) != 48)
+ return -4;
+/* key exchange complete;
+ * send/receive messages encrypted with crypto_lock() now */
+.Ed
+.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 */
+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);
+if (read(fd, buf, 32) != 32)
+ return -1;
+crypto_kex_xk1_2(&server_ctx, buf, buf);
+if (write(fd, buf, 48) != 48)
+ return -2;
+if (read(fd, buf, 48) != 48)
+ return -3;
+if (crypto_kex_xk1_4(&server_ctx, session_key, their_pk, buf) != 0)
+ return -4;
+/* key exchange complete;
+ * send/receive messages encrypted with crypto_lock() now */
+.Ed
+.Sh SEE ALSO
+.Xr crypto_key_exchange 3monocypher ,
+.Xr crypto_kex_x_init_client 3monocypher ,
+.Xr crypto_lock 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions are equivalent to an implementation of the XK1 pattern
+of the Noise protocol framework.
--- /dev/null
+crypto_kex_xk1_init_client.3monocypher
\ No newline at end of file
.Pp
.Fn crypto_key_exchange_public_key
deterministically computes the public key from a random secret key.
+It is a medium-level primitive.
+Prefer the
+.Xr crypto_kex_xk1_init_client 3monocypher
+and
+.Xr crypto_kex_x_init_client 3monocypher
+families of functions unless you have a specific reason not to.
.Pp
The arguments are:
.Bl -tag -width Ds