Add constant-time edx recovery; use it in ed25519_scalarmult()
This commit is contained in:
parent
5468c39d7d
commit
52fce922f4
@ -1405,13 +1405,16 @@ static const fe sqrtm1 = { -32595792, -7943725, 9377950, 3500415, 12389472,
|
||||
-272473, -25146209, -2005654, 326686, 11406482 };
|
||||
|
||||
int
|
||||
ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s)
|
||||
ge_frombytes(ge_p3 *h, const unsigned char *s)
|
||||
{
|
||||
fe u;
|
||||
fe v;
|
||||
fe v3;
|
||||
fe vxx;
|
||||
fe check;
|
||||
fe u;
|
||||
fe v;
|
||||
fe v3;
|
||||
fe vxx;
|
||||
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_1(h->Z);
|
||||
@ -1432,10 +1435,52 @@ ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s)
|
||||
|
||||
fe_sq(vxx, h->X);
|
||||
fe_mul(vxx, vxx, v);
|
||||
fe_sub(check, vxx, u); /* vx^2-u */
|
||||
if (fe_iszero(check) == 0) {
|
||||
fe_add(check, vxx, u); /* vx^2+u */
|
||||
if (fe_iszero(check) == 0) {
|
||||
fe_sub(m_root_check, vxx, u); /* vx^2-u */
|
||||
fe_add(p_root_check, vxx, u); /* vx^2+u */
|
||||
has_m_root = fe_iszero(m_root_check);
|
||||
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;
|
||||
}
|
||||
fe_mul(h->X, h->X, sqrtm1);
|
||||
|
@ -38,8 +38,7 @@ crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n,
|
||||
unsigned int i;
|
||||
|
||||
if (ge_is_canonical(p) == 0 || ge_has_small_order(p) != 0 ||
|
||||
ge_frombytes_negate_vartime(&P, p) != 0 ||
|
||||
ge_is_on_main_subgroup(&P) == 0) {
|
||||
ge_frombytes(&P, p) != 0 || ge_is_on_main_subgroup(&P) == 0) {
|
||||
return -1;
|
||||
}
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
q[31] ^= 0x80;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@ typedef struct {
|
||||
} ge_cached;
|
||||
|
||||
#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_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_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 void ge_p3_to_cached(ge_cached *,const ge_p3 *);
|
||||
|
Loading…
Reference in New Issue
Block a user