mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Add crypto_core_ed25519_scalar_from_string
This commit is contained in:
@@ -232,6 +232,32 @@ crypto_core_ed25519_scalar_is_canonical(const unsigned char *s)
|
||||
return sc25519_is_canonical(s);
|
||||
}
|
||||
|
||||
#define HASH_SC_L 48U
|
||||
|
||||
int
|
||||
crypto_core_ed25519_scalar_from_string(unsigned char *s,
|
||||
const unsigned char *ctx, size_t ctx_len,
|
||||
const unsigned char *msg, size_t msg_len,
|
||||
int hash_alg)
|
||||
{
|
||||
unsigned char h[crypto_core_ed25519_NONREDUCEDSCALARBYTES];
|
||||
unsigned char h_be[HASH_SC_L];
|
||||
size_t i;
|
||||
|
||||
if (core_h2c_string_to_hash(h_be, sizeof h_be, ctx, ctx_len, msg, msg_len,
|
||||
hash_alg) != 0) {
|
||||
return -1;
|
||||
}
|
||||
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_ed25519_scalar_reduce(s, h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
crypto_core_ed25519_bytes(void)
|
||||
{
|
||||
|
||||
@@ -159,30 +159,14 @@ 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 unsigned char *ctx, size_t ctx_len,
|
||||
const unsigned char *msg, size_t msg_len,
|
||||
int hash_alg)
|
||||
{
|
||||
unsigned char h[crypto_core_ristretto255_NONREDUCEDSCALARBYTES];
|
||||
unsigned char h_be[HASH_SC_L];
|
||||
size_t i;
|
||||
|
||||
if (core_h2c_string_to_hash(h_be, sizeof h_be, ctx, ctx_len, msg, msg_len,
|
||||
hash_alg) != 0) {
|
||||
return -1;
|
||||
}
|
||||
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;
|
||||
return crypto_core_ed25519_scalar_from_string(s, ctx, ctx_len, msg, msg_len,
|
||||
hash_alg);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -102,6 +102,13 @@ SODIUM_EXPORT
|
||||
void crypto_core_ed25519_scalar_reduce(unsigned char *r, const unsigned char *s)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_core_ed25519_scalar_from_string(unsigned char *s,
|
||||
const unsigned char *ctx, size_t ctx_len,
|
||||
const unsigned char *msg, size_t msg_len,
|
||||
int hash_alg)
|
||||
__attribute__ ((nonnull(1)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_core_ed25519_scalar_is_canonical(const unsigned char *s)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
@@ -103,6 +103,13 @@ void crypto_core_ristretto255_scalar_reduce(unsigned char *r,
|
||||
const unsigned char *s)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_core_ristretto255_scalar_from_string(unsigned char *s,
|
||||
const unsigned char *ctx, size_t ctx_len,
|
||||
const unsigned char *msg, size_t msg_len,
|
||||
int hash_alg)
|
||||
__attribute__ ((nonnull(1)));
|
||||
|
||||
SODIUM_EXPORT
|
||||
int crypto_core_ristretto255_scalar_is_canonical(const unsigned char *s)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
@@ -65,10 +65,102 @@ static TestData test_data[] = {
|
||||
"6dc2fc04f266c5c27f236a80b14f92ccd051ef1ff027f26a07f8c0f327d8f995" }
|
||||
};
|
||||
|
||||
static void
|
||||
test_scalar_from_string(void)
|
||||
{
|
||||
static const struct {
|
||||
int hash_alg;
|
||||
const char *msg;
|
||||
size_t msg_len;
|
||||
const char *ctx;
|
||||
size_t ctx_len;
|
||||
const char expected[65];
|
||||
} scalar_tvs[] = {
|
||||
{ 1, "", 0U, "test-dst", 8U,
|
||||
"28dae5fcb05a81163b41a90fc54e3e815613194ddd44b1e718bfab7457536705" },
|
||||
{ 2, "", 0U, "test-dst", 8U,
|
||||
"110d25b6c0f2ab15d9387d4d77847e62c3b133da1bcc71e588076765c74e0b03" },
|
||||
{ 1, "abc", 3U, "test-dst", 8U,
|
||||
"8a2383018254b8b57b624f049bc2e72c1c401ad0959b10d1d24ad863fcb5060c" },
|
||||
{ 2, "abc", 3U, "test-dst", 8U,
|
||||
"cc954e2d86fdba2af74270642bd6375bdf13e485077bb56a648aaf243d4a8007" },
|
||||
{ 2, "", 0U, "", 0U,
|
||||
"c9fb227ffae5fa378f3e6cbbafe054989748daae21c9ebe907f7b68d14093a06" },
|
||||
};
|
||||
unsigned char s_ed[crypto_core_ed25519_SCALARBYTES];
|
||||
unsigned char expected_s[crypto_core_ed25519_SCALARBYTES];
|
||||
char s_hex[crypto_core_ed25519_SCALARBYTES * 2U + 1U];
|
||||
size_t oversized_len = 256U;
|
||||
unsigned char *big_ctx;
|
||||
size_t t;
|
||||
|
||||
for (t = 0U; t < sizeof scalar_tvs / sizeof scalar_tvs[0]; t++) {
|
||||
sodium_hex2bin(expected_s, sizeof expected_s,
|
||||
scalar_tvs[t].expected, (size_t) -1U,
|
||||
NULL, NULL, NULL);
|
||||
if (crypto_core_ed25519_scalar_from_string(
|
||||
s_ed,
|
||||
(const unsigned char *) scalar_tvs[t].ctx,
|
||||
scalar_tvs[t].ctx_len,
|
||||
(const unsigned char *) scalar_tvs[t].msg,
|
||||
scalar_tvs[t].msg_len,
|
||||
scalar_tvs[t].hash_alg) != 0) {
|
||||
printf("scalar_from_string: ed25519 call failed for tv %u\n",
|
||||
(unsigned) t);
|
||||
continue;
|
||||
}
|
||||
if (memcmp(s_ed, expected_s, sizeof expected_s) != 0) {
|
||||
sodium_bin2hex(s_hex, sizeof s_hex, s_ed, sizeof s_ed);
|
||||
printf("scalar_from_string: ed25519 KAT %u mismatch: %s\n",
|
||||
(unsigned) t, s_hex);
|
||||
}
|
||||
if (crypto_core_ed25519_scalar_is_canonical(s_ed) != 1) {
|
||||
printf("scalar_from_string: ed25519 result %u not canonical\n",
|
||||
(unsigned) t);
|
||||
}
|
||||
}
|
||||
|
||||
if (crypto_core_ed25519_scalar_from_string(
|
||||
s_ed,
|
||||
(const unsigned char *) "test-dst", 8U,
|
||||
(const unsigned char *) "abc", 3U,
|
||||
0) != -1) {
|
||||
printf("scalar_from_string: invalid hash_alg 0 should fail\n");
|
||||
}
|
||||
if (crypto_core_ed25519_scalar_from_string(
|
||||
s_ed,
|
||||
(const unsigned char *) "test-dst", 8U,
|
||||
(const unsigned char *) "abc", 3U,
|
||||
99) != -1) {
|
||||
printf("scalar_from_string: invalid hash_alg 99 should fail\n");
|
||||
}
|
||||
|
||||
big_ctx = (unsigned char *) sodium_malloc(oversized_len);
|
||||
memset(big_ctx, 'X', oversized_len);
|
||||
|
||||
if (crypto_core_ed25519_scalar_from_string(
|
||||
s_ed, big_ctx, oversized_len,
|
||||
(const unsigned char *) "abc", 3U, 2) != 0) {
|
||||
printf("scalar_from_string: oversized DST SHA-512 failed\n");
|
||||
}
|
||||
sodium_bin2hex(s_hex, sizeof s_hex, s_ed, sizeof s_ed);
|
||||
printf("scalar_from_string oversized DST/sha512: %s\n", s_hex);
|
||||
|
||||
if (crypto_core_ed25519_scalar_from_string(
|
||||
s_ed, big_ctx, oversized_len,
|
||||
(const unsigned char *) "abc", 3U, 1) != 0) {
|
||||
printf("scalar_from_string: oversized DST SHA-256 failed\n");
|
||||
}
|
||||
sodium_bin2hex(s_hex, sizeof s_hex, s_ed, sizeof s_ed);
|
||||
printf("scalar_from_string oversized DST/sha256: %s\n", s_hex);
|
||||
|
||||
sodium_free(big_ctx);
|
||||
}
|
||||
|
||||
#define H2CHASH crypto_core_ed25519_H2CSHA512
|
||||
|
||||
int
|
||||
main(void)
|
||||
static void
|
||||
test_from_string(void)
|
||||
{
|
||||
unsigned char *expected_xr, *expected_x;
|
||||
unsigned char *expected_yr, *expected_y, *y;
|
||||
@@ -167,6 +259,13 @@ main(void)
|
||||
sodium_free(expected_yr);
|
||||
sodium_free(expected_x);
|
||||
sodium_free(expected_xr);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
test_scalar_from_string();
|
||||
test_from_string();
|
||||
|
||||
printf("OK\n");
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
NU with oversized context: 998ca2fdd0ade350cb6c279173dfd4a6a42f46ca5c2928871aacff60c16546e3
|
||||
RO with oversized context: 5ed4ae2ab665a7a9543f6e9887dc8f8f68a7720fdf32b971f3be71d9c9549ff4
|
||||
scalar_from_string oversized DST/sha512: 65a9285a623f62fb45d3f7f1598bb32d361c0e504d70d8401f28784af854cc09
|
||||
scalar_from_string oversized DST/sha256: 9520c0e0dc6af766f5708c4a4b355dba66cf15462f2556c6fa8ccc03aaa0e102
|
||||
OK
|
||||
|
||||
@@ -26,10 +26,102 @@ static TestData test_data[] = {
|
||||
"caff66fcdc41da4d87ccc72aaac70c6e267a4b55c3dc9489bb365a70a04f1a52" },
|
||||
};
|
||||
|
||||
static void
|
||||
test_scalar_from_string(void)
|
||||
{
|
||||
static const struct {
|
||||
int hash_alg;
|
||||
const char *msg;
|
||||
size_t msg_len;
|
||||
const char *ctx;
|
||||
size_t ctx_len;
|
||||
const char expected[65];
|
||||
} scalar_tvs[] = {
|
||||
{ 1, "", 0U, "test-dst", 8U,
|
||||
"28dae5fcb05a81163b41a90fc54e3e815613194ddd44b1e718bfab7457536705" },
|
||||
{ 2, "", 0U, "test-dst", 8U,
|
||||
"110d25b6c0f2ab15d9387d4d77847e62c3b133da1bcc71e588076765c74e0b03" },
|
||||
{ 1, "abc", 3U, "test-dst", 8U,
|
||||
"8a2383018254b8b57b624f049bc2e72c1c401ad0959b10d1d24ad863fcb5060c" },
|
||||
{ 2, "abc", 3U, "test-dst", 8U,
|
||||
"cc954e2d86fdba2af74270642bd6375bdf13e485077bb56a648aaf243d4a8007" },
|
||||
{ 2, "", 0U, "", 0U,
|
||||
"c9fb227ffae5fa378f3e6cbbafe054989748daae21c9ebe907f7b68d14093a06" },
|
||||
};
|
||||
unsigned char s[crypto_core_ristretto255_SCALARBYTES];
|
||||
unsigned char expected_s[crypto_core_ristretto255_SCALARBYTES];
|
||||
char s_hex[crypto_core_ristretto255_SCALARBYTES * 2U + 1U];
|
||||
size_t oversized_len = 256U;
|
||||
unsigned char *big_ctx;
|
||||
size_t t;
|
||||
|
||||
for (t = 0U; t < sizeof scalar_tvs / sizeof scalar_tvs[0]; t++) {
|
||||
sodium_hex2bin(expected_s, sizeof expected_s,
|
||||
scalar_tvs[t].expected, (size_t) -1U,
|
||||
NULL, NULL, NULL);
|
||||
if (crypto_core_ristretto255_scalar_from_string(
|
||||
s,
|
||||
(const unsigned char *) scalar_tvs[t].ctx,
|
||||
scalar_tvs[t].ctx_len,
|
||||
(const unsigned char *) scalar_tvs[t].msg,
|
||||
scalar_tvs[t].msg_len,
|
||||
scalar_tvs[t].hash_alg) != 0) {
|
||||
printf("scalar_from_string: call failed for tv %u\n",
|
||||
(unsigned) t);
|
||||
continue;
|
||||
}
|
||||
if (memcmp(s, expected_s, sizeof expected_s) != 0) {
|
||||
sodium_bin2hex(s_hex, sizeof s_hex, s, sizeof s);
|
||||
printf("scalar_from_string: KAT %u mismatch: %s\n",
|
||||
(unsigned) t, s_hex);
|
||||
}
|
||||
if (crypto_core_ristretto255_scalar_is_canonical(s) != 1) {
|
||||
printf("scalar_from_string: result %u not canonical\n",
|
||||
(unsigned) t);
|
||||
}
|
||||
}
|
||||
|
||||
if (crypto_core_ristretto255_scalar_from_string(
|
||||
s,
|
||||
(const unsigned char *) "test-dst", 8U,
|
||||
(const unsigned char *) "abc", 3U,
|
||||
0) != -1) {
|
||||
printf("scalar_from_string: invalid hash_alg 0 should fail\n");
|
||||
}
|
||||
if (crypto_core_ristretto255_scalar_from_string(
|
||||
s,
|
||||
(const unsigned char *) "test-dst", 8U,
|
||||
(const unsigned char *) "abc", 3U,
|
||||
99) != -1) {
|
||||
printf("scalar_from_string: invalid hash_alg 99 should fail\n");
|
||||
}
|
||||
|
||||
big_ctx = (unsigned char *) sodium_malloc(oversized_len);
|
||||
memset(big_ctx, 'X', oversized_len);
|
||||
|
||||
if (crypto_core_ristretto255_scalar_from_string(
|
||||
s, big_ctx, oversized_len,
|
||||
(const unsigned char *) "abc", 3U, 2) != 0) {
|
||||
printf("scalar_from_string: oversized DST SHA-512 failed\n");
|
||||
}
|
||||
sodium_bin2hex(s_hex, sizeof s_hex, s, sizeof s);
|
||||
printf("scalar_from_string oversized DST/sha512: %s\n", s_hex);
|
||||
|
||||
if (crypto_core_ristretto255_scalar_from_string(
|
||||
s, big_ctx, oversized_len,
|
||||
(const unsigned char *) "abc", 3U, 1) != 0) {
|
||||
printf("scalar_from_string: oversized DST SHA-256 failed\n");
|
||||
}
|
||||
sodium_bin2hex(s_hex, sizeof s_hex, s, sizeof s);
|
||||
printf("scalar_from_string oversized DST/sha256: %s\n", s_hex);
|
||||
|
||||
sodium_free(big_ctx);
|
||||
}
|
||||
|
||||
#define H2CHASH crypto_core_ristretto255_H2CSHA512
|
||||
|
||||
int
|
||||
main(void)
|
||||
static void
|
||||
test_from_string_ro(void)
|
||||
{
|
||||
unsigned char *p, *expected, *input;
|
||||
char *p_hex, *expected_hex;
|
||||
@@ -38,10 +130,6 @@ main(void)
|
||||
size_t oversized_ctx_len = 500U;
|
||||
size_t input_len;
|
||||
|
||||
/*
|
||||
* DST = "HashToGroup-OPRFV1-" || mode_byte || "-ristretto255-SHA512"
|
||||
* The mode byte at offset 19 is patched per test vector.
|
||||
*/
|
||||
unsigned char dst[] = {
|
||||
'H','a','s','h','T','o','G','r','o','u','p','-',
|
||||
'O','P','R','F','V','1','-', 0x00, '-',
|
||||
@@ -105,6 +193,13 @@ main(void)
|
||||
sodium_free(input);
|
||||
sodium_free(expected);
|
||||
sodium_free(p);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
test_scalar_from_string();
|
||||
test_from_string_ro();
|
||||
|
||||
printf("OK\n");
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
RO with oversized context: eedf0384646af8a94b9c8153490ce78f2e79f301800b33f4bfa655bcdc4fb135
|
||||
scalar_from_string oversized DST/sha512: 65a9285a623f62fb45d3f7f1598bb32d361c0e504d70d8401f28784af854cc09
|
||||
scalar_from_string oversized DST/sha256: 9520c0e0dc6af766f5708c4a4b355dba66cf15462f2556c6fa8ccc03aaa0e102
|
||||
OK
|
||||
|
||||
@@ -202,6 +202,7 @@ crypto_core_ed25519_nonreducedscalarbytes
|
||||
crypto_core_ed25519_random
|
||||
crypto_core_ed25519_scalar_add
|
||||
crypto_core_ed25519_scalar_complement
|
||||
crypto_core_ed25519_scalar_from_string
|
||||
crypto_core_ed25519_scalar_invert
|
||||
crypto_core_ed25519_scalar_is_canonical
|
||||
crypto_core_ed25519_scalar_mul
|
||||
|
||||
Reference in New Issue
Block a user