summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2013-12-04 10:03:57 +0900
committerWerner Koch <wk@gnupg.org>2014-08-07 19:46:27 +0200
commite2ba3187fc02f0ba0443f0ffc2d13e1fc1aee6c7 (patch)
treefeda1ca3026699020f1f93a2256e86d49f4aacc3
parent62e8e1283268f1d3b6d0cfb2fc4e7835bbcdaab6 (diff)
downloadlibgcrypt-e2ba3187fc02f0ba0443f0ffc2d13e1fc1aee6c7.tar.gz
mpi: fix gcry_mpi_powm for negative base.
* 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> (cherry picked from commit c56080c26186d25dec05f01831494c77d8d07e13) Resolved conflicts: tests/mpitests.c - Use replacements for gcry_mpi_new and gcry_mpi_is_neg.
-rw-r--r--mpi/mpi-pow.c4
-rw-r--r--tests/mpitests.c26
2 files changed, 26 insertions, 4 deletions
diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
index 469c382a..4bf0233a 100644
--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -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];
diff --git a/tests/mpitests.c b/tests/mpitests.c
index cf828425..64ab7a34 100644
--- a/tests/mpitests.c
+++ b/tests/mpitests.c
@@ -181,6 +181,7 @@ test_powm (void)
int b_int = 17;
int e_int = 3;
int m_int = 19;
+ gcry_mpi_t mpi_0 = gcry_mpi_set_ui (NULL, 0);
gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
@@ -269,10 +270,31 @@ test_powm (void)
if (gcry_mpi_cmp (res, base))
die ("test_powm failed at %d\n", __LINE__);
- /* Fixme: We should add the rest of the cases of course. */
-
+ /* Check for a case: base is negative and expo is even. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_sub (base, mpi_0, 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_cmp_ui (res, 0) < 0 || gcry_mpi_cmp_ui (res, 7))
+ {
+ if (verbose)
+ {
+ fprintf (stderr, "is_neg: %d\n", (gcry_mpi_cmp_ui (res, 0) < 0));
+ 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);
+ gcry_mpi_release (res);
+ /* Fixme: We should add the rest of the cases of course. */
return 1;
}