Skip to content
Permalink
Browse files

Add Noise_NK

  • Loading branch information
jedisct1 committed Dec 26, 2019
1 parent 0ee3594 commit 1669168fe53a0ef3db4fe8035500852a3320e256
Showing with 126 additions and 0 deletions.
  1. +16 −0 hydrogen.h
  2. +79 −0 impl/kx.h
  3. +31 −0 tests/tests.c
@@ -243,6 +243,22 @@ int hydro_kx_xx_4(hydro_kx_state *state, hydro_kx_session_keypair *kp,
const uint8_t packet3[hydro_kx_XX_PACKET3BYTES],
const uint8_t psk[hydro_kx_PSKBYTES]);

/* NOISE_NK */

#define hydro_kx_NK_PACKET1BYTES (32 + 16)
#define hydro_kx_NK_PACKET2BYTES (32 + 16)

int hydro_kx_nk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_NK_PACKET1BYTES],
const uint8_t psk[hydro_kx_PSKBYTES],
const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES]);

int hydro_kx_nk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_NK_PACKET2BYTES],
const uint8_t packet1[hydro_kx_NK_PACKET1BYTES],
const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp);

int hydro_kx_nk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
const uint8_t packet2[hydro_kx_NK_PACKET2BYTES]);

/* ---------------- */

#define hydro_pwhash_CONTEXTBYTES 8
@@ -454,3 +454,82 @@ hydro_kx_xx_4(hydro_kx_state *state, hydro_kx_session_keypair *kp,

return 0;
}

/* NOISE_NK */

int
hydro_kx_nk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_NK_PACKET1BYTES],
const uint8_t psk[hydro_kx_PSKBYTES],
const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES])
{
uint8_t *packet1_eph_pk = &packet1[0];
uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];

if (psk == NULL) {
psk = zero;
}
hydro_kx_init_state(state, "Noise_NKpsk0_hydro1");
hydro_hash_update(&state->h_st, peer_static_pk, hydro_x25519_PUBLICKEYBYTES);

hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES);
hydro_kx_eph_keygen(state, &state->eph_kp);
if (hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0) {
return -1;
}
hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0);
memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk);

return 0;
}

int
hydro_kx_nk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_NK_PACKET2BYTES],
const uint8_t packet1[hydro_kx_NK_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
const hydro_kx_keypair *static_kp)
{
hydro_kx_state state;
const uint8_t *peer_eph_pk = &packet1[0];
const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES];
uint8_t * packet2_eph_pk = &packet2[0];
uint8_t * packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];

if (psk == NULL) {
psk = zero;
}
hydro_kx_init_state(&state, "Noise_NKpsk0_hydro1");
hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES);

hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES);
hydro_hash_update(&state.h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 ||
hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) {
return -1;
}

hydro_kx_eph_keygen(&state, &state.eph_kp);
if (hydro_kx_dh(&state, state.eph_kp.sk, peer_eph_pk) != 0) {
return -1;
}
hydro_kx_aead_encrypt(&state, packet2_mac, NULL, 0);
hydro_kx_final(&state, kp->tx, kp->rx);
memcpy(packet2_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk);

return 0;
}

int
hydro_kx_nk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
const uint8_t packet2[hydro_kx_NK_PACKET2BYTES])
{
const uint8_t *peer_eph_pk = &packet2[0];
const uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES];

hydro_hash_update(&state->h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES);
if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 ||
hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) {
return -1;
}
hydro_kx_final(state, kp->rx, kp->tx);

return 0;
}
@@ -366,6 +366,36 @@ test_kx_xx(void)
assert(hydro_equal(server_peer_pk, client_static_kp.pk, hydro_kx_PUBLICKEYBYTES));
}

static void
test_kx_nk(void)
{
hydro_kx_state st_client;
hydro_kx_keypair server_static_kp;
uint8_t psk[hydro_kx_PSKBYTES];
uint8_t packet1[hydro_kx_NK_PACKET1BYTES];
uint8_t packet2[hydro_kx_NK_PACKET2BYTES];
hydro_kx_session_keypair kp_client;
hydro_kx_session_keypair kp_server;

hydro_kx_keygen(&server_static_kp);

hydro_kx_nk_1(&st_client, packet1, NULL, server_static_kp.pk);
hydro_kx_nk_2(&kp_server, packet2, packet1, NULL, &server_static_kp);
hydro_kx_nk_3(&st_client, &kp_client, packet2);

assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));

hydro_random_buf(psk, sizeof psk);

hydro_kx_nk_1(&st_client, packet1, psk, server_static_kp.pk);
hydro_kx_nk_2(&kp_server, packet2, packet1, psk, &server_static_kp);
hydro_kx_nk_3(&st_client, &kp_client, packet2);

assert(hydro_equal(kp_client.tx, kp_server.rx, hydro_kx_SESSIONKEYBYTES));
assert(hydro_equal(kp_client.rx, kp_server.tx, hydro_kx_SESSIONKEYBYTES));
}

static void
test_pwhash(void)
{
@@ -437,6 +467,7 @@ main(void)
test_kx_n();
test_kx_kk();
test_kx_xx();
test_kx_nk();
test_pwhash();
test_randombytes();
test_secretbox();

1 comment on commit 1669168

@spinda

This comment has been minimized.

Copy link
Contributor

spinda commented on 1669168 Jan 7, 2020

Awesome, thanks!

Please sign in to comment.
You can’t perform that action at this time.