Merge crypto_core_ed25519_from_uniform()

Fixes #628
although we need another one that keeps montgomery coordinates.
This commit is contained in:
Frank Denis 2017-11-14 22:05:37 +01:00
parent c44d847207
commit 5257cceda8
7 changed files with 150 additions and 5 deletions

View File

@ -143,6 +143,7 @@ _crypto_box_secretkeybytes 1 1
_crypto_box_seed_keypair 1 1
_crypto_box_seedbytes 1 1
_crypto_box_zerobytes 0 1
_crypto_core_ed25519_from_uniform 0 1
_crypto_core_ed25519_add 0 1
_crypto_core_ed25519_sub 0 1
_crypto_core_ed25519_is_valid_point 0 1

File diff suppressed because one or more lines are too long

View File

@ -13,9 +13,9 @@ crypto_core_ed25519_is_valid_point(const unsigned char *p)
ge25519_frombytes(&p_p3, p) != 0 ||
ge25519_is_on_curve(&p_p3) == 0 ||
ge25519_is_on_main_subgroup(&p_p3) == 0) {
return -1;
return 0;
}
return 0;
return 1;
}
int
@ -57,3 +57,11 @@ crypto_core_ed25519_sub(unsigned char *r,
return 0;
}
int
crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r)
{
ge25519_from_uniform(p, r);
return - ge25519_has_small_order(p);
}

View File

@ -1843,3 +1843,131 @@ sc25519_is_canonical(const unsigned char *s)
return (c != 0);
}
static void
chi25519(fe25519 out, const fe25519 z)
{
fe25519 t0, t1, t2, t3;
int i;
fe25519_sq(t0, z);
fe25519_mul(t1, t0, z);
fe25519_sq(t0, t1);
fe25519_sq(t2, t0);
fe25519_sq(t2, t2);
fe25519_mul(t2, t2, t0);
fe25519_mul(t1, t2, z);
fe25519_sq(t2, t1);
for (i = 1; i < 5; i++) {
fe25519_sq(t2, t2);
}
fe25519_mul(t1, t2, t1);
fe25519_sq(t2, t1);
for (i = 1; i < 10; i++) {
fe25519_sq(t2, t2);
}
fe25519_mul(t2, t2, t1);
fe25519_sq(t3, t2);
for (i = 1; i < 20; i++) {
fe25519_sq(t3, t3);
}
fe25519_mul(t2, t3, t2);
fe25519_sq(t2, t2);
for (i = 1; i < 10; i++) {
fe25519_sq(t2, t2);
}
fe25519_mul(t1, t2, t1);
fe25519_sq(t2, t1);
for (i = 1; i < 50; i++) {
fe25519_sq(t2, t2);
}
fe25519_mul(t2, t2, t1);
fe25519_sq(t3, t2);
for (i = 1; i < 100; i++) {
fe25519_sq(t3, t3);
}
fe25519_mul(t2, t3, t2);
fe25519_sq(t2, t2);
for (i = 1; i < 50; i++) {
fe25519_sq(t2, t2);
}
fe25519_mul(t1, t2, t1);
fe25519_sq(t1, t1);
for (i = 1; i < 4; i++) {
fe25519_sq(t1, t1);
}
fe25519_mul(out, t1, t0);
}
void
ge25519_from_uniform(unsigned char s[32], const unsigned char r[32])
{
fe25519 e;
fe25519 negx;
fe25519 rr2;
fe25519 x, x2, x3;
ge25519_p3 p3;
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);
fe25519_mul(x, curve25519_A, rr2);
fe25519_neg(x, x);
fe25519_sq(x2, x);
fe25519_mul(x3, x, x2);
fe25519_add(e, x3, x);
fe25519_mul(x2, x2, curve25519_A);
fe25519_add(e, x2, e);
chi25519(e, e);
fe25519_tobytes(s, e);
e_is_minus_1 = s[1] & 1;
fe25519_neg(negx, x);
fe25519_cmov(x, negx, e_is_minus_1);
fe25519_0(x2);
fe25519_cmov(x2, curve25519_A, e_is_minus_1);
fe25519_sub(x, x, x2);
/* yed = (x-1)/(x+1) */
{
fe25519 one;
fe25519 x_plus_one;
fe25519 x_plus_one_inv;
fe25519 x_minus_one;
fe25519 yed;
fe25519_1(one);
fe25519_add(x_plus_one, x, one);
fe25519_sub(x_minus_one, x, one);
fe25519_invert(x_plus_one_inv, x_plus_one);
fe25519_mul(yed, x_minus_one, x_plus_one_inv);
fe25519_tobytes(s, yed);
s[31] |= x_sign;
}
/* recover x */
ge25519_frombytes(&p3, s);
/* multiply by the cofactor */
ge25519_p3_dbl(&p1, &p3);
ge25519_p1p1_to_p2(&p2, &p1);
ge25519_p2_dbl(&p1, &p2);
ge25519_p1p1_to_p2(&p2, &p1);
ge25519_p2_dbl(&p1, &p2);
ge25519_p1p1_to_p3(&p3, &p1);
ge25519_p3_tobytes(s, &p3);
}

View File

@ -14,3 +14,8 @@ static const fe25519 d2 = {
static const fe25519 sqrtm1 = {
1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133
};
/* A = 486662 */
static const fe25519 curve25519_A = {
486662, 0, 0, 0, 0
};

View File

@ -19,10 +19,11 @@ SODIUM_EXPORT
int crypto_core_ed25519_sub(unsigned char *r,
const unsigned char *p, const unsigned char *q);
SODIUM_EXPORT
int crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -108,6 +108,8 @@ int ge25519_is_on_main_subgroup(const ge25519_p3 *p);
int ge25519_has_small_order(const unsigned char s[32]);
void ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]);
/*
The set of scalars is \Z/l
where l = 2^252 + 27742317777372353535851937790883648493.