crypto: add scalar mult functions returning ge_p3 instead of ge_p2

ge_scalarmult_p3
ge_double_scalarmult_precomp_vartime2_p3
ge_double_scalarmult_base_vartime_p3

This makes it possible to reuse the result without having to
convert back to unsigned char[32] and back to ge types.
This commit is contained in:
moneromooo-monero 2018-01-05 20:31:53 +00:00
parent 35d5aa36c9
commit 13b4c90e01
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
2 changed files with 155 additions and 0 deletions

View file

@ -1234,6 +1234,51 @@ void ge_double_scalarmult_base_vartime(ge_p2 *r, const unsigned char *a, const g
}
}
void ge_double_scalarmult_base_vartime_p3(ge_p3 *r3, const unsigned char *a, const ge_p3 *A, const unsigned char *b) {
signed char aslide[256];
signed char bslide[256];
ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */
ge_p1p1 t;
ge_p3 u;
ge_p2 r;
int i;
slide(aslide, a);
slide(bslide, b);
ge_dsm_precomp(Ai, A);
ge_p2_0(&r);
for (i = 255; i >= 0; --i) {
if (aslide[i] || bslide[i]) break;
}
for (; i >= 0; --i) {
ge_p2_dbl(&t, &r);
if (aslide[i] > 0) {
ge_p1p1_to_p3(&u, &t);
ge_add(&t, &u, &Ai[aslide[i]/2]);
} else if (aslide[i] < 0) {
ge_p1p1_to_p3(&u, &t);
ge_sub(&t, &u, &Ai[(-aslide[i])/2]);
}
if (bslide[i] > 0) {
ge_p1p1_to_p3(&u, &t);
ge_madd(&t, &u, &ge_Bi[bslide[i]/2]);
} else if (bslide[i] < 0) {
ge_p1p1_to_p3(&u, &t);
ge_msub(&t, &u, &ge_Bi[(-bslide[i])/2]);
}
if (i == 0)
ge_p1p1_to_p3(r3, &t);
else
ge_p1p1_to_p2(&r, &t);
}
}
/* From ge_frombytes.c, modified */
int ge_frombytes_vartime(ge_p3 *h, const unsigned char *s) {
@ -2000,6 +2045,70 @@ void ge_scalarmult(ge_p2 *r, const unsigned char *a, const ge_p3 *A) {
}
}
void ge_scalarmult_p3(ge_p3 *r3, const unsigned char *a, const ge_p3 *A) {
signed char e[64];
int carry, carry2, i;
ge_cached Ai[8]; /* 1 * A, 2 * A, ..., 8 * A */
ge_p1p1 t;
ge_p3 u;
ge_p2 r;
carry = 0; /* 0..1 */
for (i = 0; i < 31; i++) {
carry += a[i]; /* 0..256 */
carry2 = (carry + 8) >> 4; /* 0..16 */
e[2 * i] = carry - (carry2 << 4); /* -8..7 */
carry = (carry2 + 8) >> 4; /* 0..1 */
e[2 * i + 1] = carry2 - (carry << 4); /* -8..7 */
}
carry += a[31]; /* 0..128 */
carry2 = (carry + 8) >> 4; /* 0..8 */
e[62] = carry - (carry2 << 4); /* -8..7 */
e[63] = carry2; /* 0..8 */
ge_p3_to_cached(&Ai[0], A);
for (i = 0; i < 7; i++) {
ge_add(&t, A, &Ai[i]);
ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[i + 1], &u);
}
ge_p2_0(&r);
for (i = 63; i >= 0; i--) {
signed char b = e[i];
unsigned char bnegative = negative(b);
unsigned char babs = b - (((-bnegative) & b) << 1);
ge_cached cur, minuscur;
ge_p2_dbl(&t, &r);
ge_p1p1_to_p2(&r, &t);
ge_p2_dbl(&t, &r);
ge_p1p1_to_p2(&r, &t);
ge_p2_dbl(&t, &r);
ge_p1p1_to_p2(&r, &t);
ge_p2_dbl(&t, &r);
ge_p1p1_to_p3(&u, &t);
ge_cached_0(&cur);
ge_cached_cmov(&cur, &Ai[0], equal(babs, 1));
ge_cached_cmov(&cur, &Ai[1], equal(babs, 2));
ge_cached_cmov(&cur, &Ai[2], equal(babs, 3));
ge_cached_cmov(&cur, &Ai[3], equal(babs, 4));
ge_cached_cmov(&cur, &Ai[4], equal(babs, 5));
ge_cached_cmov(&cur, &Ai[5], equal(babs, 6));
ge_cached_cmov(&cur, &Ai[6], equal(babs, 7));
ge_cached_cmov(&cur, &Ai[7], equal(babs, 8));
fe_copy(minuscur.YplusX, cur.YminusX);
fe_copy(minuscur.YminusX, cur.YplusX);
fe_copy(minuscur.Z, cur.Z);
fe_neg(minuscur.T2d, cur.T2d);
ge_cached_cmov(&cur, &minuscur, bnegative);
ge_add(&t, &u, &cur);
if (i == 0)
ge_p1p1_to_p3(r3, &t);
else
ge_p1p1_to_p2(&r, &t);
}
}
void ge_double_scalarmult_precomp_vartime2(ge_p2 *r, const unsigned char *a, const ge_dsmp Ai, const unsigned char *b, const ge_dsmp Bi) {
signed char aslide[256];
signed char bslide[256];
@ -2039,6 +2148,49 @@ void ge_double_scalarmult_precomp_vartime2(ge_p2 *r, const unsigned char *a, con
}
}
void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *r3, const unsigned char *a, const ge_dsmp Ai, const unsigned char *b, const ge_dsmp Bi) {
signed char aslide[256];
signed char bslide[256];
ge_p1p1 t;
ge_p3 u;
ge_p2 r;
int i;
slide(aslide, a);
slide(bslide, b);
ge_p2_0(&r);
for (i = 255; i >= 0; --i) {
if (aslide[i] || bslide[i]) break;
}
for (; i >= 0; --i) {
ge_p2_dbl(&t, &r);
if (aslide[i] > 0) {
ge_p1p1_to_p3(&u, &t);
ge_add(&t, &u, &Ai[aslide[i]/2]);
} else if (aslide[i] < 0) {
ge_p1p1_to_p3(&u, &t);
ge_sub(&t, &u, &Ai[(-aslide[i])/2]);
}
if (bslide[i] > 0) {
ge_p1p1_to_p3(&u, &t);
ge_add(&t, &u, &Bi[bslide[i]/2]);
} else if (bslide[i] < 0) {
ge_p1p1_to_p3(&u, &t);
ge_sub(&t, &u, &Bi[(-bslide[i])/2]);
}
if (i == 0)
ge_p1p1_to_p3(r3, &t);
else
ge_p1p1_to_p2(&r, &t);
}
}
void ge_double_scalarmult_precomp_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b, const ge_dsmp Bi) {
ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */

View file

@ -79,6 +79,7 @@ typedef ge_cached ge_dsmp[8];
extern const ge_precomp ge_Bi[8];
void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s);
void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *);
void ge_double_scalarmult_base_vartime_p3(ge_p3 *, const unsigned char *, const ge_p3 *, const unsigned char *);
/* From ge_frombytes.c, modified */
@ -127,8 +128,10 @@ void sc_reduce(unsigned char *);
/* New code */
void ge_scalarmult(ge_p2 *, const unsigned char *, const ge_p3 *);
void ge_scalarmult_p3(ge_p3 *, const unsigned char *, const ge_p3 *);
void ge_double_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *, const ge_dsmp);
void ge_double_scalarmult_precomp_vartime2(ge_p2 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp);
void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp);
void ge_mul8(ge_p1p1 *, const ge_p2 *);
extern const fe fe_ma2;
extern const fe fe_ma;