summaryrefslogtreecommitdiff
path: root/libs/libsodium/src/crypto_kx/crypto_kx.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libsodium/src/crypto_kx/crypto_kx.c')
-rw-r--r--libs/libsodium/src/crypto_kx/crypto_kx.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/libs/libsodium/src/crypto_kx/crypto_kx.c b/libs/libsodium/src/crypto_kx/crypto_kx.c
new file mode 100644
index 0000000000..877ab7ff4a
--- /dev/null
+++ b/libs/libsodium/src/crypto_kx/crypto_kx.c
@@ -0,0 +1,143 @@
+
+#include <stddef.h>
+
+#include "core.h"
+#include "crypto_generichash.h"
+#include "crypto_kx.h"
+#include "crypto_scalarmult.h"
+#include "private/common.h"
+#include "randombytes.h"
+#include "utils.h"
+
+int
+crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
+ unsigned char sk[crypto_kx_SECRETKEYBYTES],
+ const unsigned char seed[crypto_kx_SEEDBYTES])
+{
+ crypto_generichash(sk, crypto_kx_SECRETKEYBYTES,
+ seed, crypto_kx_SEEDBYTES, NULL, 0);
+ return crypto_scalarmult_base(pk, sk);
+}
+
+int
+crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
+ unsigned char sk[crypto_kx_SECRETKEYBYTES])
+{
+ COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES);
+ COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES);
+
+ randombytes_buf(sk, crypto_kx_SECRETKEYBYTES);
+ return crypto_scalarmult_base(pk, sk);
+}
+
+int
+crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
+ unsigned char tx[crypto_kx_SESSIONKEYBYTES],
+ const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
+ const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
+ const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
+{
+ crypto_generichash_state h;
+ unsigned char q[crypto_scalarmult_BYTES];
+ unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES];
+ int i;
+
+ if (rx == NULL) {
+ rx = tx;
+ }
+ if (tx == NULL) {
+ tx = rx;
+ }
+ if (rx == NULL) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ if (crypto_scalarmult(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_BYTES);
+ sodium_memzero(q, sizeof q);
+ crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
+ crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
+ crypto_generichash_final(&h, keys, sizeof keys);
+ sodium_memzero(&h, sizeof h);
+ for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) {
+ rx[i] = keys[i];
+ tx[i] = keys[i + crypto_kx_SESSIONKEYBYTES];
+ }
+ sodium_memzero(keys, sizeof keys);
+
+ return 0;
+}
+
+int
+crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
+ unsigned char tx[crypto_kx_SESSIONKEYBYTES],
+ const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES],
+ const unsigned char server_sk[crypto_kx_SECRETKEYBYTES],
+ const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES])
+{
+ crypto_generichash_state h;
+ unsigned char q[crypto_scalarmult_BYTES];
+ unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES];
+ int i;
+
+ if (rx == NULL) {
+ rx = tx;
+ }
+ if (tx == NULL) {
+ tx = rx;
+ }
+ if (rx == NULL) {
+ sodium_misuse(); /* LCOV_EXCL_LINE */
+ }
+ if (crypto_scalarmult(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_BYTES);
+ sodium_memzero(q, sizeof q);
+ crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
+ crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
+ crypto_generichash_final(&h, keys, sizeof keys);
+ sodium_memzero(&h, sizeof h);
+ for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) {
+ tx[i] = keys[i];
+ rx[i] = keys[i + crypto_kx_SESSIONKEYBYTES];
+ }
+ sodium_memzero(keys, sizeof keys);
+
+ return 0;
+}
+
+size_t
+crypto_kx_publickeybytes(void)
+{
+ return crypto_kx_PUBLICKEYBYTES;
+}
+
+size_t
+crypto_kx_secretkeybytes(void)
+{
+ return crypto_kx_SECRETKEYBYTES;
+}
+
+size_t
+crypto_kx_seedbytes(void)
+{
+ return crypto_kx_SEEDBYTES;
+}
+
+size_t
+crypto_kx_sessionkeybytes(void)
+{
+ return crypto_kx_SESSIONKEYBYTES;
+}
+
+const char *
+crypto_kx_primitive(void)
+{
+ return crypto_kx_PRIMITIVE;
+}