Add low-level kx_curve25519 functions

This commit is contained in:
Frank Denis 2018-12-25 11:10:33 +01:00
parent 7e31bbf1e5
commit 7f3bc5cd08
6 changed files with 230 additions and 89 deletions

View File

@ -1,3 +1,4 @@
lib_LTLIBRARIES = \ lib_LTLIBRARIES = \
libsodium.la libsodium.la
@ -34,6 +35,7 @@ libsodium_la_SOURCES = \
crypto_kdf/blake2b/kdf_blake2b.c \ crypto_kdf/blake2b/kdf_blake2b.c \
crypto_kdf/crypto_kdf.c \ crypto_kdf/crypto_kdf.c \
crypto_kx/crypto_kx.c \ crypto_kx/crypto_kx.c \
crypto_kx/curve25519/kx_curve25519.c \
crypto_onetimeauth/crypto_onetimeauth.c \ crypto_onetimeauth/crypto_onetimeauth.c \
crypto_onetimeauth/poly1305/onetimeauth_poly1305.c \ crypto_onetimeauth/poly1305/onetimeauth_poly1305.c \
crypto_onetimeauth/poly1305/onetimeauth_poly1305.h \ crypto_onetimeauth/poly1305/onetimeauth_poly1305.h \

View File

@ -1,33 +1,21 @@
#include <stddef.h>
#include "core.h"
#include "crypto_generichash.h"
#include "crypto_kx.h" #include "crypto_kx.h"
#include "crypto_scalarmult.h" #include "crypto_kx_curve25519.h"
#include "private/common.h" #include "private/common.h"
#include "randombytes.h"
#include "utils.h"
int int
crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
unsigned char sk[crypto_kx_SECRETKEYBYTES], unsigned char sk[crypto_kx_SECRETKEYBYTES],
const unsigned char seed[crypto_kx_SEEDBYTES]) const unsigned char seed[crypto_kx_SEEDBYTES])
{ {
crypto_generichash(sk, crypto_kx_SECRETKEYBYTES, return crypto_kx_curve25519_seed_keypair(pk, sk, seed);
seed, crypto_kx_SEEDBYTES, NULL, 0);
return crypto_scalarmult_base(pk, sk);
} }
int int
crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
unsigned char sk[crypto_kx_SECRETKEYBYTES]) unsigned char sk[crypto_kx_SECRETKEYBYTES])
{ {
COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES); return crypto_kx_curve25519_keypair(pk, sk);
COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES);
randombytes_buf(sk, crypto_kx_SECRETKEYBYTES);
return crypto_scalarmult_base(pk, sk);
} }
int int
@ -37,38 +25,8 @@ crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
const unsigned char client_sk[crypto_kx_SECRETKEYBYTES], const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES]) const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
{ {
crypto_generichash_state h; return crypto_kx_curve25519_client_session_keys(rx, tx, client_pk,
unsigned char q[crypto_scalarmult_BYTES]; client_sk, server_pk);
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 int
@ -78,66 +36,36 @@ crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], const unsigned char server_sk[crypto_kx_SECRETKEYBYTES],
const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]) const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES])
{ {
crypto_generichash_state h; return crypto_kx_curve25519_server_session_keys(rx, tx, server_pk,
unsigned char q[crypto_scalarmult_BYTES]; server_sk, client_pk);
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 size_t
crypto_kx_publickeybytes(void) crypto_kx_publickeybytes(void)
{ {
return crypto_kx_PUBLICKEYBYTES; return crypto_kx_curve25519_PUBLICKEYBYTES;
} }
size_t size_t
crypto_kx_secretkeybytes(void) crypto_kx_secretkeybytes(void)
{ {
return crypto_kx_SECRETKEYBYTES; return crypto_kx_curve25519_SECRETKEYBYTES;
} }
size_t size_t
crypto_kx_seedbytes(void) crypto_kx_seedbytes(void)
{ {
return crypto_kx_SEEDBYTES; return crypto_kx_curve25519_SEEDBYTES;
} }
size_t size_t
crypto_kx_sessionkeybytes(void) crypto_kx_sessionkeybytes(void)
{ {
return crypto_kx_SESSIONKEYBYTES; return crypto_kx_curve25519_SESSIONKEYBYTES;
} }
const char * const char *
crypto_kx_primitive(void) crypto_kx_primitive(void)
{ {
return crypto_kx_PRIMITIVE; return crypto_kx_curve25519_PRIMITIVE;
} }

View File

@ -0,0 +1,143 @@
#include <stddef.h>
#include "core.h"
#include "crypto_generichash.h"
#include "crypto_kx_curve25519.h"
#include "crypto_scalarmult_curve25519.h"
#include "private/common.h"
#include "randombytes.h"
#include "utils.h"
int
crypto_kx_curve25519_seed_keypair(unsigned char pk[crypto_kx_curve25519_PUBLICKEYBYTES],
unsigned char sk[crypto_kx_curve25519_SECRETKEYBYTES],
const unsigned char seed[crypto_kx_curve25519_SEEDBYTES])
{
crypto_generichash(sk, crypto_kx_curve25519_SECRETKEYBYTES,
seed, crypto_kx_curve25519_SEEDBYTES, NULL, 0);
return crypto_scalarmult_curve25519_base(pk, sk);
}
int
crypto_kx_curve25519_keypair(unsigned char pk[crypto_kx_curve25519_PUBLICKEYBYTES],
unsigned char sk[crypto_kx_curve25519_SECRETKEYBYTES])
{
COMPILER_ASSERT(crypto_kx_curve25519_SECRETKEYBYTES == crypto_scalarmult_curve25519_SCALARBYTES);
COMPILER_ASSERT(crypto_kx_curve25519_PUBLICKEYBYTES == crypto_scalarmult_curve25519_BYTES);
randombytes_buf(sk, crypto_kx_curve25519_SECRETKEYBYTES);
return crypto_scalarmult_curve25519_base(pk, sk);
}
int
crypto_kx_curve25519_client_session_keys(unsigned char rx[crypto_kx_curve25519_SESSIONKEYBYTES],
unsigned char tx[crypto_kx_curve25519_SESSIONKEYBYTES],
const unsigned char client_pk[crypto_kx_curve25519_PUBLICKEYBYTES],
const unsigned char client_sk[crypto_kx_curve25519_SECRETKEYBYTES],
const unsigned char server_pk[crypto_kx_curve25519_PUBLICKEYBYTES])
{
crypto_generichash_state h;
unsigned char q[crypto_scalarmult_curve25519_BYTES];
unsigned char keys[2 * crypto_kx_curve25519_SESSIONKEYBYTES];
int i;
if (rx == NULL) {
rx = tx;
}
if (tx == NULL) {
tx = rx;
}
if (rx == NULL) {
sodium_misuse(); /* LCOV_EXCL_LINE */
}
if (crypto_scalarmult_curve25519(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_curve25519_BYTES);
sodium_memzero(q, sizeof q);
crypto_generichash_update(&h, client_pk, crypto_kx_curve25519_PUBLICKEYBYTES);
crypto_generichash_update(&h, server_pk, crypto_kx_curve25519_PUBLICKEYBYTES);
crypto_generichash_final(&h, keys, sizeof keys);
sodium_memzero(&h, sizeof h);
for (i = 0; i < crypto_kx_curve25519_SESSIONKEYBYTES; i++) {
rx[i] = keys[i];
tx[i] = keys[i + crypto_kx_curve25519_SESSIONKEYBYTES];
}
sodium_memzero(keys, sizeof keys);
return 0;
}
int
crypto_kx_curve25519_server_session_keys(unsigned char rx[crypto_kx_curve25519_SESSIONKEYBYTES],
unsigned char tx[crypto_kx_curve25519_SESSIONKEYBYTES],
const unsigned char server_pk[crypto_kx_curve25519_PUBLICKEYBYTES],
const unsigned char server_sk[crypto_kx_curve25519_SECRETKEYBYTES],
const unsigned char client_pk[crypto_kx_curve25519_PUBLICKEYBYTES])
{
crypto_generichash_state h;
unsigned char q[crypto_scalarmult_curve25519_BYTES];
unsigned char keys[2 * crypto_kx_curve25519_SESSIONKEYBYTES];
int i;
if (rx == NULL) {
rx = tx;
}
if (tx == NULL) {
tx = rx;
}
if (rx == NULL) {
sodium_misuse(); /* LCOV_EXCL_LINE */
}
if (crypto_scalarmult_curve25519(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_curve25519_BYTES);
sodium_memzero(q, sizeof q);
crypto_generichash_update(&h, client_pk, crypto_kx_curve25519_PUBLICKEYBYTES);
crypto_generichash_update(&h, server_pk, crypto_kx_curve25519_PUBLICKEYBYTES);
crypto_generichash_final(&h, keys, sizeof keys);
sodium_memzero(&h, sizeof h);
for (i = 0; i < crypto_kx_curve25519_SESSIONKEYBYTES; i++) {
tx[i] = keys[i];
rx[i] = keys[i + crypto_kx_curve25519_SESSIONKEYBYTES];
}
sodium_memzero(keys, sizeof keys);
return 0;
}
size_t
crypto_kx_curve25519_publickeybytes(void)
{
return crypto_kx_curve25519_PUBLICKEYBYTES;
}
size_t
crypto_kx_curve25519_secretkeybytes(void)
{
return crypto_kx_curve25519_SECRETKEYBYTES;
}
size_t
crypto_kx_curve25519_seedbytes(void)
{
return crypto_kx_curve25519_SEEDBYTES;
}
size_t
crypto_kx_curve25519_sessionkeybytes(void)
{
return crypto_kx_curve25519_SESSIONKEYBYTES;
}
const char *
crypto_kx_curve25519_primitive(void)
{
return crypto_kx_curve25519_PRIMITIVE;
}

View File

@ -27,6 +27,7 @@
#include "sodium/crypto_kdf.h" #include "sodium/crypto_kdf.h"
#include "sodium/crypto_kdf_blake2b.h" #include "sodium/crypto_kdf_blake2b.h"
#include "sodium/crypto_kx.h" #include "sodium/crypto_kx.h"
#include "sodium/crypto_kx_curve25519.h"
#include "sodium/crypto_onetimeauth.h" #include "sodium/crypto_onetimeauth.h"
#include "sodium/crypto_onetimeauth_poly1305.h" #include "sodium/crypto_onetimeauth_poly1305.h"
#include "sodium/crypto_pwhash.h" #include "sodium/crypto_pwhash.h"

View File

@ -3,6 +3,7 @@
#include <stddef.h> #include <stddef.h>
#include "crypto_kx_curve25519.h"
#include "export.h" #include "export.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -12,23 +13,23 @@
extern "C" { extern "C" {
#endif #endif
#define crypto_kx_PUBLICKEYBYTES 32 #define crypto_kx_PUBLICKEYBYTES crypto_kx_curve25519_PUBLICKEYBYTES
SODIUM_EXPORT SODIUM_EXPORT
size_t crypto_kx_publickeybytes(void); size_t crypto_kx_publickeybytes(void);
#define crypto_kx_SECRETKEYBYTES 32 #define crypto_kx_SECRETKEYBYTES crypto_kx_curve25519_SECRETKEYBYTES
SODIUM_EXPORT SODIUM_EXPORT
size_t crypto_kx_secretkeybytes(void); size_t crypto_kx_secretkeybytes(void);
#define crypto_kx_SEEDBYTES 32 #define crypto_kx_SEEDBYTES crypto_kx_curve25519_SEEDBYTES
SODIUM_EXPORT SODIUM_EXPORT
size_t crypto_kx_seedbytes(void); size_t crypto_kx_seedbytes(void);
#define crypto_kx_SESSIONKEYBYTES 32 #define crypto_kx_SESSIONKEYBYTES crypto_kx_curve25519_SESSIONKEYBYTES
SODIUM_EXPORT SODIUM_EXPORT
size_t crypto_kx_sessionkeybytes(void); size_t crypto_kx_sessionkeybytes(void);
#define crypto_kx_PRIMITIVE "x25519blake2b" #define crypto_kx_PRIMITIVE crypto_kx_curve25519_PRIMITIVE
SODIUM_EXPORT SODIUM_EXPORT
const char *crypto_kx_primitive(void); const char *crypto_kx_primitive(void);

View File

@ -0,0 +1,66 @@
#ifndef crypto_kx_curve25519_H
#define crypto_kx_curve25519_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_kx_curve25519_PUBLICKEYBYTES 32
SODIUM_EXPORT
size_t crypto_kx_curve25519_publickeybytes(void);
#define crypto_kx_curve25519_SECRETKEYBYTES 32
SODIUM_EXPORT
size_t crypto_kx_curve25519_secretkeybytes(void);
#define crypto_kx_curve25519_SEEDBYTES 32
SODIUM_EXPORT
size_t crypto_kx_curve25519_seedbytes(void);
#define crypto_kx_curve25519_SESSIONKEYBYTES 32
SODIUM_EXPORT
size_t crypto_kx_curve25519_sessionkeybytes(void);
#define crypto_kx_curve25519_PRIMITIVE "x25519blake2b"
SODIUM_EXPORT
const char *crypto_kx_curve25519_primitive(void);
SODIUM_EXPORT
int crypto_kx_curve25519_seed_keypair(unsigned char pk[crypto_kx_curve25519_PUBLICKEYBYTES],
unsigned char sk[crypto_kx_curve25519_SECRETKEYBYTES],
const unsigned char seed[crypto_kx_curve25519_SEEDBYTES])
__attribute__ ((nonnull));
SODIUM_EXPORT
int crypto_kx_curve25519_keypair(unsigned char pk[crypto_kx_curve25519_PUBLICKEYBYTES],
unsigned char sk[crypto_kx_curve25519_SECRETKEYBYTES])
__attribute__ ((nonnull));
SODIUM_EXPORT
int crypto_kx_curve25519_client_session_keys(unsigned char rx[crypto_kx_curve25519_SESSIONKEYBYTES],
unsigned char tx[crypto_kx_curve25519_SESSIONKEYBYTES],
const unsigned char client_pk[crypto_kx_curve25519_PUBLICKEYBYTES],
const unsigned char client_sk[crypto_kx_curve25519_SECRETKEYBYTES],
const unsigned char server_pk[crypto_kx_curve25519_PUBLICKEYBYTES])
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 4, 5)));
SODIUM_EXPORT
int crypto_kx_curve25519_server_session_keys(unsigned char rx[crypto_kx_curve25519_SESSIONKEYBYTES],
unsigned char tx[crypto_kx_curve25519_SESSIONKEYBYTES],
const unsigned char server_pk[crypto_kx_curve25519_PUBLICKEYBYTES],
const unsigned char server_sk[crypto_kx_curve25519_SECRETKEYBYTES],
const unsigned char client_pk[crypto_kx_curve25519_PUBLICKEYBYTES])
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 4, 5)));
#ifdef __cplusplus
}
#endif
#endif