diff --git a/src/libsodium/crypto_core/ed25519/core_ed25519.c b/src/libsodium/crypto_core/ed25519/core_ed25519.c index 2af85409..8b9e27fb 100644 --- a/src/libsodium/crypto_core/ed25519/core_ed25519.c +++ b/src/libsodium/crypto_core/ed25519/core_ed25519.c @@ -1,4 +1,5 @@ +#include #include #include #include @@ -75,24 +76,21 @@ crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r) #define HASH_BYTES crypto_hash_sha512_BYTES #define HASH_BLOCKBYTES 128U -#define HASH_L 48U -static int -_string_to_points(unsigned char * const px, size_t n, - const char *ctx, const unsigned char *msg, size_t msg_len) +static void +_string_to_h2c_hash(unsigned char *h, const size_t h_len, + const char *ctx, const unsigned char *msg, size_t msg_len) { crypto_hash_sha512_state st; const unsigned char empty_block[HASH_BLOCKBYTES] = { 0 }; - unsigned char u0[HASH_BYTES], u[2 * HASH_BYTES]; - unsigned char t[3] = { 0U, n * HASH_L, 0U}; + unsigned char u0[HASH_BYTES]; + unsigned char ux[HASH_BYTES] = { 0 }; + unsigned char t[3] = { 0U, (unsigned char) h_len, 0U}; unsigned char ctx_len_u8; size_t ctx_len = ctx != NULL ? strlen(ctx) : 0U; size_t i, j; - if (n > 2U) { - abort(); /* LCOV_EXCL_LINE */ - } - COMPILER_ASSERT(2U * HASH_L <= 0xff); + assert(h_len <= 0xff); if (ctx_len > (size_t) 0xff) { crypto_hash_sha512_init(&st); crypto_hash_sha512_update(&st, @@ -113,23 +111,43 @@ _string_to_points(unsigned char * const px, size_t n, crypto_hash_sha512_update(&st, &ctx_len_u8, 1U); crypto_hash_sha512_final(&st, u0); - for (i = 0U; i < n * HASH_BYTES; i += HASH_BYTES) { - memcpy(&u[i], u0, HASH_BYTES); - for (j = 0U; i > 0U && j < HASH_BYTES; j++) { - u[i + j] ^= u[i + j - HASH_BYTES]; + for (i = 0U; i < h_len; i += HASH_BYTES) { + for (j = 0U; j < HASH_BYTES; j++) { + ux[j] ^= u0[j]; } t[2]++; crypto_hash_sha512_init(&st); - crypto_hash_sha512_update(&st, &u[i], HASH_BYTES); + crypto_hash_sha512_update(&st, ux, HASH_BYTES); crypto_hash_sha512_update(&st, &t[2], 1U); crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); crypto_hash_sha512_update(&st, &ctx_len_u8, 1U); - crypto_hash_sha512_final(&st, &u[i]); + crypto_hash_sha512_final(&st, ux); + memcpy(&h[i], ux, h_len - i >= (sizeof ux) ? (sizeof ux) : h_len - i); } +} + +#define HASH_GE_L 48U + +static int +_string_to_points(unsigned char * const px, const size_t n, + const char *ctx, const unsigned char *msg, size_t msg_len) +{ + unsigned char h[crypto_core_ed25519_HASHBYTES]; + unsigned char h_be[2U * HASH_GE_L]; + size_t i, j; + + if (n > 2U) { + abort(); /* LCOV_EXCL_LINE */ + } + _string_to_h2c_hash(h_be, n * HASH_GE_L, ctx, msg, msg_len); + + COMPILER_ASSERT(sizeof h >= HASH_GE_L); for (i = 0U; i < n; i++) { - memset(u0, 0U, HASH_BYTES - HASH_L); - memcpy(u0 + HASH_BYTES - HASH_L, &u[i * HASH_L], HASH_L); - ge25519_from_hash(&px[i * crypto_core_ed25519_BYTES], u0); + for (j = 0U; j < HASH_GE_L; j++) { + h[j] = h_be[i * HASH_GE_L + HASH_GE_L - 1U - j]; + } + memset(&h[j], 0, (sizeof h) - j); + ge25519_from_hash(&px[i * crypto_core_ed25519_BYTES], h); } return 0; } diff --git a/src/libsodium/crypto_core/ed25519/core_ristretto255.c b/src/libsodium/crypto_core/ed25519/core_ristretto255.c index babde706..ba61c2b9 100644 --- a/src/libsodium/crypto_core/ed25519/core_ristretto255.c +++ b/src/libsodium/crypto_core/ed25519/core_ristretto255.c @@ -1,5 +1,7 @@ +#include #include +#include #include "crypto_core_ed25519.h" #include "crypto_core_ristretto255.h" @@ -70,23 +72,21 @@ crypto_core_ristretto255_from_hash(unsigned char *p, const unsigned char *r) #define HASH_BYTES crypto_hash_sha256_BYTES #define HASH_BLOCKBYTES 64U -#define HASH_L crypto_core_ristretto255_HASHBYTES -static int -_string_to_element(unsigned char *p, - const char *ctx, const unsigned char *msg, size_t msg_len) +static void +_string_to_h2c_hash(unsigned char *h, const size_t h_len, + const char *ctx, const unsigned char *msg, size_t msg_len) { crypto_hash_sha256_state st; const unsigned char empty_block[HASH_BLOCKBYTES] = { 0 }; unsigned char u0[HASH_BYTES]; - unsigned char u[2 * HASH_BYTES]; - unsigned char t[3] = { 0U, HASH_L, 0U}; + unsigned char ux[HASH_BYTES] = { 0 }; + unsigned char t[3] = { 0U, (unsigned char) h_len, 0U}; unsigned char ctx_len_u8; size_t ctx_len = ctx != NULL ? strlen(ctx) : 0U; - size_t i; + size_t i, j; - COMPILER_ASSERT(HASH_L == sizeof u); - COMPILER_ASSERT(HASH_L <= 0xff); + assert(h_len <= 0xff); if (ctx_len > (size_t) 0xff) { crypto_hash_sha256_init(&st); crypto_hash_sha256_update(&st, @@ -107,27 +107,29 @@ _string_to_element(unsigned char *p, crypto_hash_sha256_update(&st, &ctx_len_u8, 1U); crypto_hash_sha256_final(&st, u0); - t[2]++; - crypto_hash_sha256_init(&st); - crypto_hash_sha256_update(&st, u0, HASH_BYTES); - crypto_hash_sha256_update(&st, &t[2], 1U); - crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); - crypto_hash_sha256_update(&st, &ctx_len_u8, 1U); - crypto_hash_sha256_final(&st, u); - - t[2]++; - crypto_hash_sha256_init(&st); - for (i = 0; i < HASH_BYTES; i++) { - u[32 + i] = u[i] ^ u0[i]; + for (i = 0U; i < h_len; i += HASH_BYTES) { + for (j = 0U; j < HASH_BYTES; j++) { + ux[j] ^= u0[j]; + } + t[2]++; + crypto_hash_sha256_init(&st); + crypto_hash_sha256_update(&st, ux, HASH_BYTES); + crypto_hash_sha256_update(&st, &t[2], 1U); + crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha256_update(&st, &ctx_len_u8, 1U); + crypto_hash_sha256_final(&st, ux); + memcpy(&h[i], ux, h_len - i >= (sizeof ux) ? (sizeof ux) : h_len - i); } - crypto_hash_sha256_update(&st, &u[32], HASH_BYTES); - crypto_hash_sha256_update(&st, &t[2], 1U); - crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); - crypto_hash_sha256_update(&st, &ctx_len_u8, 1U); - crypto_hash_sha256_final(&st, &u[32]); +} - COMPILER_ASSERT(crypto_core_ristretto255_HASHBYTES == HASH_L); - ristretto255_from_hash(p, u); +static int +_string_to_element(unsigned char *p, + const char *ctx, const unsigned char *msg, size_t msg_len) +{ + unsigned char h[crypto_core_ristretto255_HASHBYTES]; + + _string_to_h2c_hash(h, sizeof h, ctx, msg, msg_len); + ristretto255_from_hash(p, h); return 0; } @@ -218,6 +220,29 @@ crypto_core_ristretto255_scalar_is_canonical(const unsigned char *s) return sc25519_is_canonical(s); } +#define HASH_SC_L 48U + +int +crypto_core_ristretto255_scalar_from_string(unsigned char *s, + const char *ctx, const unsigned char *msg, + size_t msg_len) +{ + unsigned char h[crypto_core_ristretto255_NONREDUCEDSCALARBYTES]; + unsigned char h_be[HASH_SC_L]; + size_t i; + + _string_to_h2c_hash(h_be, sizeof h_be, ctx, msg, msg_len); + + COMPILER_ASSERT(sizeof h >= sizeof h_be); + for (i = 0U; i < HASH_SC_L; i++) { + h[i] = h_be[HASH_SC_L - 1U - i]; + } + memset(&h[i], 0, (sizeof h) - i); + crypto_core_ristretto255_scalar_reduce(s, h); + + return 0; +} + size_t crypto_core_ristretto255_bytes(void) { diff --git a/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c b/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c index d8ad4ec3..2f23cb00 100644 --- a/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c +++ b/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c @@ -2714,15 +2714,13 @@ fe25519_reduce64(fe25519 fe_f, const unsigned char h[64]) fe25519 fe_g; size_t i; - for (i = 0; i < 32; i++) { - fl[i] = h[63 - i]; - gl[i] = h[31 - i]; - } + memcpy(fl, h, 32); + memcpy(gl, h + 32, 32); fl[31] &= 0x7f; gl[31] &= 0x7f; fe25519_frombytes(fe_f, fl); fe25519_frombytes(fe_g, gl); - fe_f[0] += (h[32] >> 7) * 19; + fe_f[0] += (h[31] >> 7) * 19; for (i = 0; i < sizeof (fe25519) / sizeof fe_f[0]; i++) { fe_f[i] += 38 * fe_g[i]; }