mpi: fix gcry_mpi_powm for negative base.
authorNIIBE Yutaka <gniibe@fsij.org>
Wed, 4 Dec 2013 01:03:57 +0000 (10:03 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Wed, 4 Dec 2013 01:31:31 +0000 (10:31 +0900)
* mpi/mpi-pow.c (gcry_mpi_powm) [USE_ALGORITHM_SIMPLE_EXPONENTIATION]:
Fix for the case where BASE is negative.
* tests/mpitests.c (test_powm): Add a test case of (-17)^6 mod 19.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
mpi/mpi-pow.c
tests/mpitests.c

index 469c382..4bf0233 100644 (file)
@@ -177,7 +177,7 @@ gcry_mpi_powm (gcry_mpi_t res,
     }
   MPN_COPY ( rp, bp, bsize );
   rsize = bsize;
-  rsign = bsign;
+  rsign = 0;
 
   /* Main processing.  */
   {
@@ -192,7 +192,7 @@ gcry_mpi_powm (gcry_mpi_t res,
     xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
 
     memset( &karactx, 0, sizeof karactx );
-    negative_result = (ep[0] & 1) && base->sign;
+    negative_result = (ep[0] & 1) && bsign;
 
     i = esize - 1;
     e = ep[i];
index 1c4edb6..9d1206e 100644 (file)
@@ -520,6 +520,25 @@ test_powm (void)
   if (gcry_mpi_cmp (res, base))
     die ("test_powm failed at %d\n", __LINE__);
 
+  /* Check for a case: base is negative and expo is even.  */
+  gcry_mpi_set_ui (base, b_int);
+  gcry_mpi_neg (base, base);
+  gcry_mpi_set_ui (exp, e_int * 2);
+  gcry_mpi_set_ui(mod, m_int);
+  gcry_mpi_powm (res, base, exp, mod);
+  /* Result should be positive and it's 7 = (-17)^6 mod 19.  */
+  if (gcry_mpi_is_neg (res) || gcry_mpi_cmp_ui (res, 7))
+    {
+      if (verbose)
+        {
+          fprintf (stderr, "is_neg: %d\n", gcry_mpi_is_neg (res));
+          fprintf (stderr, "mpi: ");
+          gcry_mpi_dump (res);
+          putc ('\n', stderr);
+        }
+      die ("test_powm failed for negative base at %d\n", __LINE__);
+    }
+
   gcry_mpi_release (base);
   gcry_mpi_release (exp);
   gcry_mpi_release (mod);