diff options
author | Werner Koch <wk@wheatstone.g10code.de> | 2013-04-16 18:59:22 +0200 |
---|---|---|
committer | Werner Koch <wk@wheatstone.g10code.de> | 2013-04-16 18:59:41 +0200 |
commit | 78cd0ba8a8eceee9d0b3397a2ab3bda6ba37c8a4 (patch) | |
tree | 0997bf4df22845788eace4d2ebd8bfa608e345c8 | |
parent | bd3afc27459a44df8cf501a7e1ae37bb849a8b0e (diff) | |
download | libgcrypt-78cd0ba8a8eceee9d0b3397a2ab3bda6ba37c8a4.tar.gz |
Fix multiply by zero in gcry_mpi_ec_mul.
* mpi/ec.c (_gcry_mpi_ec_mul_point): Handle case of SCALAR == 0.
* tests/t-mpi-point.c (basic_ec_math): Add a test case for this.
Signed-off-by: Werner Koch <wk@wheatstone.g10code.de>
-rw-r--r-- | mpi/ec.c | 21 | ||||
-rw-r--r-- | tests/t-mpi-point.c | 16 |
2 files changed, 32 insertions, 5 deletions
@@ -977,10 +977,23 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, mpi_mul (h, k, mpi_const (MPI_C_THREE)); /* h = 3k */ loops = mpi_get_nbits (h); - - mpi_set (result->x, point->x); - mpi_set (result->y, yy); mpi_free (yy); yy = NULL; - mpi_set (result->z, point->z); + if (loops < 2) + { + /* If SCALAR is zero, the above mpi_mul sets H to zero and thus + LOOPs will be zero. To avoid an underflow of I in the main + loop we set LOOP to 2 and the result to (0,0,0). */ + loops = 2; + mpi_clear (result->x); + mpi_clear (result->y); + mpi_clear (result->z); + } + else + { + mpi_set (result->x, point->x); + mpi_set (result->y, yy); + mpi_set (result->z, point->z); + } + mpi_free (yy); yy = NULL; p1.x = x1; x1 = NULL; p1.y = y1; y1 = NULL; diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 9f7360e2..98236e78 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -593,11 +593,25 @@ basic_ec_math (void) err = ec_p_new (&ctx, P, A); if (err) die ("ec_p_new failed: %s\n", gpg_strerror (err)); - gcry_mpi_ec_mul (Q, d, G, ctx); x = gcry_mpi_new (0); y = gcry_mpi_new (0); z = gcry_mpi_new (0); + + { + /* A quick check that multiply by zero works. */ + gcry_mpi_t tmp; + + tmp = gcry_mpi_new (0); + gcry_mpi_ec_mul (Q, tmp, G, ctx); + gcry_mpi_release (tmp); + gcry_mpi_point_get (x, y, z, Q); + if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0) + || gcry_mpi_cmp_ui (z, 0)) + fail ("multiply a point by zero failed\n"); + } + + gcry_mpi_ec_mul (Q, d, G, ctx); gcry_mpi_point_get (x, y, z, Q); if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66") || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8") |