1
mirror of https://github.com/jedisct1/libsodium.git synced 2024-12-23 20:15:19 -07:00

Add core_ed25519_from_hash() and core_{ed25519, ristretto255}_random()

This commit is contained in:
Frank Denis 2019-05-02 00:51:17 +02:00
parent 689407c36d
commit 24c54073a8
8 changed files with 115 additions and 27 deletions

View File

@ -67,7 +67,24 @@ crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r)
{
ge25519_from_uniform(p, r);
return - ge25519_has_small_order(p);
return 0;
}
int
crypto_core_ed25519_from_hash(unsigned char *p, const unsigned char *h)
{
ge25519_from_hash(p, h);
return 0;
}
void
crypto_core_ed25519_random(unsigned char *p)
{
unsigned char h[crypto_core_ed25519_HASHBYTES];
randombytes_buf(h, sizeof h);
(void) crypto_core_ed25519_from_hash(p, h);
}
void
@ -195,6 +212,12 @@ crypto_core_ed25519_uniformbytes(void)
return crypto_core_ed25519_UNIFORMBYTES;
}
size_t
crypto_core_ed25519_hashbytes(void)
{
return crypto_core_ed25519_HASHBYTES;
}
size_t
crypto_core_ed25519_scalarbytes(void)
{

View File

@ -67,6 +67,15 @@ crypto_core_ristretto255_from_hash(unsigned char *p, const unsigned char *r)
return 0;
}
void
crypto_core_ristretto255_random(unsigned char *p)
{
unsigned char h[crypto_core_ristretto255_HASHBYTES];
randombytes_buf(h, sizeof h);
(void) crypto_core_ristretto255_from_hash(p, h);
}
void
crypto_core_ristretto255_scalar_random(unsigned char *r)
{

View File

@ -2525,8 +2525,8 @@ chi25519(fe25519 out, const fe25519 z)
fe25519_mul(out, t1, t0);
}
void
ge25519_from_uniform(unsigned char s[32], const unsigned char r[32])
static void
ge25519_elligator2(unsigned char s[32], const unsigned char x_sign)
{
fe25519 e;
fe25519 negx;
@ -2536,15 +2536,9 @@ ge25519_from_uniform(unsigned char s[32], const unsigned char r[32])
ge25519_p1p1 p1;
ge25519_p2 p2;
unsigned int e_is_minus_1;
unsigned char x_sign;
memcpy(s, r, 32);
x_sign = s[31] & 0x80;
s[31] &= 0x7f;
fe25519_frombytes(rr2, s);
/* elligator */
fe25519_sq2(rr2, rr2);
rr2[0]++;
fe25519_invert(rr2, rr2);
@ -2600,6 +2594,31 @@ ge25519_from_uniform(unsigned char s[32], const unsigned char r[32])
ge25519_p3_tobytes(s, &p3);
}
void
ge25519_from_uniform(unsigned char s[32], const unsigned char r[32])
{
unsigned char x_sign;
memcpy(s, r, 32);
x_sign = s[31] & 0x80;
s[31] &= 0x7f;
ge25519_elligator2(s, x_sign);
}
void
ge25519_from_hash(unsigned char s[32], const unsigned char h[64])
{
unsigned char r[64];
unsigned char x_sign;
memcpy(r, h, 64);
x_sign = h[63] & 0x80;
r[63] &= 0x7f;
sc25519_reduce(r);
memcpy(s, r, 32);
ge25519_elligator2(s, x_sign);
}
/* Ristretto group */
static int
@ -2815,7 +2834,7 @@ ristretto255_elligator(ge25519_p3 *p, const fe25519 t)
}
void
ristretto255_from_hash(unsigned char s[32], const unsigned char r[64])
ristretto255_from_hash(unsigned char s[32], const unsigned char h[64])
{
fe25519 r0, r1;
ge25519_cached p1_cached;
@ -2823,8 +2842,8 @@ ristretto255_from_hash(unsigned char s[32], const unsigned char r[64])
ge25519_p3 p0, p1;
ge25519_p3 p;
fe25519_frombytes(r0, r);
fe25519_frombytes(r1, r + 32);
fe25519_frombytes(r0, h);
fe25519_frombytes(r1, h + 32);
ristretto255_elligator(&p0, r0);
ristretto255_elligator(&p1, r1);
ge25519_p3_to_cached(&p1_cached, &p1);

View File

@ -16,6 +16,10 @@ size_t crypto_core_ed25519_bytes(void);
SODIUM_EXPORT
size_t crypto_core_ed25519_uniformbytes(void);
#define crypto_core_ed25519_HASHBYTES 64
SODIUM_EXPORT
size_t crypto_core_ed25519_hashbytes(void);
#define crypto_core_ed25519_SCALARBYTES 32
SODIUM_EXPORT
size_t crypto_core_ed25519_scalarbytes(void);
@ -42,6 +46,14 @@ SODIUM_EXPORT
int crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r)
__attribute__ ((nonnull));
SODIUM_EXPORT
int crypto_core_ed25519_from_hash(unsigned char *p, const unsigned char *h)
__attribute__ ((nonnull));
SODIUM_EXPORT
void crypto_core_ed25519_random(unsigned char *p)
__attribute__ ((nonnull));
SODIUM_EXPORT
void crypto_core_ed25519_scalar_random(unsigned char *r)
__attribute__ ((nonnull));

View File

@ -43,6 +43,10 @@ int crypto_core_ristretto255_from_hash(unsigned char *p,
const unsigned char *r)
__attribute__ ((nonnull));
SODIUM_EXPORT
void crypto_core_ristretto255_random(unsigned char *p)
__attribute__ ((nonnull));
SODIUM_EXPORT
void crypto_core_ristretto255_scalar_random(unsigned char *r)
__attribute__ ((nonnull));

View File

@ -110,6 +110,8 @@ int ge25519_has_small_order(const unsigned char s[32]);
void ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]);
void ge25519_from_hash(unsigned char s[32], const unsigned char h[64]);
/*
Ristretto group
*/
@ -118,7 +120,7 @@ int ristretto255_frombytes(ge25519_p3 *h, const unsigned char *s);
void ristretto255_p3_tobytes(unsigned char *s, const ge25519_p3 *h);
void ristretto255_from_hash(unsigned char s[32], const unsigned char r[64]);
void ristretto255_from_hash(unsigned char s[32], const unsigned char h[64]);
/*
The set of scalars is \Z/l

View File

@ -44,29 +44,43 @@ add_l64(unsigned char * const S)
int
main(void)
{
unsigned char *h;
unsigned char *h, *r;
unsigned char *p, *p2, *p3;
unsigned char *sc, *sc2, *sc3;
unsigned char *sc64;
char *hex;
unsigned int i, j;
h = (unsigned char *) sodium_malloc(crypto_core_ed25519_UNIFORMBYTES);
h = (unsigned char *) sodium_malloc(crypto_core_ed25519_HASHBYTES);
r = (unsigned char *) sodium_malloc(crypto_core_ed25519_UNIFORMBYTES);
p = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES);
for (i = 0; i < 1000; i++) {
randombytes_buf(h, crypto_core_ed25519_UNIFORMBYTES);
if (crypto_core_ed25519_from_uniform(p, h) != 0) {
for (i = 0; i < 500; i++) {
randombytes_buf(r, crypto_core_ed25519_UNIFORMBYTES);
if (crypto_core_ed25519_from_uniform(p, r) != 0) {
printf("crypto_core_ed25519_from_uniform() failed\n");
}
if (crypto_core_ed25519_is_valid_point(p) == 0) {
printf("crypto_core_ed25519_from_uniform() returned an invalid point\n");
}
randombytes_buf(h, crypto_core_ed25519_HASHBYTES);
if (crypto_core_ed25519_from_hash(p, h) != 0) {
printf("crypto_core_ed25519_from_hash() failed\n");
}
if (crypto_core_ed25519_is_valid_point(p) == 0) {
printf("crypto_core_ed25519_from_hash() returned an invalid point\n");
}
crypto_core_ed25519_random(p);
if (crypto_core_ed25519_is_valid_point(p) == 0) {
printf("crypto_core_ed25519_random() returned an invalid point\n");
}
}
p2 = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES);
p3 = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES);
randombytes_buf(h, crypto_core_ed25519_UNIFORMBYTES);
crypto_core_ed25519_from_uniform(p2, h);
crypto_core_ed25519_random(p2);
j = 1 + (unsigned int) randombytes_uniform(100);
memcpy(p3, p, crypto_core_ed25519_BYTES);
@ -145,8 +159,7 @@ main(void)
assert(crypto_core_ed25519_sub(p3, non_canonical_invalid_p, p3) == -1);
for (i = 0; i < 1000; i++) {
randombytes_buf(h, crypto_core_ed25519_UNIFORMBYTES);
crypto_core_ed25519_from_uniform(p, h);
crypto_core_ed25519_random(p);
do {
crypto_core_ed25519_scalar_random(sc);
} while (sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES));
@ -177,8 +190,8 @@ main(void)
printf("crypto_core_ed25519_scalar_reduce() failed\n");
}
randombytes_buf(h, crypto_core_ed25519_UNIFORMBYTES);
crypto_core_ed25519_from_uniform(p, h);
randombytes_buf(r, crypto_core_ed25519_UNIFORMBYTES);
crypto_core_ed25519_from_uniform(p, r);
memcpy(p2, p, crypto_core_ed25519_BYTES);
crypto_core_ed25519_scalar_random(sc);
if (crypto_scalarmult_ed25519_noclamp(p, sc, p) != 0) {
@ -189,15 +202,14 @@ main(void)
printf("crypto_scalarmult_ed25519_noclamp() failed (2)\n");
}
crypto_core_ed25519_add(p3, p, p2);
crypto_core_ed25519_from_uniform(p, h);
crypto_core_ed25519_from_uniform(p, r);
crypto_core_ed25519_sub(p, p, p3);
assert(p[0] == 0x01);
for (i = 1; i < crypto_core_ed25519_BYTES; i++) {
assert(p[i] == 0);
}
randombytes_buf(h, crypto_core_ed25519_UNIFORMBYTES);
crypto_core_ed25519_from_uniform(p, h);
crypto_core_ed25519_random(p);
memcpy(p2, p, crypto_core_ed25519_BYTES);
crypto_core_ed25519_scalar_random(sc);
if (crypto_scalarmult_ed25519_noclamp(p, sc, p) != 0) {
@ -383,6 +395,7 @@ main(void)
sodium_free(p3);
sodium_free(p2);
sodium_free(p);
sodium_free(r);
sodium_free(h);
assert(crypto_core_ed25519_BYTES == crypto_core_ed25519_bytes());
@ -391,6 +404,8 @@ main(void)
assert(crypto_core_ed25519_NONREDUCEDSCALARBYTES >= crypto_core_ed25519_SCALARBYTES);
assert(crypto_core_ed25519_UNIFORMBYTES == crypto_core_ed25519_uniformbytes());
assert(crypto_core_ed25519_UNIFORMBYTES >= crypto_core_ed25519_BYTES);
assert(crypto_core_ed25519_HASHBYTES == crypto_core_ed25519_hashbytes());
assert(crypto_core_ed25519_HASHBYTES >= 2 * crypto_core_ed25519_BYTES);
printf("OK\n");

View File

@ -135,6 +135,10 @@ tv3(void)
crypto_core_ristretto255_is_valid_point(s) != 1) {
printf("crypto_scalarmult_ristretto255_base() failed\n");
}
crypto_core_ristretto255_random(s);
if (crypto_core_ristretto255_is_valid_point(s) != 1) {
printf("crypto_core_ristretto255_random() failed\n");
}
if (crypto_scalarmult_ristretto255(s, l, s) == 0) {
printf("s*l != inf (1)\n");
}