From 2dbfa8444bdf7669a54006c4a83d1e60ba374528 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Tue, 26 Sep 2017 10:48:55 -0700 Subject: [PATCH] nistp521: add a comment to the P+P exceptional case in point_add. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This change adds a comment to the exceptional case in point_add that handles the case of a doubling, which explains when this case may occur during normal processing. Thanks go to Antonio Sanso for noting this. Reviewed-by: Emilia Käsper Reviewed-by: Andy Polyakov Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/4424) --- crypto/ec/ecp_nistp521.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c index e491fe55c2..d68d60ef32 100644 --- a/crypto/ec/ecp_nistp521.c +++ b/crypto/ec/ecp_nistp521.c @@ -1157,9 +1157,9 @@ static void copy_conditional(felem out, const felem in, limb mask) * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). * * This function includes a branch for checking whether the two input points - * are equal (while not equal to the point at infinity). This case never - * happens during single point multiplication, so there is no timing leak for - * ECDH or ECDSA signing. */ + * are equal (while not equal to the point at infinity). See comment below + * on constant-time. + */ static void point_add(felem x3, felem y3, felem z3, const felem x1, const felem y1, const felem z1, const int mixed, const felem x2, const felem y2, @@ -1253,6 +1253,22 @@ static void point_add(felem x3, felem y3, felem z3, /* ftmp5[i] < 2^61 */ if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { + /* + * This is obviously not constant-time but it will almost-never happen + * for ECDH / ECDSA. The case where it can happen is during scalar-mult + * where the intermediate value gets very close to the group order. + * Since |ec_GFp_nistp_recode_scalar_bits| produces signed digits for + * the scalar, it's possible for the intermediate value to be a small + * negative multiple of the base point, and for the final signed digit + * to be the same value. We believe that this only occurs for the scalar + * 1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + * ffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb + * 71e913863f7, in that case the penultimate intermediate is -9G and + * the final digit is also -9G. Since this only happens for a single + * scalar, the timing leak is irrelevent. (Any attacker who wanted to + * check whether a secret scalar was that exact value, can already do + * so.) + */ point_double(x3, y3, z3, x1, y1, z1); return; } -- 2.25.1