summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@wheatstone.g10code.de>2013-04-16 18:59:22 +0200
committerWerner Koch <wk@wheatstone.g10code.de>2013-04-16 18:59:41 +0200
commit78cd0ba8a8eceee9d0b3397a2ab3bda6ba37c8a4 (patch)
tree0997bf4df22845788eace4d2ebd8bfa608e345c8
parentbd3afc27459a44df8cf501a7e1ae37bb849a8b0e (diff)
downloadlibgcrypt-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.c21
-rw-r--r--tests/t-mpi-point.c16
2 files changed, 32 insertions, 5 deletions
diff --git a/mpi/ec.c b/mpi/ec.c
index 5d2f5c92..8fb47a30 100644
--- a/mpi/ec.c
+++ b/mpi/ec.c
@@ -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")