diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj b/builds/msvc/vs2010/libsodium/libsodium.vcxproj
index ec340a17..292219f2 100644
--- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj
@@ -86,6 +86,8 @@
+
+
@@ -199,6 +201,7 @@
+
@@ -209,6 +212,7 @@
+
@@ -240,6 +244,7 @@
+
diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters
index 079094b9..e6e7c823 100644
--- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters
@@ -51,6 +51,12 @@
crypto_kx
+
+ crypto_kx\ed25519
+
+
+ crypto_kx\curve25519
+
crypto_sign
@@ -386,6 +392,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -416,6 +425,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -509,6 +521,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -835,6 +850,12 @@
{898b6bd5-1360-3a34-adcd-0fade7561685}
+
+ {a87725bb-5474-365f-be59-ada5ae3f9e73}
+
+
+ {57637f5e-c7cb-31ae-8f7b-1a68c22ef39f}
+
{323c0a15-3c1d-39b2-9ec1-299deb299497}
diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj b/builds/msvc/vs2012/libsodium/libsodium.vcxproj
index f140d161..15032ef3 100644
--- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj
@@ -86,6 +86,8 @@
+
+
@@ -199,6 +201,7 @@
+
@@ -209,6 +212,7 @@
+
@@ -240,6 +244,7 @@
+
diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters
index 079094b9..e6e7c823 100644
--- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters
@@ -51,6 +51,12 @@
crypto_kx
+
+ crypto_kx\ed25519
+
+
+ crypto_kx\curve25519
+
crypto_sign
@@ -386,6 +392,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -416,6 +425,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -509,6 +521,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -835,6 +850,12 @@
{898b6bd5-1360-3a34-adcd-0fade7561685}
+
+ {a87725bb-5474-365f-be59-ada5ae3f9e73}
+
+
+ {57637f5e-c7cb-31ae-8f7b-1a68c22ef39f}
+
{323c0a15-3c1d-39b2-9ec1-299deb299497}
diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj b/builds/msvc/vs2013/libsodium/libsodium.vcxproj
index cddd4ad6..f3a077e6 100644
--- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj
@@ -86,6 +86,8 @@
+
+
@@ -199,6 +201,7 @@
+
@@ -209,6 +212,7 @@
+
@@ -240,6 +244,7 @@
+
diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters
index 079094b9..e6e7c823 100644
--- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters
@@ -51,6 +51,12 @@
crypto_kx
+
+ crypto_kx\ed25519
+
+
+ crypto_kx\curve25519
+
crypto_sign
@@ -386,6 +392,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -416,6 +425,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -509,6 +521,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -835,6 +850,12 @@
{898b6bd5-1360-3a34-adcd-0fade7561685}
+
+ {a87725bb-5474-365f-be59-ada5ae3f9e73}
+
+
+ {57637f5e-c7cb-31ae-8f7b-1a68c22ef39f}
+
{323c0a15-3c1d-39b2-9ec1-299deb299497}
diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj b/builds/msvc/vs2015/libsodium/libsodium.vcxproj
index 230086a9..11349940 100644
--- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj
@@ -86,6 +86,8 @@
+
+
@@ -199,6 +201,7 @@
+
@@ -209,6 +212,7 @@
+
@@ -240,6 +244,7 @@
+
diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters
index 079094b9..e6e7c823 100644
--- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters
@@ -51,6 +51,12 @@
crypto_kx
+
+ crypto_kx\ed25519
+
+
+ crypto_kx\curve25519
+
crypto_sign
@@ -386,6 +392,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -416,6 +425,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -509,6 +521,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -835,6 +850,12 @@
{898b6bd5-1360-3a34-adcd-0fade7561685}
+
+ {a87725bb-5474-365f-be59-ada5ae3f9e73}
+
+
+ {57637f5e-c7cb-31ae-8f7b-1a68c22ef39f}
+
{323c0a15-3c1d-39b2-9ec1-299deb299497}
diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj b/builds/msvc/vs2017/libsodium/libsodium.vcxproj
index 8a175e0b..2ba0f13e 100644
--- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj
@@ -86,6 +86,8 @@
+
+
@@ -199,6 +201,7 @@
+
@@ -209,6 +212,7 @@
+
@@ -240,6 +244,7 @@
+
diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters
index 079094b9..e6e7c823 100644
--- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters
@@ -51,6 +51,12 @@
crypto_kx
+
+ crypto_kx\ed25519
+
+
+ crypto_kx\curve25519
+
crypto_sign
@@ -386,6 +392,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -416,6 +425,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -509,6 +521,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -835,6 +850,12 @@
{898b6bd5-1360-3a34-adcd-0fade7561685}
+
+ {a87725bb-5474-365f-be59-ada5ae3f9e73}
+
+
+ {57637f5e-c7cb-31ae-8f7b-1a68c22ef39f}
+
{323c0a15-3c1d-39b2-9ec1-299deb299497}
diff --git a/dist-build/emscripten-symbols.def b/dist-build/emscripten-symbols.def
index e47e6d26..84e9f5db 100644
--- a/dist-build/emscripten-symbols.def
+++ b/dist-build/emscripten-symbols.def
@@ -250,6 +250,15 @@ _crypto_kx_curve25519_seed_keypair 0 1
_crypto_kx_curve25519_seedbytes 0 1
_crypto_kx_curve25519_server_session_keys 0 1
_crypto_kx_curve25519_sessionkeybytes 0 1
+_crypto_kx_ed25519_client_session_keys 0 1
+_crypto_kx_ed25519_keypair 0 1
+_crypto_kx_ed25519_primitive 0 1
+_crypto_kx_ed25519_publickeybytes 0 1
+_crypto_kx_ed25519_secretkeybytes 0 1
+_crypto_kx_ed25519_seed_keypair 0 1
+_crypto_kx_ed25519_seedbytes 0 1
+_crypto_kx_ed25519_server_session_keys 0 1
+_crypto_kx_ed25519_sessionkeybytes 0 1
_crypto_onetimeauth 0 1
_crypto_onetimeauth_bytes 0 1
_crypto_onetimeauth_final 0 1
diff --git a/libsodium.vcxproj b/libsodium.vcxproj
index 63d5f956..eb414baf 100644
--- a/libsodium.vcxproj
+++ b/libsodium.vcxproj
@@ -324,6 +324,8 @@
+
+
@@ -437,6 +439,7 @@
+
@@ -447,6 +450,7 @@
+
@@ -478,6 +482,7 @@
+
diff --git a/libsodium.vcxproj.filters b/libsodium.vcxproj.filters
index b4a4ea96..7f46d94e 100644
--- a/libsodium.vcxproj.filters
+++ b/libsodium.vcxproj.filters
@@ -42,6 +42,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
Source Files
@@ -377,6 +383,9 @@
Header Files
+
+ Header Files
+
Header Files
@@ -407,6 +416,9 @@
Header Files
+
+ Header Files
+
Header Files
@@ -500,6 +512,9 @@
Header Files
+
+ Header Files
+
Header Files
diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am
index 706d006e..a3c8758b 100644
--- a/src/libsodium/Makefile.am
+++ b/src/libsodium/Makefile.am
@@ -154,6 +154,7 @@ libsodium_la_SOURCES += \
crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c \
crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c \
crypto_core/ed25519/core_ed25519.c \
+ crypto_kx/ed25519/kx_ed25519.c \
crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c \
crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h \
crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c \
diff --git a/src/libsodium/crypto_kx/ed25519/kx_ed25519.c b/src/libsodium/crypto_kx/ed25519/kx_ed25519.c
new file mode 100644
index 00000000..783e9003
--- /dev/null
+++ b/src/libsodium/crypto_kx/ed25519/kx_ed25519.c
@@ -0,0 +1,143 @@
+
+#include
+
+#include "core.h"
+#include "crypto_generichash.h"
+#include "crypto_kx_ed25519.h"
+#include "crypto_scalarmult_ed25519.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "utils.h"
+
+int
+crypto_kx_ed25519_seed_keypair(unsigned char pk[crypto_kx_ed25519_PUBLICKEYBYTES],
+ unsigned char sk[crypto_kx_ed25519_SECRETKEYBYTES],
+ const unsigned char seed[crypto_kx_ed25519_SEEDBYTES])
+{
+ crypto_generichash(sk, crypto_kx_ed25519_SECRETKEYBYTES,
+ seed, crypto_kx_ed25519_SEEDBYTES, NULL, 0);
+ return crypto_scalarmult_ed25519_base(pk, sk);
+}
+
+int
+crypto_kx_ed25519_keypair(unsigned char pk[crypto_kx_ed25519_PUBLICKEYBYTES],
+ unsigned char sk[crypto_kx_ed25519_SECRETKEYBYTES])
+{
+ COMPILER_ASSERT(crypto_kx_ed25519_SECRETKEYBYTES == crypto_scalarmult_ed25519_SCALARBYTES);
+ COMPILER_ASSERT(crypto_kx_ed25519_PUBLICKEYBYTES == crypto_scalarmult_ed25519_BYTES);
+
+ randombytes_buf(sk, crypto_kx_ed25519_SECRETKEYBYTES);
+ return crypto_scalarmult_ed25519_base(pk, sk);
+}
+
+int
+crypto_kx_ed25519_client_session_keys(unsigned char rx[crypto_kx_ed25519_SESSIONKEYBYTES],
+ unsigned char tx[crypto_kx_ed25519_SESSIONKEYBYTES],
+ const unsigned char client_pk[crypto_kx_ed25519_PUBLICKEYBYTES],
+ const unsigned char client_sk[crypto_kx_ed25519_SECRETKEYBYTES],
+ const unsigned char server_pk[crypto_kx_ed25519_PUBLICKEYBYTES])
+{
+ crypto_generichash_state h;
+ unsigned char q[crypto_scalarmult_ed25519_BYTES];
+ unsigned char keys[2 * crypto_kx_ed25519_SESSIONKEYBYTES];
+ int i;
+
+ if (rx == NULL) {
+ rx = tx;
+ }
+ if (tx == NULL) {
+ tx = rx;
+ }
+ if (rx == NULL) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ if (crypto_scalarmult_ed25519(q, client_sk, server_pk) != 0) {
+ return -1;
+ }
+ COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX);
+ crypto_generichash_init(&h, NULL, 0U, sizeof keys);
+ crypto_generichash_update(&h, q, crypto_scalarmult_ed25519_BYTES);
+ sodium_memzero(q, sizeof q);
+ crypto_generichash_update(&h, client_pk, crypto_kx_ed25519_PUBLICKEYBYTES);
+ crypto_generichash_update(&h, server_pk, crypto_kx_ed25519_PUBLICKEYBYTES);
+ crypto_generichash_final(&h, keys, sizeof keys);
+ sodium_memzero(&h, sizeof h);
+ for (i = 0; i < crypto_kx_ed25519_SESSIONKEYBYTES; i++) {
+ rx[i] = keys[i];
+ tx[i] = keys[i + crypto_kx_ed25519_SESSIONKEYBYTES];
+ }
+ sodium_memzero(keys, sizeof keys);
+
+ return 0;
+}
+
+int
+crypto_kx_ed25519_server_session_keys(unsigned char rx[crypto_kx_ed25519_SESSIONKEYBYTES],
+ unsigned char tx[crypto_kx_ed25519_SESSIONKEYBYTES],
+ const unsigned char server_pk[crypto_kx_ed25519_PUBLICKEYBYTES],
+ const unsigned char server_sk[crypto_kx_ed25519_SECRETKEYBYTES],
+ const unsigned char client_pk[crypto_kx_ed25519_PUBLICKEYBYTES])
+{
+ crypto_generichash_state h;
+ unsigned char q[crypto_scalarmult_ed25519_BYTES];
+ unsigned char keys[2 * crypto_kx_ed25519_SESSIONKEYBYTES];
+ int i;
+
+ if (rx == NULL) {
+ rx = tx;
+ }
+ if (tx == NULL) {
+ tx = rx;
+ }
+ if (rx == NULL) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ if (crypto_scalarmult_ed25519(q, server_sk, client_pk) != 0) {
+ return -1;
+ }
+ COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX);
+ crypto_generichash_init(&h, NULL, 0U, sizeof keys);
+ crypto_generichash_update(&h, q, crypto_scalarmult_ed25519_BYTES);
+ sodium_memzero(q, sizeof q);
+ crypto_generichash_update(&h, client_pk, crypto_kx_ed25519_PUBLICKEYBYTES);
+ crypto_generichash_update(&h, server_pk, crypto_kx_ed25519_PUBLICKEYBYTES);
+ crypto_generichash_final(&h, keys, sizeof keys);
+ sodium_memzero(&h, sizeof h);
+ for (i = 0; i < crypto_kx_ed25519_SESSIONKEYBYTES; i++) {
+ tx[i] = keys[i];
+ rx[i] = keys[i + crypto_kx_ed25519_SESSIONKEYBYTES];
+ }
+ sodium_memzero(keys, sizeof keys);
+
+ return 0;
+}
+
+size_t
+crypto_kx_ed25519_publickeybytes(void)
+{
+ return crypto_kx_ed25519_PUBLICKEYBYTES;
+}
+
+size_t
+crypto_kx_ed25519_secretkeybytes(void)
+{
+ return crypto_kx_ed25519_SECRETKEYBYTES;
+}
+
+size_t
+crypto_kx_ed25519_seedbytes(void)
+{
+ return crypto_kx_ed25519_SEEDBYTES;
+}
+
+size_t
+crypto_kx_ed25519_sessionkeybytes(void)
+{
+ return crypto_kx_ed25519_SESSIONKEYBYTES;
+}
+
+const char *
+crypto_kx_ed25519_primitive(void)
+{
+ return crypto_kx_ed25519_PRIMITIVE;
+}
diff --git a/src/libsodium/include/Makefile.am b/src/libsodium/include/Makefile.am
index b70c22b3..4bf69e78 100644
--- a/src/libsodium/include/Makefile.am
+++ b/src/libsodium/include/Makefile.am
@@ -26,6 +26,8 @@ SODIUM_EXPORT = \
sodium/crypto_kdf.h \
sodium/crypto_kdf_blake2b.h \
sodium/crypto_kx.h \
+ sodium/crypto_kx_curve25519.h \
+ sodium/crypto_kx_ed25519.h \
sodium/crypto_onetimeauth.h \
sodium/crypto_onetimeauth_poly1305.h \
sodium/crypto_pwhash.h \
diff --git a/src/libsodium/include/sodium.h b/src/libsodium/include/sodium.h
index f3049b2f..54e37632 100644
--- a/src/libsodium/include/sodium.h
+++ b/src/libsodium/include/sodium.h
@@ -28,6 +28,7 @@
#include "sodium/crypto_kdf_blake2b.h"
#include "sodium/crypto_kx.h"
#include "sodium/crypto_kx_curve25519.h"
+#include "sodium/crypto_kx_ed25519.h"
#include "sodium/crypto_onetimeauth.h"
#include "sodium/crypto_onetimeauth_poly1305.h"
#include "sodium/crypto_pwhash.h"
diff --git a/src/libsodium/include/sodium/crypto_kx_ed25519.h b/src/libsodium/include/sodium/crypto_kx_ed25519.h
new file mode 100644
index 00000000..daa9598a
--- /dev/null
+++ b/src/libsodium/include/sodium/crypto_kx_ed25519.h
@@ -0,0 +1,66 @@
+#ifndef crypto_kx_ed25519_H
+#define crypto_kx_ed25519_H
+
+#include
+
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_kx_ed25519_PUBLICKEYBYTES 32
+SODIUM_EXPORT
+size_t crypto_kx_ed25519_publickeybytes(void);
+
+#define crypto_kx_ed25519_SECRETKEYBYTES 32
+SODIUM_EXPORT
+size_t crypto_kx_ed25519_secretkeybytes(void);
+
+#define crypto_kx_ed25519_SEEDBYTES 32
+SODIUM_EXPORT
+size_t crypto_kx_ed25519_seedbytes(void);
+
+#define crypto_kx_ed25519_SESSIONKEYBYTES 32
+SODIUM_EXPORT
+size_t crypto_kx_ed25519_sessionkeybytes(void);
+
+#define crypto_kx_ed25519_PRIMITIVE "ed25519blake2b"
+SODIUM_EXPORT
+const char *crypto_kx_ed25519_primitive(void);
+
+SODIUM_EXPORT
+int crypto_kx_ed25519_seed_keypair(unsigned char pk[crypto_kx_ed25519_PUBLICKEYBYTES],
+ unsigned char sk[crypto_kx_ed25519_SECRETKEYBYTES],
+ const unsigned char seed[crypto_kx_ed25519_SEEDBYTES])
+ __attribute__ ((nonnull));
+
+SODIUM_EXPORT
+int crypto_kx_ed25519_keypair(unsigned char pk[crypto_kx_ed25519_PUBLICKEYBYTES],
+ unsigned char sk[crypto_kx_ed25519_SECRETKEYBYTES])
+ __attribute__ ((nonnull));
+
+SODIUM_EXPORT
+int crypto_kx_ed25519_client_session_keys(unsigned char rx[crypto_kx_ed25519_SESSIONKEYBYTES],
+ unsigned char tx[crypto_kx_ed25519_SESSIONKEYBYTES],
+ const unsigned char client_pk[crypto_kx_ed25519_PUBLICKEYBYTES],
+ const unsigned char client_sk[crypto_kx_ed25519_SECRETKEYBYTES],
+ const unsigned char server_pk[crypto_kx_ed25519_PUBLICKEYBYTES])
+ __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 4, 5)));
+
+SODIUM_EXPORT
+int crypto_kx_ed25519_server_session_keys(unsigned char rx[crypto_kx_ed25519_SESSIONKEYBYTES],
+ unsigned char tx[crypto_kx_ed25519_SESSIONKEYBYTES],
+ const unsigned char server_pk[crypto_kx_ed25519_PUBLICKEYBYTES],
+ const unsigned char server_sk[crypto_kx_ed25519_SECRETKEYBYTES],
+ const unsigned char client_pk[crypto_kx_ed25519_PUBLICKEYBYTES])
+ __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 4, 5)));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif