KK variant - jedisct1/libhydrogen GitHub Wiki

Key exchange using the KK variant

  • What the client needs to know about the server: the server's public key
  • What the server needs to know about the client: the client's public key

This variant is designed to exchange messages between two parties that already know each other's public key.

Example

Client: generate a long-term key pair

hydro_kx_keypair client_static_kp;

hydro_kx_keygen(&client_static_kp);

Server: generate a long-term key pair

hydro_kx_keypair server_static_kp;

hydro_kx_keygen(&server_static_kp);

Client: initiate a key exchange

hydro_kx_state st_client;

hydro_kx_kk_1(&st_client, packet1, server_static_kp.pk, &client_static_kp);

Server: process the initial request from the client, and compute the session keys

hydro_kx_session_keypair session_kp;

if (hydro_kx_kk_2(&session_kp, packet2, packet1,
    client_static_kp.pk, &server_static_kp) != 0) {
  // abort
}
// Done! session_kp.tx is the key for sending data to the client,
// and session_kp.rx is the key for receiving data from the client.

Client: process the server packet and compute the session keys

hydro_kx_session_keypair session_kp;

if (hydro_kx_kk_3(&st_client, &session_kp, packet2, &client_static_kp) != 0) {
  // abort
}
// Done! session_kp.tx is the key for sending data to the server,
// and session_kp.rx is the key for receiving data from the server.
// The session keys are the same as those computed by the server, but swapped.

Annex: declarations

uint8_t packet1[hydro_kx_KK_PACKET1BYTES];
uint8_t packet2[hydro_kx_KK_PACKET2BYTES];

Usage

Generating static keys

void hydro_kx_keygen(hydro_kx_keypair *static_kp);

The hydro_kx_keygen() function generates a long-term key pair.

kp->pk contains the public key (hydro_kx_PUBLICKEYBYTES bytes) and kp->sk contains the secret key (hydro_kx_SECRETKEYBYTES bytes).

These long-term keys can be reused indefinitely, even though rotating them from time to time is highly recommended in case the secret key ever gets leaked.

First message (client->server)

int hydro_kx_kk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
                  const uint8_t           peer_static_pk[hydro_kx_PUBLICKEYBYTES],
                  const hydro_kx_keypair *static_kp);

The hydro_kx_kk_1() function is called by a client initiating a connection. It initializes the local state state, computes an ephemeral key pair, and puts the first packet to send to the server into packet1.

Second message (server->client)

int hydro_kx_kk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_KK_PACKET2BYTES],
                  const uint8_t           packet1[hydro_kx_KK_PACKET1BYTES],
                  const uint8_t           peer_static_pk[hydro_kx_PUBLICKEYBYTES],
                  const hydro_kx_keypair *static_kp);

The hydro_kx_kk_2() function has to be called by the server after a client request packet1 has been received.

It validates the request, computes an ephemeral key pair, puts it into kp, and stores the packet to send to the client into packet2.

Third message (client->server)

int hydro_kx_kk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
                  const uint8_t           packet2[hydro_kx_KK_PACKET2BYTES],
                  const hydro_kx_keypair *static_kp);

The hydro_kx_kk_3() function has to be called by the client after having received the packet from the server, packet2.

It validates the packet, computes the shared session key and puts it into kp.