Add constant-time edx recovery; use it in ed25519_scalarmult()

This commit is contained in:
Frank Denis 2017-10-31 15:27:48 +01:00
parent 5468c39d7d
commit 52fce922f4
3 changed files with 58 additions and 14 deletions

View File

@ -1405,13 +1405,16 @@ static const fe sqrtm1 = { -32595792, -7943725, 9377950, 3500415, 12389472,
-272473, -25146209, -2005654, 326686, 11406482 }; -272473, -25146209, -2005654, 326686, 11406482 };
int int
ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) ge_frombytes(ge_p3 *h, const unsigned char *s)
{ {
fe u; fe u;
fe v; fe v;
fe v3; fe v3;
fe vxx; fe vxx;
fe check; fe m_root_check, p_root_check;
fe negx;
fe x_sqrtm1;
int has_m_root, has_p_root;
fe_frombytes(h->Y, s); fe_frombytes(h->Y, s);
fe_1(h->Z); fe_1(h->Z);
@ -1432,10 +1435,52 @@ ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s)
fe_sq(vxx, h->X); fe_sq(vxx, h->X);
fe_mul(vxx, vxx, v); fe_mul(vxx, vxx, v);
fe_sub(check, vxx, u); /* vx^2-u */ fe_sub(m_root_check, vxx, u); /* vx^2-u */
if (fe_iszero(check) == 0) { fe_add(p_root_check, vxx, u); /* vx^2+u */
fe_add(check, vxx, u); /* vx^2+u */ has_m_root = fe_iszero(m_root_check);
if (fe_iszero(check) == 0) { has_p_root = fe_iszero(p_root_check);
fe_mul(x_sqrtm1, h->X, sqrtm1); /* x*sqrt(-1) */
fe_cmov(h->X, x_sqrtm1, 1 - has_m_root);
fe_neg(negx, h->X);
fe_cmov(h->X, negx, fe_isnegative(h->X) ^ (s[31] >> 7));
fe_mul(h->T, h->X, h->Y);
return (has_m_root | has_p_root) - 1;
}
int
ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s)
{
fe u;
fe v;
fe v3;
fe vxx;
fe m_root_check, p_root_check;
fe_frombytes(h->Y, s);
fe_1(h->Z);
fe_sq(u, h->Y);
fe_mul(v, u, d);
fe_sub(u, u, h->Z); /* u = y^2-1 */
fe_add(v, v, h->Z); /* v = dy^2+1 */
fe_sq(v3, v);
fe_mul(v3, v3, v); /* v3 = v^3 */
fe_sq(h->X, v3);
fe_mul(h->X, h->X, v);
fe_mul(h->X, h->X, u); /* x = uv^7 */
fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
fe_mul(h->X, h->X, v3);
fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
fe_sq(vxx, h->X);
fe_mul(vxx, vxx, v);
fe_sub(m_root_check, vxx, u); /* vx^2-u */
if (fe_iszero(m_root_check) == 0) {
fe_add(p_root_check, vxx, u); /* vx^2+u */
if (fe_iszero(p_root_check) == 0) {
return -1; return -1;
} }
fe_mul(h->X, h->X, sqrtm1); fe_mul(h->X, h->X, sqrtm1);

View File

@ -38,8 +38,7 @@ crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n,
unsigned int i; unsigned int i;
if (ge_is_canonical(p) == 0 || ge_has_small_order(p) != 0 || if (ge_is_canonical(p) == 0 || ge_has_small_order(p) != 0 ||
ge_frombytes_negate_vartime(&P, p) != 0 || ge_frombytes(&P, p) != 0 || ge_is_on_main_subgroup(&P) == 0) {
ge_is_on_main_subgroup(&P) == 0) {
return -1; return -1;
} }
for (i = 0; i < 32; ++i) { for (i = 0; i < 32; ++i) {
@ -51,8 +50,6 @@ crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n,
if (_crypto_scalarmult_ed25519_is_inf(q) != 0) { if (_crypto_scalarmult_ed25519_is_inf(q) != 0) {
return -1; return -1;
} }
q[31] ^= 0x80;
return 0; return 0;
} }

View File

@ -93,6 +93,7 @@ typedef struct {
} ge_cached; } ge_cached;
#define ge_frombytes_negate_vartime crypto_core_curve25519_ref10_ge_frombytes_negate_vartime #define ge_frombytes_negate_vartime crypto_core_curve25519_ref10_ge_frombytes_negate_vartime
#define ge_frombytes crypto_core_curve25519_ref10_ge_frombytes
#define ge_tobytes crypto_core_curve25519_ref10_ge_tobytes #define ge_tobytes crypto_core_curve25519_ref10_ge_tobytes
#define ge_p3_tobytes crypto_core_curve25519_ref10_ge_p3_tobytes #define ge_p3_tobytes crypto_core_curve25519_ref10_ge_p3_tobytes
@ -111,6 +112,7 @@ typedef struct {
extern void ge_tobytes(unsigned char *,const ge_p2 *); extern void ge_tobytes(unsigned char *,const ge_p2 *);
extern void ge_p3_tobytes(unsigned char *,const ge_p3 *); extern void ge_p3_tobytes(unsigned char *,const ge_p3 *);
extern int ge_frombytes(ge_p3 *,const unsigned char *);
extern int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *); extern int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *);
extern void ge_p3_to_cached(ge_cached *,const ge_p3 *); extern void ge_p3_to_cached(ge_cached *,const ge_p3 *);