diff --git a/src/libsodium/crypto_core/ed25519/core_ristretto255.c b/src/libsodium/crypto_core/ed25519/core_ristretto255.c index ab3f7757..6cb1b0b9 100644 --- a/src/libsodium/crypto_core/ed25519/core_ristretto255.c +++ b/src/libsodium/crypto_core/ed25519/core_ristretto255.c @@ -3,6 +3,7 @@ #include "crypto_core_ed25519.h" #include "crypto_core_ristretto255.h" +#include "crypto_hash_sha512.h" #include "private/common.h" #include "private/ed25519_ref10.h" #include "randombytes.h" @@ -67,6 +68,72 @@ crypto_core_ristretto255_from_hash(unsigned char *p, const unsigned char *r) return 0; } +#define HASH_BYTES crypto_hash_sha512_BYTES +#define HASH_BLOCKBYTES 128U +#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) +{ + crypto_hash_sha512_state st; + const unsigned char empty_block[128] = { 0 }; + unsigned char u0[HASH_BYTES]; + unsigned char t[3] = { 0U, HASH_L, 0U}; + unsigned char ctx_len_u8; + size_t ctx_len = ctx != NULL ? strlen(ctx) : 0U; + + COMPILER_ASSERT(HASH_L <= 0xff); + if (ctx_len > (size_t) 0xff) { + crypto_hash_sha512_init(&st); + crypto_hash_sha512_update(&st, + (const unsigned char *) "H2C-OVERSIZE-DST-", + sizeof "H2C-OVERSIZE-DST-" - 1U); + crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha512_final(&st, u0); + ctx = (const char *) u0; + ctx_len = HASH_BYTES; + COMPILER_ASSERT(HASH_BYTES <= (size_t) 0xff); + } + ctx_len_u8 = (unsigned char) ctx_len; + crypto_hash_sha512_init(&st); + crypto_hash_sha512_update(&st, empty_block, sizeof empty_block); + crypto_hash_sha512_update(&st, msg, msg_len); + crypto_hash_sha512_update(&st, t, 3U); + 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, u0); + + t[2]++; + crypto_hash_sha512_init(&st); + crypto_hash_sha512_update(&st, u0, 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, u0); + + COMPILER_ASSERT(crypto_core_ristretto255_HASHBYTES == HASH_L); + ristretto255_from_hash(p, u0); + + return 0; +} + +int +crypto_core_risretto255_from_string(unsigned char p[crypto_core_ristretto255_BYTES], + const char *ctx, const unsigned char *msg, + size_t msg_len) +{ + return _string_to_element(p, ctx, msg, msg_len); +} + +int +crypto_core_ristretto255_from_string_ro(unsigned char p[crypto_core_ristretto255_BYTES], + const char *ctx, const unsigned char *msg, + size_t msg_len) +{ + return crypto_core_risretto255_from_string(p, ctx, msg, msg_len); +} + void crypto_core_ristretto255_random(unsigned char *p) { diff --git a/src/libsodium/include/sodium/crypto_core_ristretto255.h b/src/libsodium/include/sodium/crypto_core_ristretto255.h index d2485adc..c22dfdd4 100644 --- a/src/libsodium/include/sodium/crypto_core_ristretto255.h +++ b/src/libsodium/include/sodium/crypto_core_ristretto255.h @@ -43,6 +43,20 @@ int crypto_core_ristretto255_from_hash(unsigned char *p, const unsigned char *r) __attribute__ ((nonnull)); +SODIUM_EXPORT +int crypto_core_ristretto255_from_string(unsigned char p[crypto_core_ristretto255_BYTES], + const char *ctx, + const unsigned char *msg, + size_t msg_len) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_core_ristretto255_from_string_ro(unsigned char p[crypto_core_ristretto255_BYTES], + const char *ctx, + const unsigned char *msg, + size_t msg_len) + __attribute__ ((nonnull(1))); + SODIUM_EXPORT void crypto_core_ristretto255_random(unsigned char *p) __attribute__ ((nonnull));