mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Allow arbitrary long string-to-H2C-hash operations
Make the ristretto and edwards25519 string to hash code lookalike.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user