diff options
Diffstat (limited to 'src/crypto')
-rw-r--r-- | src/crypto/crypto-ops.c | 100 | ||||
-rw-r--r-- | src/crypto/crypto-ops.h | 2 |
2 files changed, 102 insertions, 0 deletions
diff --git a/src/crypto/crypto-ops.c b/src/crypto/crypto-ops.c index 3110d3ce7..508709280 100644 --- a/src/crypto/crypto-ops.c +++ b/src/crypto/crypto-ops.c @@ -1234,6 +1234,56 @@ void ge_double_scalarmult_base_vartime(ge_p2 *r, const unsigned char *a, const g } } +// Computes aG + bB + cC (G is the fixed basepoint) +void ge_triple_scalarmult_base_vartime(ge_p2 *r, const unsigned char *a, const unsigned char *b, const ge_dsmp Bi, const unsigned char *c, const ge_dsmp Ci) { + signed char aslide[256]; + signed char bslide[256]; + signed char cslide[256]; + ge_p1p1 t; + ge_p3 u; + int i; + + slide(aslide, a); + slide(bslide, b); + slide(cslide, c); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i] || cslide[i]) break; + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &ge_Bi[aslide[i]/2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &ge_Bi[(-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 (cslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ci[cslide[i]/2]); + } else if (cslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ci[(-cslide[i])/2]); + } + + ge_p1p1_to_p2(r, &t); + } +} + 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]; @@ -2148,6 +2198,56 @@ void ge_double_scalarmult_precomp_vartime2(ge_p2 *r, const unsigned char *a, con } } +// Computes aA + bB + cC (all points require precomputation) +void ge_triple_scalarmult_precomp_vartime(ge_p2 *r, const unsigned char *a, const ge_dsmp Ai, const unsigned char *b, const ge_dsmp Bi, const unsigned char *c, const ge_dsmp Ci) { + signed char aslide[256]; + signed char bslide[256]; + signed char cslide[256]; + ge_p1p1 t; + ge_p3 u; + int i; + + slide(aslide, a); + slide(bslide, b); + slide(cslide, c); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i] || cslide[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 (cslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ci[cslide[i]/2]); + } else if (cslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ci[(-cslide[i])/2]); + } + + ge_p1p1_to_p2(r, &t); + } +} + 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]; diff --git a/src/crypto/crypto-ops.h b/src/crypto/crypto-ops.h index eeb94669b..22f76974b 100644 --- a/src/crypto/crypto-ops.h +++ b/src/crypto/crypto-ops.h @@ -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_triple_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp); void ge_double_scalarmult_base_vartime_p3(ge_p3 *, const unsigned char *, const ge_p3 *, const unsigned char *); /* From ge_frombytes.c, modified */ @@ -130,6 +131,7 @@ void sc_reduce(unsigned char *); 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_triple_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp, 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 *); |