Implement crypto_sign_ed25519_scalarmult()
This commit is contained in:
parent
fe5d65853b
commit
bab680f35b
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user