Implement crypto_sign_ed25519_scalarmult()

This commit is contained in:
Frank Denis 2017-10-20 01:45:49 +02:00
parent fe5d65853b
commit bab680f35b
4 changed files with 149 additions and 3 deletions

View File

@ -1572,6 +1572,23 @@ ge_p3_to_cached(ge_cached *r, const ge_p3 *p)
fe_mul(r->T2d, p->T, d2);
}
static void
ge_p3_to_precomp(ge_precomp *pi, const ge_p3 *p)
{
fe recip;
fe x;
fe y;
fe xy;
fe_invert(recip, p->Z);
fe_mul(x, p->X, recip);
fe_mul(y, p->Y, recip);
fe_add(pi->yplusx, y, x);
fe_sub(pi->yminusx, y, x);
fe_mul(xy, x, y);
fe_mul(pi->xy2d, xy, d2);
}
/*
r = p
*/
@ -1866,11 +1883,105 @@ ge_scalarmult_vartime(ge_p3 *r, const unsigned char *a, const ge_p3 *A)
#endif
/*
h = a * p
where a = a[0]+256*a[1]+...+256^31 a[31]
Preconditions:
a[31] <= 127
p is public
*/
void
ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *p)
{
signed char e[64];
signed char carry;
ge_p1p1 r;
ge_p2 s;
ge_p1p1 t2, t3, t4, t5, t6, t7, t8;
ge_p3 p2, p3, p4, p5, p6, p7, p8;
ge_precomp pi[8];
ge_precomp t;
int i;
ge_p3_to_precomp(&pi[1 - 1], p); /* p */
ge_p3_dbl(&t2, p);
ge_p1p1_to_p3(&p2, &t2);
ge_p3_to_precomp(&pi[2 - 1], &p2); /* 2p = 2*p */
ge_madd(&t3, p, &pi[2 - 1]);
ge_p1p1_to_p3(&p3, &t3);
ge_p3_to_precomp(&pi[3 - 1], &p3); /* 3p = 2p+p */
ge_p3_dbl(&t4, &p2);
ge_p1p1_to_p3(&p4, &t4);
ge_p3_to_precomp(&pi[4 - 1], &p4); /* 4p = 2*2p */
ge_madd(&t5, p, &pi[4 - 1]);
ge_p1p1_to_p3(&p5, &t5);
ge_p3_to_precomp(&pi[5 - 1], &p5); /* 5p = 4p+p */
ge_p3_dbl(&t6, &p3);
ge_p1p1_to_p3(&p6, &t6);
ge_p3_to_precomp(&pi[6 - 1], &p6); /* 6p = 2*3p */
ge_madd(&t7, p, &pi[6 - 1]);
ge_p1p1_to_p3(&p7, &t7);
ge_p3_to_precomp(&pi[7 - 1], &p7); /* 7p = 6p+p */
ge_p3_dbl(&t8, &p4);
ge_p1p1_to_p3(&p8, &t8);
ge_p3_to_precomp(&pi[8 - 1], &p8); /* 8p = 2*4p */
for (i = 0; i < 32; ++i) {
e[2 * i + 0] = (a[i] >> 0) & 15;
e[2 * i + 1] = (a[i] >> 4) & 15;
}
/* each e[i] is between 0 and 15 */
/* e[63] is between 0 and 7 */
carry = 0;
for (i = 0; i < 63; ++i) {
e[i] += carry;
carry = e[i] + 8;
carry >>= 4;
e[i] -= carry * ((signed char) 1 << 4);
}
e[63] += carry;
/* each e[i] is between -8 and 8 */
ge_p3_0(h);
for (i = 63; i != 0; i--) {
ge_select(&t, pi, e[i]);
ge_madd(&r, h, &t);
ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s);
ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s);
ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s);
ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s);
ge_p1p1_to_p3(h, &r); /* *16 */
}
ge_select(&t, pi, e[i]);
ge_madd(&r, h, &t);
ge_p1p1_to_p3(h, &r);
}
/*
h = a * B (with precomputation)
where a = a[0]+256*a[1]+...+256^31 a[31]
B is the Ed25519 base point (x,4/5) with x positive.
*
B is the Ed25519 base point (x,4/5) with x positive
(as bytes: 0x5866666666666666666666666666666666666666666666666666666666666666)
Preconditions:
a[31] <= 127
*/

View File

@ -9,6 +9,34 @@
#include "randombytes.h"
#include "utils.h"
int
crypto_sign_ed25519_scalarmult(unsigned char *q, const unsigned char *n,
const unsigned char *p)
{
unsigned char *t = q;
ge_p3 Q;
ge_p3 P;
ge_p3 pl;
if (_crypto_sign_ed25519_small_order(p) ||
ge_frombytes_negate_vartime(&P, p) != 0) {
return -1;
}
ge_mul_l(&pl, &P);
if (fe_isnonzero(pl.X)) {
return -1;
}
memmove(t, n, 32);
t[0] &= 248;
t[31] &= 63;
t[31] |= 64;
ge_scalarmult(&Q, t, &P);
ge_p3_tobytes(q, &Q);
q[31] ^= 0x80;
return 0;
}
int
crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk,
const unsigned char *seed)
@ -16,7 +44,7 @@ crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk,
ge_p3 A;
#ifdef ED25519_NONDETERMINISTIC
memcpy(sk, seed, 32);
memmove(sk, seed, 32);
#else
crypto_hash_sha512(sk, seed, 32);
#endif

View File

@ -87,6 +87,11 @@ int crypto_sign_ed25519_sk_to_seed(unsigned char *seed,
SODIUM_EXPORT
int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk);
SODIUM_EXPORT
int crypto_sign_ed25519_scalarmult(unsigned char *q, const unsigned char *n,
const unsigned char *p)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_sign_ed25519ph_init(crypto_sign_ed25519ph_state *state);

View File

@ -100,6 +100,7 @@ typedef struct {
#define ge_p1p1_to_p2 crypto_core_curve25519_ref10_ge_p1p1_to_p2
#define ge_add crypto_core_curve25519_ref10_ge_add
#define ge_scalarmult crypto_core_curve25519_ref10_ge_scalarmult
#define ge_scalarmult_base crypto_core_curve25519_ref10_ge_scalarmult_base
#define ge_double_scalarmult_vartime crypto_core_curve25519_ref10_ge_double_scalarmult_vartime
#define ge_scalarmult_vartime crypto_core_curve25519_ref10_ge_scalarmult_vartime
@ -115,6 +116,7 @@ extern void ge_p1p1_to_p2(ge_p2 *,const ge_p1p1 *);
extern void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *);
extern void ge_scalarmult_base(ge_p3 *,const unsigned char *);
extern void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *);
extern void ge_scalarmult(ge_p3 *,const unsigned char *,const ge_p3 *);
extern void ge_scalarmult_vartime(ge_p3 *,const unsigned char *,const ge_p3 *);
extern void ge_mul_l(ge_p3 *r, const ge_p3 *A);