Jelajahi Sumber

Add NOISE_KK

Frank Denis 8 tahun lalu
induk
melakukan
fa9cb583a0
3 mengubah file dengan 150 tambahan dan 20 penghapusan
  1. 21 0
      hydrogen.h
  2. 81 0
      impl/kx.h
  3. 48 20
      tests/tests.c

+ 21 - 0
hydrogen.h

@@ -191,6 +191,27 @@ int hydro_kx_n_1(hydro_kx_session_keypair *kp, uint8_t packet1[hydro_kx_N_PACKET
 int hydro_kx_n_2(hydro_kx_session_keypair *kp, const uint8_t packet1[hydro_kx_N_PACKET1BYTES],
                  const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp);
 
+/* NOISE_KK */
+
+#define hydro_kx_KK_PACKET1BYTES 32
+#define hydro_kx_KK_PACKET2BYTES 32
+
+int hydro_kx_kk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
+                  const uint8_t           psk[hydro_kx_PSKBYTES],
+                  const uint8_t           peer_static_pk[hydro_kx_PUBLICKEYBYTES],
+                  const hydro_kx_keypair *static_kp);
+
+int hydro_kx_kk_2(hydro_kx_state *state, hydro_kx_session_keypair *kp,
+                  uint8_t                 packet2[hydro_kx_KK_PACKET2BYTES],
+                  const uint8_t           packet1[hydro_kx_KK_PACKET1BYTES],
+                  const uint8_t           psk[hydro_kx_PSKBYTES],
+                  const uint8_t           peer_static_pk[hydro_kx_PUBLICKEYBYTES],
+                  const hydro_kx_keypair *static_kp);
+
+int hydro_kx_kk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
+                  const uint8_t packet2[hydro_kx_KK_PACKET2BYTES],
+                  const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES]);
+
 /* NOISE_XX */
 
 #define hydro_kx_XX_PACKET1BYTES 32

+ 81 - 0
impl/kx.h

@@ -256,6 +256,87 @@ hydro_kx_n_2(hydro_kx_session_keypair *kp, const uint8_t packet1[hydro_kx_N_PACK
     return 0;
 }
 
+/* NOISE_KK */
+
+int
+hydro_kx_kk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_KK_PACKET1BYTES],
+              const uint8_t           psk[hydro_kx_PSKBYTES],
+              const uint8_t           peer_static_pk[hydro_kx_PUBLICKEYBYTES],
+              const hydro_kx_keypair *static_kp)
+{
+    uint8_t dh_res[hydro_x25519_BYTES];
+    mem_zero(state, sizeof *state);
+
+    hydro_kx_keygen(&state->eph_kp);
+    COMPILER_ASSERT(hydro_kx_PSKBYTES >= hydro_hash_KEYBYTES);
+    hydro_hash_hash(state->h, sizeof state->h, state->eph_kp.pk, sizeof state->eph_kp.pk,
+                    hydro_kx_CONTEXT, psk);
+    memcpy(packet1, state->eph_kp.pk, sizeof state->eph_kp.pk);
+
+    if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_static_pk) != 0) {
+        return -1;
+    }
+    if (hydro_kx_scalarmult(state, dh_res, static_kp->sk, peer_static_pk) != 0) {
+        return -1;
+    }
+    return 0;
+}
+
+int
+hydro_kx_kk_2(hydro_kx_state *state, hydro_kx_session_keypair *kp,
+              uint8_t       packet2[hydro_kx_KK_PACKET2BYTES],
+              const uint8_t packet1[hydro_kx_KK_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES],
+              const uint8_t           peer_static_pk[hydro_kx_PUBLICKEYBYTES],
+              const hydro_kx_keypair *static_kp)
+{
+    uint8_t        dh_res[hydro_x25519_BYTES];
+    const uint8_t *peer_eph_pk = packet1;
+
+    mem_zero(state, sizeof *state);
+
+    hydro_kx_keygen(&state->eph_kp);
+    COMPILER_ASSERT(hydro_kx_PSKBYTES >= hydro_hash_KEYBYTES);
+    hydro_hash_hash(state->h, sizeof state->h, state->eph_kp.pk, sizeof state->eph_kp.pk,
+                    hydro_kx_CONTEXT, psk);
+    memcpy(packet2, state->eph_kp.pk, sizeof state->eph_kp.pk);
+
+    if (hydro_kx_scalarmult(state, dh_res, static_kp->sk, peer_eph_pk) != 0) {
+        return -1;
+    }
+    if (hydro_kx_scalarmult(state, dh_res, static_kp->sk, peer_static_pk) != 0) {
+        return -1;
+    }
+
+    if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_eph_pk) != 0) {
+        return -1;
+    }
+    if (hydro_kx_scalarmult(state, dh_res, static_kp->sk, peer_eph_pk) != 0) {
+        return -1;
+    }
+    hydro_kx_final(state, kp->rx, kp->tx);
+
+    return 0;
+}
+
+int
+hydro_kx_kk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp,
+              const uint8_t packet2[hydro_kx_KK_PACKET2BYTES],
+              const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES])
+{
+    uint8_t        dh_res[hydro_x25519_BYTES];
+    const uint8_t *peer_eph_pk = packet2;
+
+    if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_eph_pk) != 0) {
+        return -1;
+    }
+    if (hydro_kx_scalarmult(state, dh_res, state->eph_kp.sk, peer_static_pk) != 0) {
+        return -1;
+    }
+    hydro_kx_final(state, kp->tx, kp->rx);
+
+    return 0;
+}
+
 /* NOISE_XX */
 
 int

+ 48 - 20
tests/tests.c

@@ -271,6 +271,52 @@ test_sign(void)
     assert(hydro_sign_verify(sig, msg, 0, ctx, kp.pk) == 0);
 }
 
+static void
+test_kx_n(void)
+{
+    hydro_kx_keypair         server_static_kp;
+    uint8_t                  psk[hydro_kx_PSKBYTES];
+    uint8_t                  packet1[hydro_kx_N_PACKET1BYTES];
+    hydro_kx_session_keypair kp_client;
+    hydro_kx_session_keypair kp_server;
+
+    hydro_kx_keygen(&server_static_kp);
+    hydro_random_buf(psk, sizeof psk);
+
+    hydro_kx_n_1(&kp_client, packet1, psk, server_static_kp.pk);
+    hydro_kx_n_2(&kp_server, packet1, psk, &server_static_kp);
+
+    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_kx_kk(void)
+{
+    hydro_kx_state           st_client;
+    hydro_kx_state           st_server;
+    hydro_kx_keypair         client_static_kp;
+    hydro_kx_keypair         server_static_kp;
+    uint8_t                  psk[hydro_kx_PSKBYTES];
+    uint8_t                  packet1[hydro_kx_KK_PACKET1BYTES];
+    uint8_t                  packet2[hydro_kx_KK_PACKET2BYTES];
+    hydro_kx_session_keypair kp_client;
+    hydro_kx_session_keypair kp_server;
+
+    hydro_random_buf(psk, sizeof psk);
+
+    hydro_kx_keygen(&client_static_kp);
+    hydro_kx_keygen(&server_static_kp);
+
+    hydro_kx_kk_1(&st_client, packet1, psk, server_static_kp.pk, &client_static_kp);
+    hydro_kx_kk_2(&st_server, &kp_server, packet2, packet1, psk, client_static_kp.pk,
+                  &server_static_kp);
+    hydro_kx_kk_3(&st_client, &kp_client, packet2, server_static_kp.pk);
+
+    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_kx_xx(void)
 {
@@ -310,25 +356,6 @@ test_kx_xx(void)
     assert(hydro_equal(server_peer_pk, client_static_kp.pk, hydro_kx_PUBLICKEYBYTES));
 }
 
-static void
-test_kx_n(void)
-{
-    hydro_kx_keypair         server_static_kp;
-    uint8_t                  psk[hydro_kx_PSKBYTES];
-    uint8_t                  packet1[hydro_kx_N_PACKET1BYTES];
-    hydro_kx_session_keypair kp_client;
-    hydro_kx_session_keypair kp_server;
-
-    hydro_kx_keygen(&server_static_kp);
-    hydro_random_buf(psk, sizeof psk);
-
-    hydro_kx_n_1(&kp_client, packet1, psk, server_static_kp.pk);
-    hydro_kx_n_2(&kp_server, packet1, psk, &server_static_kp);
-
-    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)
 {
@@ -389,8 +416,9 @@ main(void)
     test_core();
     test_hash();
     test_kdf();
-    test_kx_xx();
     test_kx_n();
+    test_kx_kk();
+    test_kx_xx();
     test_pwhash();
     test_randombytes();
     test_secretbox();