From 15150994333c872a20a1902aa01e1a60dbb1393d Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Fri, 3 Dec 2021 21:08:56 +0700 Subject: [PATCH] Simpler and faster ecdh skew fixup --- src/ecmult_const_impl.h | 39 ++++++++++++--------------------------- src/group.h | 3 +++ src/group_impl.h | 8 ++++++++ 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/ecmult_const_impl.h b/src/ecmult_const_impl.h index b79787506b..2a8a293c72 100644 --- a/src/ecmult_const_impl.h +++ b/src/ecmult_const_impl.h @@ -234,36 +234,21 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons { /* Correct for wNAF skew */ - secp256k1_ge correction = *a; - secp256k1_ge_storage correction_1_stor; - secp256k1_ge_storage correction_lam_stor; - secp256k1_ge_storage a2_stor; - secp256k1_gej tmpj; - secp256k1_gej_set_ge(&tmpj, &correction); - secp256k1_gej_double_var(&tmpj, &tmpj, NULL); - secp256k1_ge_set_gej(&correction, &tmpj); - secp256k1_ge_to_storage(&correction_1_stor, a); - if (size > 128) { - secp256k1_ge_to_storage(&correction_lam_stor, a); - } - secp256k1_ge_to_storage(&a2_stor, &correction); - - /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */ - secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2); - if (size > 128) { - secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2); - } + secp256k1_gej tmp; + secp256k1_ge a_1; - /* Apply the correction */ - secp256k1_ge_from_storage(&correction, &correction_1_stor); - secp256k1_ge_neg(&correction, &correction); - secp256k1_gej_add_ge(r, r, &correction); + secp256k1_ge_neg(&a_1, a); + secp256k1_gej_add_ge(r, r, &a_1); + secp256k1_gej_add_ge(&tmp, r, &a_1); + secp256k1_gej_cmov(r, &tmp, skew_1 == 2); if (size > 128) { - secp256k1_ge_from_storage(&correction, &correction_lam_stor); - secp256k1_ge_neg(&correction, &correction); - secp256k1_ge_mul_lambda(&correction, &correction); - secp256k1_gej_add_ge(r, r, &correction); + secp256k1_ge a_lam; + secp256k1_ge_mul_lambda(&a_lam, &a_1); + + secp256k1_gej_add_ge(r, r, &a_lam); + secp256k1_gej_add_ge(&tmp, r, &a_lam); + secp256k1_gej_cmov(r, &tmp, skew_lam == 2); } } } diff --git a/src/group.h b/src/group.h index b9cd334dae..0b55ad73c6 100644 --- a/src/group.h +++ b/src/group.h @@ -124,6 +124,9 @@ static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge /** Convert a group element back from the storage type. */ static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a); +/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ +static void secp256k1_gej_cmov(secp256k1_gej *r, const secp256k1_gej *a, int flag); + /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag); diff --git a/src/group_impl.h b/src/group_impl.h index bce9fbdad5..f02891de77 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -642,6 +642,14 @@ static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storag r->infinity = 0; } +static SECP256K1_INLINE void secp256k1_gej_cmov(secp256k1_gej *r, const secp256k1_gej *a, int flag) { + secp256k1_fe_cmov(&r->x, &a->x, flag); + secp256k1_fe_cmov(&r->y, &a->y, flag); + secp256k1_fe_cmov(&r->z, &a->z, flag); + + r->infinity ^= (r->infinity ^ a->infinity) & flag; +} + static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag) { secp256k1_fe_storage_cmov(&r->x, &a->x, flag); secp256k1_fe_storage_cmov(&r->y, &a->y, flag);